<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.flightgear.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Elgaton</id>
	<title>FlightGear wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.flightgear.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Elgaton"/>
	<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/Special:Contributions/Elgaton"/>
	<updated>2026-05-30T02:20:11Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.39.6</generator>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=User:Elgaton/Draft:Translate_FlightGear&amp;diff=115804</id>
		<title>User:Elgaton/Draft:Translate FlightGear</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=User:Elgaton/Draft:Translate_FlightGear&amp;diff=115804"/>
		<updated>2018-08-08T15:38:03Z</updated>

		<summary type="html">&lt;p&gt;Elgaton: Initial version&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WIP}}&lt;br /&gt;
&lt;br /&gt;
FlightGear supports localization, that is, showing the user interface in the user's native language rather than in English. At the time of writing (August 2018), not all parts of the simulator are localized, but efforts are underway to make it so.&lt;br /&gt;
&lt;br /&gt;
This page will help you translate FlightGear to a new language or improve the existing translations.&lt;br /&gt;
&lt;br /&gt;
== What can be translated ==&lt;br /&gt;
The following parts of the simulator can be translated:&lt;br /&gt;
* the menus, splash screens, startup tips and the text shown when the &amp;lt;code&amp;gt;--help&amp;lt;/code&amp;gt; command-line option is used (FlightGear 2.7.0 and later);&lt;br /&gt;
* the shortcut file on Linux systems (FlightGear 2017.1 and later);&lt;br /&gt;
* the man pages (FlightGear 2017.3 and later).&lt;br /&gt;
&lt;br /&gt;
== How to translate the interface ==&lt;br /&gt;
Each language in the world has an associated two-letter code (the ISO 639-1 language code). You can find their list on the [https://www.loc.gov/standards/iso639-2/php/code_list.php Library of Congress Web site].&lt;br /&gt;
&lt;br /&gt;
Interface language files are saved in [{{fgdata url|path=Translations}} the Translations directory in the FGDATA repository]; each language is stored inside a directory having the corresponding ISO 639-1 code as its name.&lt;br /&gt;
&lt;br /&gt;
There is also a [{{fgdata url|path=python3-flightgear}} set of translation helper scripts] which help you create a new translation or update an existing one.&lt;br /&gt;
&lt;br /&gt;
=== Preparing the translation environment ===&lt;br /&gt;
On the machine you are going to use to translate FlightGear, install:&lt;br /&gt;
* '''Python 3''': on Microsoft Windows and Mac OS X systems, download the latest 3.x build from the [https://www.python.org/downloads/ official site]; on Linux, install it from your distribution's package manager;&lt;br /&gt;
* '''Git''': on Microsoft Windows, download it from the [https://git-scm.com/ official site]; on Mac OS X, run &amp;lt;code&amp;gt;git --help&amp;lt;/code&amp;gt; from a terminal to have it downloaded and installed if needed; on Linux, install it from your distribution's package manager;&lt;br /&gt;
* an editor for XLIFF files, like [http://doc.qt.io/qt-5/linguist-translators.html QT Linguist].&lt;br /&gt;
&lt;br /&gt;
Open a terminal, go into the directory you would like to clone the repositories into and type the following command to clone the FGMeta repository:&lt;br /&gt;
 $ git clone git://git.code.sf.net/p/flightgear/fgmeta/ fgmeta&lt;br /&gt;
Then, follow the instructions in [[FlightGear Git: data developers#Preparations]] to clone FGData ''inside'' the &amp;lt;code&amp;gt;fgmeta&amp;lt;/code&amp;gt; directory.&lt;br /&gt;
&lt;br /&gt;
=== Translating the interface into a new language ===&lt;br /&gt;
If there is no translation for your language:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Check the &amp;lt;code&amp;gt;PLURAL_FORMS&amp;lt;/code&amp;gt; variable inside [{{fgmeta url|path=python3-flightgear/flightgear/meta/i18n.py}} python3-flightgear/flightgear/meta/i18n.py] to make sure that your language is listed. If it is not, add a new entry for it - it should have the following form:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot;LANGUAGE_CODE&amp;quot;: [&amp;quot;singular&amp;quot;, &amp;quot;plural&amp;quot;],&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
where &amp;lt;code&amp;gt;&amp;lt;i&amp;gt;LANGUAGE_CODE&amp;lt;/i&amp;gt;&amp;lt;/code&amp;gt; is the language code and what follows is an array of plural forms for the language (in the same order as they are displayed in the Qt Linguist tool).&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Open a terminal and change into the &amp;lt;code&amp;gt;python3-flightgear&amp;lt;/code&amp;gt; directory inside your FGData clone.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Run &amp;lt;code&amp;gt;./fg-new-translations --transl-dir=&amp;quot;&amp;lt;i&amp;gt;FGDATA_CLONE_PATH&amp;lt;/i&amp;gt;/Translations&amp;quot; &amp;lt;i&amp;gt;LANGUAGE_CODE&amp;lt;/i&amp;gt;&amp;lt;/code&amp;gt; to create the new files. Replace &amp;lt;code&amp;gt;&amp;lt;i&amp;gt;FGDATA_CLONE_PATH&amp;lt;/i&amp;gt;&amp;lt;/code&amp;gt; with the path of the directory you cloned FGData into and &amp;lt;code&amp;gt;&amp;lt;i&amp;gt;LANGUAGE_CODE&amp;lt;/i&amp;gt;&amp;lt;/code&amp;gt; with the language code.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Updating an existing translation ===&lt;br /&gt;
If a translation for your language already exists:&lt;br /&gt;
# Open a terminal and change into the &amp;lt;code&amp;gt;python3-flightgear&amp;lt;/code&amp;gt; directory inside your FGData clone.&lt;br /&gt;
# Run &amp;lt;code&amp;gt;./fg-update-translation-files --transl-dir=&amp;quot;&amp;lt;i&amp;gt;FGDATA_CLONE_PATH&amp;lt;/i&amp;gt;/Translations&amp;quot; merge-new-master &amp;lt;i&amp;gt;LANGUAGE_CODE&amp;lt;/i&amp;gt;&amp;lt;/code&amp;gt; to update the translation files. Replace &amp;lt;code&amp;gt;&amp;lt;i&amp;gt;FGDATA_CLONE_PATH&amp;lt;/i&amp;gt;&amp;lt;/code&amp;gt; with the path of the directory you cloned FGData into and &amp;lt;code&amp;gt;&amp;lt;i&amp;gt;LANGUAGE_CODE&amp;lt;/i&amp;gt;&amp;lt;/code&amp;gt; with the language code.&lt;br /&gt;
&lt;br /&gt;
=== Translating the files ===&lt;br /&gt;
# Open the XLT files inside &amp;lt;code&amp;gt;&amp;lt;i&amp;gt;FGDATA_CLONE_PATH&amp;lt;/i&amp;gt;/Translations/&amp;lt;i&amp;gt;LANGUAGE_CODE&amp;lt;/i&amp;gt;&amp;lt;/code&amp;gt; with the XLIFF file editor and translate them.&lt;br /&gt;
# If you want to test your translation, you will need to [[Building FlightGear|build the latest FlightGear version from source]]. After you have built it, start FlightGear to test your translation, passing the &amp;lt;code&amp;gt;--fg-root=&amp;lt;i&amp;gt;FGDATA_CLONE_PATH&amp;lt;/i&amp;gt;&amp;lt;/code&amp;gt; option to have it read the translations from your FGData clone. By default, the simulator will select the locale of your operating system as the language to use; you can explicitly select a language using the command-line option &amp;lt;code&amp;gt;--language=&amp;lt;i&amp;gt;LANGUAGE_CODE&amp;lt;/i&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Note that the user interface might have not full Unicode support (some special/accented characters might not be shown): should you encounter such a location, please write to the flightgear-devel mailing list at {{Mailing list e-mail address|flightgear-devel}}.&lt;br /&gt;
&lt;br /&gt;
== How to translate the shortcut file ==&lt;br /&gt;
Open [{{flightgear url|path=package/org.flightgear.FlightGear.desktop}} the FlightGear &amp;lt;code&amp;gt;.desktop&amp;lt;/code&amp;gt; file] and translate the ''GenericName'', ''Comment'' and ''Keywords'' keys (add the &amp;lt;code&amp;gt;GenericName[&amp;lt;i&amp;gt;LANGUAGE_CODE&amp;lt;/i&amp;gt;]&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Comment[&amp;lt;i&amp;gt;LANGUAGE_CODE&amp;lt;/i&amp;gt;]&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Keywords[&amp;lt;i&amp;gt;LANGUAGE_CODE&amp;lt;/i&amp;gt;]&amp;lt;/code&amp;gt; keys, where &amp;lt;code&amp;gt;&amp;lt;i&amp;gt;LANGUAGE_CODE&amp;lt;/i&amp;gt;&amp;lt;/code&amp;gt; is the two letter ISO 639-1 code of the language).&lt;br /&gt;
&lt;br /&gt;
== How to translate the man pages ==&lt;br /&gt;
# Determine the two letter ISO 639-1 language code for the language you want to translate the man pages to.&lt;br /&gt;
# Check whether your language already has a subdirectory below [{{flightgear url|path=man}} the man pages directory]. If it does not, create an empty directory in it named after the language code, then copy &amp;lt;code&amp;gt;man1&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;man5&amp;lt;/code&amp;gt; from the man pages directory to the directory of your language.&lt;br /&gt;
# Edit [{{flightgear url|path=man/CMakeLists.txt}} man/CMakeLists.txt] and add the instruction &amp;lt;code&amp;gt;add_subdirectory(LANGUAGE_CODE)&amp;lt;/code&amp;gt; in the &amp;lt;code&amp;gt;if(NOT WIN32)&amp;lt;/code&amp;gt; block (where ''LANGUAGE_CODE'' is the language code).&lt;br /&gt;
# Edit &amp;lt;code&amp;gt;man/LANGUAGE_CODE/man1/CMakeLists.txt&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;man/LANGUAGE_CODE/man5/CMakeLists.txt&amp;lt;/code&amp;gt;: on the last row, set the installation directory (&amp;lt;code&amp;gt;DESTINATION&amp;lt;/code&amp;gt;), respectively, to &amp;lt;code&amp;gt;${CMAKE_INSTALL_MANDIR}/LANGUAGE_CODE/man1&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;${CMAKE_INSTALL_MANDIR}/LANGUAGE_CODE/man5&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Open the man pages in the subdirectory of your language and translate them.&lt;br /&gt;
&lt;br /&gt;
== Related content ==&lt;br /&gt;
* [[Howto: Translate FlightGear Launch Control‎‎]]&lt;br /&gt;
* [[Translation requests]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Howto|Translate FlightGear]]&lt;/div&gt;</summary>
		<author><name>Elgaton</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Cessna_172P/info&amp;diff=112864</id>
		<title>Cessna 172P/info</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Cessna_172P/info&amp;diff=112864"/>
		<updated>2017-12-09T15:41:17Z</updated>

		<summary type="html">&lt;p&gt;Elgaton: Translate the template to Italian&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;includeonly&amp;gt;{{infobox aircraft&lt;br /&gt;
| name           = Cessna 172P Skyhawk&lt;br /&gt;
| hangar         = fgdata&lt;br /&gt;
| image          = c172p-thumbnail.jpg&lt;br /&gt;
| image2         = C172p-cockpit2.jpg&lt;br /&gt;
| type           = Civil aircraft/Civil utility aircraft&lt;br /&gt;
| config         = High wing aircraft/Fixed gear aircraft&lt;br /&gt;
| propulsion     = Propeller aircraft/Single-engine aircraft&lt;br /&gt;
| manufacturer   = Cessna&lt;br /&gt;
| authors        = David Megginson/Gilberto Agostinho/Wayne Bragg/Juan Vera del Campo/onox/Fernando Barbosa/Daniel Dubreuil/Jonathan Schellhase/Israel Hernandez/Tuomas Kuosmanen/Anders Gidenstam/Waldo Kitty/algefaen&lt;br /&gt;
| fdm            = JSBSim&lt;br /&gt;
| fgname         = c172p&lt;br /&gt;
| status-fdm     = 4&lt;br /&gt;
| status-systems = 5&lt;br /&gt;
| status-cockpit = 5&lt;br /&gt;
| status-model   = 4&lt;br /&gt;
| ready          = tutorials/checklist&lt;br /&gt;
| devel-repo     = {{github url|user=Juanvvc|repo=c172p-detailed}}&lt;br /&gt;
| download       = {{github zip file|user=Juanvvc|repo=c172p-detailed|full=1}}&lt;br /&gt;
| liverydbid     = 70&lt;br /&gt;
| forumtid       = 25157&lt;br /&gt;
| note           = {{LangSwitch&lt;br /&gt;
                     | ar = هذه هيا طائرة فلايت جير الإفتراضية ويتم توزيعها كجزء من حزمة البرنامج&lt;br /&gt;
                     | en = This is the default FlightGear aircraft and is distributed as part of the base package.&lt;br /&gt;
                     | de = Dies ist das FlightGear Standardflugzeug und im Basispaket der Software enthalten.&lt;br /&gt;
                     | es = Este es el avión predeterminado de FlightGear y se distribuye como parte de la descarga de FlightGear. &lt;br /&gt;
                     | it = Questo è l'aeromobile predefinito di FlightGear ed è distribuito come parte del pacchetto di base.&lt;br /&gt;
                     | zh = 这是FlightGear的默认机型，并被包括在FlightGear主程序中。&lt;br /&gt;
                   }}&lt;br /&gt;
| navbar         = 1&lt;br /&gt;
}}&amp;lt;/includeonly&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
This is the aircraft infobox subpage of the [[Cessna 172P]].&lt;br /&gt;
[[Category:Aircraft infobox documentation]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Elgaton</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Template:Infobox_aircraft&amp;diff=112863</id>
		<title>Template:Infobox aircraft</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Template:Infobox_aircraft&amp;diff=112863"/>
		<updated>2017-12-09T15:40:17Z</updated>

		<summary type="html">&lt;p&gt;Elgaton: Partially translate the template to Italian&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;includeonly&amp;gt;{{Infobox&lt;br /&gt;
| title       = {{{name|{{LangSwitch&lt;br /&gt;
                          | de = Unbekanntes Flugzeug&lt;br /&gt;
                          | en = Unknown Aircraft&lt;br /&gt;
                          | es = Avión desconocido&lt;br /&gt;
                          | fr = Aéronef Inconnu&lt;br /&gt;
                          | it = Aeromobile sconosciuto&lt;br /&gt;
                          | th = เครื่องบินที่ไม่รู้จัก&lt;br /&gt;
                          | zh = 未知机型&lt;br /&gt;
                        }}&lt;br /&gt;
                }}}&lt;br /&gt;
| above{{#if:{{{hangar|}}}||NULL}}&lt;br /&gt;
              = {{hangar banner|{{{hangar}}}}}&lt;br /&gt;
| image       = {{#if: {{{image|}}}&lt;br /&gt;
                  | [[File:{{{image}}}|300px|{{{alt|}}}]]&lt;br /&gt;
                  | [[Special:UploadWizard|{{LangSwitch&lt;br /&gt;
                          | de = Benötigt ein Bild&lt;br /&gt;
                          | en = Image requested&lt;br /&gt;
                          | es = Necesita una imagen&lt;br /&gt;
                          | it = Immagine richiesta&lt;br /&gt;
                          | th = ถ่ายรูปเครื่องบินนี้เลยสิ!&lt;br /&gt;
                          | zh = 需要图片&lt;br /&gt;
                         }}]] [[Category:Aircraft requiring a screenshot]]&lt;br /&gt;
                }}&lt;br /&gt;
| caption     = {{{alt|}}}&lt;br /&gt;
| image2      = {{#if: {{{image2|}}}&lt;br /&gt;
                  | [[File:{{{image2}}}{{!}}300px|{{{alt2|}}}]]&lt;br /&gt;
                  | [[Category:Aircraft requiring a cockpit screenshot]]&lt;br /&gt;
                }}&lt;br /&gt;
| caption2    = {{{alt2|}}}&lt;br /&gt;
| label1      = {{LangSwitch&lt;br /&gt;
                  | de = Typ&lt;br /&gt;
                  | en = Type&lt;br /&gt;
                  | es = Tipo&lt;br /&gt;
                  | fr = Type&lt;br /&gt;
                  | it = Tipo&lt;br /&gt;
                  | ja = て&lt;br /&gt;
                  | nl = Type&lt;br /&gt;
                  | pl = Typu&lt;br /&gt;
                  | pt = Tipo&lt;br /&gt;
                  | ru = тип&lt;br /&gt;
                  | th = ชนิดเครื่องบิน&lt;br /&gt;
                  | zh = 类型&lt;br /&gt;
                }}&lt;br /&gt;
| data1       = {{craft type|{{#titleparts:/{{{type|}}}|1|2}}}}&amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{craft type|{{#titleparts:/{{{type|}}}|1|3}}|pre=, &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;}}&amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{craft type|{{#titleparts:/{{{type|}}}|1|4}}|pre=, &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;}}&amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{craft type|{{#titleparts:/{{{type|}}}|1|5}}|pre=, &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;}}&amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{craft type|{{#titleparts:/{{{type|}}}|1|6}}|pre=, &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;}}&amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{craft type|{{#titleparts:/{{{type|}}}|1|7}}|pre=, &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;}}&amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{craft type|{{#titleparts:/{{{type|}}}|1|8}}|pre=, &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;}}&amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{craft type|{{#titleparts:/{{{type|}}}|1|9}}|pre=, &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;}}&amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{craft type|{{#titleparts:/{{{type|}}}|1|10}}|pre=, &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;}}&amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{craft type|{{#titleparts:/{{{type|}}}|1|11}}|pre=, &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;}}&amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{craft type|{{#titleparts:/{{{type|}}}|1|12}}|pre=, &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;}}&amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{craft type|{{#titleparts:/{{{type|}}}|1|13}}|pre=, &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;}}&amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{craft type|{{#titleparts:/{{{type|}}}|1|14}}|pre=, &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;}}&amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{craft type|{{#titleparts:/{{{type|}}}|1|15}}|pre=, &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;}}&amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{craft type|{{#titleparts:/{{{type|}}}|1|16}}|pre=, &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;}}&amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{craft type|{{#titleparts:/{{{type|}}}|1|17}}|pre=, &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;}}&amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{craft type|{{#titleparts:/{{{type|}}}|1|18}}|pre=, &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;}}&amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{craft type|{{#titleparts:/{{{type|}}}|1|19}}|pre=, &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
| label2      = {{LangSwitch&lt;br /&gt;
                  | de = Konfiguration&lt;br /&gt;
                  | en = Configuration&lt;br /&gt;
                  | es = Configuración&lt;br /&gt;
                  | fi = Kokoonpanoon&lt;br /&gt;
                  | fr = Configuration&lt;br /&gt;
                  | it = Configurazione&lt;br /&gt;
                  | ja = 設定&lt;br /&gt;
                  | nl = Configuratie&lt;br /&gt;
                  | pl = Konfiguracja&lt;br /&gt;
                  | pt = Configuração&lt;br /&gt;
                  | ru = конфигурация&lt;br /&gt;
                  | th = โครงสร้างของเครื่องบิน&lt;br /&gt;
                  | zh = 构型&lt;br /&gt;
                }}&lt;br /&gt;
| data2       = {{craft configuration|{{#titleparts:/{{{config|}}}|1|2}}}}&amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{craft configuration|{{#titleparts:/{{{config|}}}|1|3}}|pre=, &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;}}&amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{craft configuration|{{#titleparts:/{{{config|}}}|1|4}}|pre=, &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;}}&amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{craft configuration|{{#titleparts:/{{{config|}}}|1|5}}|pre=, &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;}}&amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{craft configuration|{{#titleparts:/{{{config|}}}|1|6}}|pre=, &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;}}&amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{craft configuration|{{#titleparts:/{{{config|}}}|1|7}}|pre=, &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;}}&amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{craft configuration|{{#titleparts:/{{{config|}}}|1|8}}|pre=, &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;}}&amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{craft configuration|{{#titleparts:/{{{config|}}}|1|9}}|pre=, &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
| label3      = {{LangSwitch&lt;br /&gt;
                  | de = Antrieb&lt;br /&gt;
                  | en = Propulsion&lt;br /&gt;
                  | es = Propulsión&lt;br /&gt;
                  | fr = Propulsion&lt;br /&gt;
                  | it = Propulsione&lt;br /&gt;
                  | ja = 推進&lt;br /&gt;
                  | nl = Aandrijving&lt;br /&gt;
                  | pt = Propulsão&lt;br /&gt;
                  | ru = движение&lt;br /&gt;
                  | th = เครื่องยนต์&lt;br /&gt;
                  | zh = 动力&lt;br /&gt;
                }}&lt;br /&gt;
| data3       = {{craft propulsion|{{#titleparts:/{{{propulsion|}}}|1|2}}}}&amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{craft propulsion|{{#titleparts:/{{{propulsion|}}}|1|3}}|pre=, &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;}}&amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{craft propulsion|{{#titleparts:/{{{propulsion|}}}|1|4}}|pre=, &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;}}&amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{craft propulsion|{{#titleparts:/{{{propulsion|}}}|1|5}}|pre=, &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;}}&amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{craft propulsion|{{#titleparts:/{{{propulsion|}}}|1|6}}|pre=, &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;}}&amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{craft propulsion|{{#titleparts:/{{{propulsion|}}}|1|7}}|pre=, &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;}}&amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{craft propulsion|{{#titleparts:/{{{propulsion|}}}|1|8}}|pre=, &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;}}&amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{craft propulsion|{{#titleparts:/{{{propulsion|}}}|1|9}}|pre=, &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
| label4      = {{LangSwitch&lt;br /&gt;
                  | de = Hersteller&lt;br /&gt;
                  | en = Manufacturer&lt;br /&gt;
                  | es = Fabricante&lt;br /&gt;
                  | fr = Constructeur&lt;br /&gt;
                  | it = Costruttore&lt;br /&gt;
                  | ja = メーカー&lt;br /&gt;
                  | nl = Fabrikant&lt;br /&gt;
                  | pl = Producent&lt;br /&gt;
                  | pt = Fabricante&lt;br /&gt;
                  | ru = производитель&lt;br /&gt;
                  | th = ผู้ผลิต&lt;br /&gt;
                  | zh = 制造商&lt;br /&gt;
                }}&lt;br /&gt;
| data4       = {{craft manufacturer|{{#titleparts:/{{{manufacturer|}}}|1|2}}}}&amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{craft manufacturer|{{#titleparts:/{{{manufacturer|}}}|1|3}}|pre=, &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;}}&amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{craft manufacturer|{{#titleparts:/{{{manufacturer|}}}|1|4}}|pre=, &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;}}&amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{craft manufacturer|{{#titleparts:/{{{manufacturer|}}}|1|5}}|pre=, &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;}}&amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{craft manufacturer|{{#titleparts:/{{{manufacturer|}}}|1|6}}|pre=, &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;}}&amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{craft manufacturer|{{#titleparts:/{{{manufacturer|}}}|1|7}}|pre=, &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;}}&amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{craft manufacturer|{{#titleparts:/{{{manufacturer|}}}|1|8}}|pre=, &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;}}&amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{craft manufacturer|{{#titleparts:/{{{manufacturer|}}}|1|9}}|pre=, &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
| label5      = {{LangSwitch&lt;br /&gt;
                  | de = Autor(en)&lt;br /&gt;
                  | en = Author(s)&lt;br /&gt;
                  | es = Autor(es)&lt;br /&gt;
                  | fr = Créateur(s)&lt;br /&gt;
                  | it = Autore/i&lt;br /&gt;
                  | th = ผู้สร้าง(ใน FlightGear)&lt;br /&gt;
                  | zh = 作者&lt;br /&gt;
                }}&lt;br /&gt;
| data5       = {{#if: {{{devel-team|}}} | &amp;lt;div class=&amp;quot;toccolours mw-collapsible mw-collapsed&amp;quot; style=&amp;quot;padding: 0px; border: none&amp;quot;&amp;gt;{{{devel-team}}}&amp;lt;div class=&amp;quot;mw-collapsible-content&amp;quot;&amp;gt;}}&amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{#if: {{{authors|{{{author1|}}}}}}&lt;br /&gt;
                  | {{#if: {{#titleparts:/{{{authors|}}}|1|3}} &amp;lt;!-- Do not use a bullet list for single authors. --&amp;gt;&lt;br /&gt;
                      | {{#if: {{#titleparts:/{{{authors|}}}|1|2}}  | * {{#titleparts:/{{{authors|}}}|1|2}} }}&lt;br /&gt;
                      | {{#if: {{{author1|}}}&lt;br /&gt;
                          | {{#if: {{{authors|}}}&lt;br /&gt;
                              | {{#if: {{#titleparts:/{{{authors|}}}|1|2}}  | * {{#titleparts:/{{{authors|}}}|1|2}} }}&lt;br /&gt;
                              | {{#if: {{#titleparts:/{{{authors|}}}|1|2}}  | {{#titleparts:/{{{authors|}}}|1|2}} }}&lt;br /&gt;
                            }}&lt;br /&gt;
                          | {{#if: {{#titleparts:/{{{authors|}}}|1|2}}  | {{#titleparts:/{{{authors|}}}|1|2}} }}&lt;br /&gt;
                        }}&lt;br /&gt;
                    }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{#titleparts:/{{{authors|}}}|1|3}}  | * {{#titleparts:/{{{authors|}}}|1|3}}  }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{#titleparts:/{{{authors|}}}|1|4}}  | * {{#titleparts:/{{{authors|}}}|1|4}}  }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{#titleparts:/{{{authors|}}}|1|5}}  | * {{#titleparts:/{{{authors|}}}|1|5}}  }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{#titleparts:/{{{authors|}}}|1|6}}  | * {{#titleparts:/{{{authors|}}}|1|6}}  }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{#titleparts:/{{{authors|}}}|1|7}}  | * {{#titleparts:/{{{authors|}}}|1|7}}  }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{#titleparts:/{{{authors|}}}|1|8}}  | * {{#titleparts:/{{{authors|}}}|1|8}}  }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{#titleparts:/{{{authors|}}}|1|9}}  | * {{#titleparts:/{{{authors|}}}|1|9}}  }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{#titleparts:/{{{authors|}}}|1|10}} | * {{#titleparts:/{{{authors|}}}|1|10}} }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{#titleparts:/{{{authors|}}}|1|11}} | * {{#titleparts:/{{{authors|}}}|1|11}} }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{#titleparts:/{{{authors|}}}|1|12}} | * {{#titleparts:/{{{authors|}}}|1|12}} }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{#titleparts:/{{{authors|}}}|1|13}} | * {{#titleparts:/{{{authors|}}}|1|13}} }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{#titleparts:/{{{authors|}}}|1|14}} | * {{#titleparts:/{{{authors|}}}|1|14}} }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{#titleparts:/{{{authors|}}}|1|15}} | * {{#titleparts:/{{{authors|}}}|1|15}} }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{#titleparts:/{{{authors|}}}|1|16}} | * {{#titleparts:/{{{authors|}}}|1|16}} }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{#titleparts:/{{{authors|}}}|1|17}} | * {{#titleparts:/{{{authors|}}}|1|17}} }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{#titleparts:/{{{authors|}}}|1|18}} | * {{#titleparts:/{{{authors|}}}|1|18}} }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{#titleparts:/{{{authors|}}}|1|19}} | * {{#titleparts:/{{{authors|}}}|1|19}} }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{#titleparts:/{{{authors|}}}|1|20}} | * {{#titleparts:/{{{authors|}}}|1|20}} }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{#titleparts:/{{{authors|}}}|1|21}} | * {{#titleparts:/{{{authors|}}}|1|21}} }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{#titleparts:/{{{authors|}}}|1|22}} | * {{#titleparts:/{{{authors|}}}|1|22}} }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{#titleparts:/{{{authors|}}}|1|23}} | * {{#titleparts:/{{{authors|}}}|1|23}} }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{#titleparts:/{{{authors|}}}|1|24}} | * {{#titleparts:/{{{authors|}}}|1|24}} }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{#titleparts:/{{{authors|}}}|1|25}} | * {{#titleparts:/{{{authors|}}}|1|25}} }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{{authors|}}} &amp;lt;!-- Do not use a bullet list for single authors. --&amp;gt;&lt;br /&gt;
                      | {{#if: {{{author1|}}}  | * {{{author1}}} }}&lt;br /&gt;
                      | {{#if: {{{author2|}}}&lt;br /&gt;
                          | {{#if: {{{author1|}}}  | * {{{author1}}} }}&lt;br /&gt;
                          | {{#if: {{{author1|}}}  |   {{{author1}}} }}&lt;br /&gt;
                        }}&lt;br /&gt;
                    }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{{author2|}}}  | * {{{author2}}}  }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{{author3|}}}  | * {{{author3}}}  }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{{author4|}}}  | * {{{author4}}}  }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{{author5|}}}  | * {{{author5}}}  }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{{author6|}}}  | * {{{author6}}}  }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{{author7|}}}  | * {{{author7}}}  }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{{author8|}}}  | * {{{author8}}}  }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{{author9|}}}  | * {{{author9}}}  }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{{author10|}}} | * {{{author10}}} }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{{author11|}}} | * {{{author11}}} }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{{author12|}}} | * {{{author12}}} }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{{author13|}}} | * {{{author13}}} }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{{author14|}}} | * {{{author14}}} }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{{author15|}}} | * {{{author15}}} }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{{author16|}}} | * {{{author16}}} }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{{author17|}}} | * {{{author17}}} }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{{author18|}}} | * {{{author18}}} }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{{author19|}}} | * {{{author19}}} }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{{author20|}}} | * {{{author20}}} }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{{author21|}}} | * {{{author21}}} }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{{author22|}}} | * {{{author22}}} }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{{author23|}}} | * {{{author23}}} }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{{author24|}}} | * {{{author24}}} }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{{author25|}}} | * {{{author25}}} }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{{author26|}}} | * {{{author26}}} }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{{author27|}}} | * {{{author27}}} }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{{author28|}}} | * {{{author28}}} }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{{author29|}}} | * {{{author29}}} }}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{{author30|}}} | * {{{author30}}} }}&lt;br /&gt;
                  | {{LangSwitch&lt;br /&gt;
                      | de = Unbekannt&lt;br /&gt;
                      | en = Unknown&lt;br /&gt;
                      | es = Desconocido&lt;br /&gt;
                      | fr = Inconnu&lt;br /&gt;
                      | it = Sconosciuto&lt;br /&gt;
                      | th = ไม่ทราบ&lt;br /&gt;
                      | zh = 未知&lt;br /&gt;
                    }}&lt;br /&gt;
                }}&amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{#if: {{{devel-team|}}} | &amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;}}&lt;br /&gt;
| label6      = FDM&lt;br /&gt;
| data6       = {{#if: {{{fdm|}}}&lt;br /&gt;
                  | {{FDM link|{{#titleparts:/{{{fdm|}}}|1|2}}}}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{FDM link|{{#titleparts:/{{{fdm|}}}|1|3}}|pre=, &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;}}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{FDM link|{{#titleparts:/{{{fdm|}}}|1|4}}|pre=, &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;}}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{FDM link|{{#titleparts:/{{{fdm|}}}|1|5}}|pre=, &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;}}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{FDM link|{{#titleparts:/{{{fdm|}}}|1|6}}|pre=, &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;}}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{FDM link|{{#titleparts:/{{{fdm|}}}|1|7}}|pre=, &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;}}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{FDM link|{{#titleparts:/{{{fdm|}}}|1|8}}|pre=, &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;}}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{FDM link|{{#titleparts:/{{{fdm|}}}|1|9}}|pre=, &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
                  | {{LangSwitch&lt;br /&gt;
                      | de = Unbekannt&lt;br /&gt;
                      | en = Unknown&lt;br /&gt;
                      | es = Desconocido&lt;br /&gt;
                      | fr = Inconnu&lt;br /&gt;
                      | it = Sconosciuto&lt;br /&gt;
                      | th = ไม่ทราบ&lt;br /&gt;
                      | zh = 未知&lt;br /&gt;
                    }}&lt;br /&gt;
                }}&lt;br /&gt;
| label7      = --aircraft=&lt;br /&gt;
| data7       = {{#if: {{{fgname|}}}&lt;br /&gt;
                  | {{#if: {{#titleparts:/{{{fgname|}}}|1|2}} | &amp;lt;tt&amp;gt;{{#titleparts:/{{{fgname|}}}|1|2}}&amp;lt;/tt&amp;gt;}}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{#titleparts:/{{{fgname|}}}|1|3}} | &amp;lt;tt&amp;gt;&amp;lt;br/&amp;gt;{{#titleparts:/{{{fgname|}}}|1|3}}&amp;lt;/tt&amp;gt;}}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{#titleparts:/{{{fgname|}}}|1|4}} | &amp;lt;tt&amp;gt;&amp;lt;br/&amp;gt;{{#titleparts:/{{{fgname|}}}|1|4}}&amp;lt;/tt&amp;gt;}}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{#titleparts:/{{{fgname|}}}|1|5}} | &amp;lt;tt&amp;gt;&amp;lt;br/&amp;gt;{{#titleparts:/{{{fgname|}}}|1|5}}&amp;lt;/tt&amp;gt;}}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{#titleparts:/{{{fgname|}}}|1|6}} | &amp;lt;tt&amp;gt;&amp;lt;br/&amp;gt;{{#titleparts:/{{{fgname|}}}|1|6}}&amp;lt;/tt&amp;gt;}}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{#titleparts:/{{{fgname|}}}|1|7}} | &amp;lt;tt&amp;gt;&amp;lt;br/&amp;gt;{{#titleparts:/{{{fgname|}}}|1|7}}&amp;lt;/tt&amp;gt;}}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{#titleparts:/{{{fgname|}}}|1|8}} | &amp;lt;tt&amp;gt;&amp;lt;br/&amp;gt;{{#titleparts:/{{{fgname|}}}|1|8}}&amp;lt;/tt&amp;gt;}}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{#titleparts:/{{{fgname|}}}|1|9}} | &amp;lt;tt&amp;gt;&amp;lt;br/&amp;gt;{{#titleparts:/{{{fgname|}}}|1|9}}&amp;lt;/tt&amp;gt;}}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{#titleparts:/{{{fgname|}}}|1|10}} | &amp;lt;tt&amp;gt;&amp;lt;br/&amp;gt;{{#titleparts:/{{{fgname|}}}|1|10}}&amp;lt;/tt&amp;gt;}}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{#titleparts:/{{{fgname|}}}|1|11}} | &amp;lt;tt&amp;gt;&amp;lt;br/&amp;gt;{{#titleparts:/{{{fgname|}}}|1|11}}&amp;lt;/tt&amp;gt;}}&amp;lt;!--&lt;br /&gt;
                 --&amp;gt;{{#if: {{#titleparts:/{{{fgname|}}}|1|12}} | &amp;lt;tt&amp;gt;&amp;lt;br/&amp;gt;{{#titleparts:/{{{fgname|}}}|1|12}}&amp;lt;/tt&amp;gt;}}&lt;br /&gt;
                }}&amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{#if: {{{fgname1|}}}&lt;br /&gt;
                  | {{#if: {{{fgname|}}}&lt;br /&gt;
                      | &amp;lt;tt&amp;gt;&amp;lt;br/&amp;gt;{{{fgname1}}}&amp;lt;/tt&amp;gt;&lt;br /&gt;
                      | &amp;lt;tt&amp;gt;{{{fgname1}}}&amp;lt;/tt&amp;gt;&lt;br /&gt;
                    }}&lt;br /&gt;
                }}&amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{#if: {{{fgname2|}}}  | &amp;lt;tt&amp;gt;&amp;lt;br/&amp;gt;{{{fgname2}}}&amp;lt;/tt&amp;gt;}}&amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{#if: {{{fgname3|}}}  | &amp;lt;tt&amp;gt;&amp;lt;br/&amp;gt;{{{fgname3}}}&amp;lt;/tt&amp;gt;}}&amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{#if: {{{fgname4|}}}  | &amp;lt;tt&amp;gt;&amp;lt;br/&amp;gt;{{{fgname4}}}&amp;lt;/tt&amp;gt;}}&amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{#if: {{{fgname5|}}}  | &amp;lt;tt&amp;gt;&amp;lt;br/&amp;gt;{{{fgname5}}}&amp;lt;/tt&amp;gt;}}&amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{#if: {{{fgname6|}}}  | &amp;lt;tt&amp;gt;&amp;lt;br/&amp;gt;{{{fgname6}}}&amp;lt;/tt&amp;gt;}}&amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{#if: {{{fgname7|}}}  | &amp;lt;tt&amp;gt;&amp;lt;br/&amp;gt;{{{fgname7}}}&amp;lt;/tt&amp;gt;}}&amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{#if: {{{fgname8|}}}  | &amp;lt;tt&amp;gt;&amp;lt;br/&amp;gt;{{{fgname8}}}&amp;lt;/tt&amp;gt;}}&amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{#if: {{{fgname9|}}}  | &amp;lt;tt&amp;gt;&amp;lt;br/&amp;gt;{{{fgname9}}}&amp;lt;/tt&amp;gt;}}&amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{#if: {{{fgname10|}}} | &amp;lt;tt&amp;gt;&amp;lt;br/&amp;gt;{{{fgname10}}}&amp;lt;/tt&amp;gt;}}&lt;br /&gt;
| label8      = {{LangSwitch&lt;br /&gt;
                  | de = Stand&lt;br /&gt;
                  | en = Status&lt;br /&gt;
                  | es = Estado&lt;br /&gt;
                  | fr = Etat&lt;br /&gt;
                  | it = Stato&lt;br /&gt;
                  | ja = ステータス&lt;br /&gt;
                  | nl = Status&lt;br /&gt;
                  | pl = Status&lt;br /&gt;
                  | pt = Situação&lt;br /&gt;
                  | ru = статус&lt;br /&gt;
                  | th = คะแนนความละเอียด&lt;br /&gt;
                  | zh = 开发状况&lt;br /&gt;
                }}&lt;br /&gt;
| data8       = {{#if: {{{status-fdm|}}}&lt;br /&gt;
                  | {{#ifexpr: {{#expr: {{{status-fdm|}}}+{{{status-systems|}}}+{{{status-cockpit|}}}+{{{status-model|}}} }} &amp;gt; 17&lt;br /&gt;
                      | {{LangSwitch&lt;br /&gt;
                          | de = [[De/Flugzeugbewertung#Gesamtwertung|Fortgeschrittene Produktion]]&lt;br /&gt;
                          | en = [[Aircraft rating system#Overall status|Advanced production]]&lt;br /&gt;
                          | es = [[Aircraft rating system#Overall status|Producción avanzada]]&lt;br /&gt;
                          | fr = [[Fr/Aircraft status indication#Statut global|Production avancée]]&lt;br /&gt;
                        }}&lt;br /&gt;
                        [[Category:Aircraft status: Advanced production]]&lt;br /&gt;
                      | {{#ifexpr: {{#expr: {{{status-fdm|}}}+{{{status-systems|}}}+{{{status-cockpit|}}}+{{{status-model|}}} }} &amp;gt; 15&lt;br /&gt;
                          | {{LangSwitch&lt;br /&gt;
                              | de = [[De/Flugzeugbewertung#Gesamtwertung|Produktion]]&lt;br /&gt;
                              | en = [[Aircraft rating system#Overall status|Production]]&lt;br /&gt;
                              | es = [[Aircraft rating system#Overall status|Producción]]&lt;br /&gt;
                              | fr = [[Fr/Aircraft status indication#Statut global|Production]]&lt;br /&gt;
                            }}&lt;br /&gt;
                            [[Category:Aircraft status: Production]]&lt;br /&gt;
                          | {{#ifexpr: {{#expr: {{{status-fdm|}}}+{{{status-systems|}}}+{{{status-cockpit|}}}+{{{status-model|}}} }} &amp;gt; 11&lt;br /&gt;
                              | {{LangSwitch&lt;br /&gt;
                                  | de = [[De/Flugzeugbewertung#Gesamtwertung|Frühe Produktion]]&lt;br /&gt;
                                  | en = [[Aircraft rating system#Overall status|Early production]]&lt;br /&gt;
                                  | es = [[Aircraft rating system#Overall status|Producción temprana]]&lt;br /&gt;
                                  | fr = [[Fr/Aircraft status indication#Statut global|Production précoce]]&lt;br /&gt;
                                }}&lt;br /&gt;
                                [[Category:Aircraft status: Early production]]&lt;br /&gt;
                              | {{#ifexpr: {{#expr: {{{status-fdm|}}}+{{{status-systems|}}}+{{{status-cockpit|}}}+{{{status-model|}}} }} &amp;gt; 8&lt;br /&gt;
                                  | {{LangSwitch&lt;br /&gt;
                                      | de = [[De/Flugzeugbewertung#Gesamtwertung|Beta]]&lt;br /&gt;
                                      | en = [[Aircraft rating system#Overall status|Beta]]&lt;br /&gt;
                                      | fr = [[Fr/Aircraft status indication#Statut global|Bêta]]&lt;br /&gt;
                                    }}&lt;br /&gt;
                                    [[Category:Aircraft status: Beta]]&lt;br /&gt;
                                  | {{#ifexpr: {{#expr: {{{status-fdm|}}}+{{{status-systems|}}}+{{{status-cockpit|}}}+{{{status-model|}}} }} &amp;lt; 9&lt;br /&gt;
                                      | {{LangSwitch&lt;br /&gt;
                                          | de = [[De/Flugzeugbewertung#Gesamtwertung|Alpha]]&lt;br /&gt;
                                          | en = [[Aircraft rating system#Overall status|Alpha]]&lt;br /&gt;
                                          | fr = [[Fr/Aircraft status indication#Statut global|Alpha]]&lt;br /&gt;
                                        }}&lt;br /&gt;
                                        [[Category:Aircraft status: Alpha]]&lt;br /&gt;
                                      |&lt;br /&gt;
                                    }}&lt;br /&gt;
                                }}&lt;br /&gt;
                            }}&lt;br /&gt;
                        }}&lt;br /&gt;
                    }}&lt;br /&gt;
                  | {{#if:{{{status|}}}&lt;br /&gt;
                      | {{LangSwitch&lt;br /&gt;
                          | de = [[De/Flugzeugbewertung|{{{status}}}]]&lt;br /&gt;
                          | en = [[Aircraft rating system|{{{status}}}]]&lt;br /&gt;
                          | fr = [[Fr/Aircraft status indication|{{{status}}}]]&lt;br /&gt;
                        }}&lt;br /&gt;
                      | {{LangSwitch&lt;br /&gt;
                          | de = [[De/Flugzeugbewertung|Unbekannt]]&lt;br /&gt;
                          | en = [[Aircraft rating system|Unknown]]&lt;br /&gt;
                          | es = [[Aircraft rating system|Desconocido]]&lt;br /&gt;
                          | fr = [[Fr/Aircraft status indication|Inconnu]]&lt;br /&gt;
                        }}&lt;br /&gt;
                    }}&lt;br /&gt;
                }}&lt;br /&gt;
| label9      = &amp;amp;emsp;FDM&lt;br /&gt;
| data9       = {{#if:{{{status-fdm|}}}&lt;br /&gt;
                  | [[File:stars-{{{status-fdm}}}.png&amp;lt;!--&lt;br /&gt;
                   --&amp;gt;|link={{LangSwitch&lt;br /&gt;
                              | de = De/Flugzeugbewertung#Flight Dynamics Model (FDM)&lt;br /&gt;
                              | en = Aircraft rating system#Flight Dynamics Model (FDM)&lt;br /&gt;
                              | fr = Fr/Aircraft status indication#Modèle de vol dynamique&lt;br /&gt;
                            }}&lt;br /&gt;
                    ]]&amp;lt;!--&lt;br /&gt;
                  | [[File:stars-unrated.png|link=Aircraft rating system#Flight Dynamics Model (FDM)]]--&amp;gt;&lt;br /&gt;
                }}&lt;br /&gt;
| label10     = &amp;amp;emsp;{{LangSwitch&lt;br /&gt;
                        | de = Systeme&lt;br /&gt;
                        | en = Systems&lt;br /&gt;
                        | es = Sistemas&lt;br /&gt;
                        | fr = Systèmes&lt;br /&gt;
                        | it = Sistemi&lt;br /&gt;
                        | th = ระบบที่ใช้งานได้&lt;br /&gt;
                        | zh = 系统&lt;br /&gt;
                      }}&lt;br /&gt;
| data10      = {{#if:{{{status-systems|}}}&lt;br /&gt;
                  | [[File:stars-{{{status-systems}}}.png&amp;lt;!--&lt;br /&gt;
                   --&amp;gt;|link={{LangSwitch&lt;br /&gt;
                              | de = De/Flugzeugbewertung#Systeme&lt;br /&gt;
                              | en = Aircraft rating system#Systems&lt;br /&gt;
                              | fr = Fr/Aircraft status indication#Systèmes&lt;br /&gt;
                            }}&lt;br /&gt;
                    ]]&amp;lt;!--&lt;br /&gt;
                  | [[File:stars-unrated.png|link=Aircraft rating system#Systems]]--&amp;gt;&lt;br /&gt;
                }}&lt;br /&gt;
| label11     = &amp;amp;emsp;{{LangSwitch&lt;br /&gt;
                        | ca = Cabina de pilotatge&lt;br /&gt;
                        | de = Cockpit&lt;br /&gt;
                        | en = Cockpit&lt;br /&gt;
                        | es = Cabina de vuelo&lt;br /&gt;
                        | fi = Ohjaamo&lt;br /&gt;
                        | fr = Cockpit&lt;br /&gt;
                        | it = Cabina di pilotaggio&lt;br /&gt;
                        | ja = コックピット&lt;br /&gt;
                        | nl = Cockpit&lt;br /&gt;
                        | pl = Kokpit&lt;br /&gt;
                        | pt = Cabine de pilotagem&lt;br /&gt;
                        | ru = Кабина&lt;br /&gt;
                        | sl = Pilotska kabina&lt;br /&gt;
                        | th = ห้องนักบินและปุ่มต่างๆ&lt;br /&gt;
                        | zh = 驾驶舱&lt;br /&gt;
                      }}&lt;br /&gt;
| data11      = {{#if:{{{status-cockpit|}}}&lt;br /&gt;
                  | [[File:stars-{{{status-cockpit}}}.png&amp;lt;!--&lt;br /&gt;
                   --&amp;gt;|link={{LangSwitch&lt;br /&gt;
                              | de = De/Flugzeugbewertung#Cockpit&lt;br /&gt;
                              | en = Aircraft rating system#Cockpit&lt;br /&gt;
                              | fr = Fr/Aircraft status indication#Cockpit&lt;br /&gt;
                            }}&lt;br /&gt;
                    ]]&amp;lt;!--&lt;br /&gt;
                  | [[File:stars-unrated.png|link=Aircraft rating system#Cockpit]]--&amp;gt;&lt;br /&gt;
                }}&lt;br /&gt;
| label12     = &amp;amp;emsp;{{LangSwitch&lt;br /&gt;
                        | de = Modell&lt;br /&gt;
                        | en = Model&lt;br /&gt;
                        | es = Modelo&lt;br /&gt;
                        | fr = Modèle&lt;br /&gt;
                        | it = Modello&lt;br /&gt;
                        | th = แบบจำลอง&lt;br /&gt;
                        | zh = 模型&lt;br /&gt;
                      }}&lt;br /&gt;
| data12      = {{#if:{{{status-model|}}}&lt;br /&gt;
                  | [[File:stars-{{{status-model}}}.png&amp;lt;!--&lt;br /&gt;
                   --&amp;gt;|link={{LangSwitch&lt;br /&gt;
                              | de = De/Flugzeugbewertung#Äußeres Modell&lt;br /&gt;
                              | en = Aircraft rating system#External Model&lt;br /&gt;
                              | fr = Fr/Aircraft status indication#Modèle externe&lt;br /&gt;
                            }}&lt;br /&gt;
                    ]]&amp;lt;!--&lt;br /&gt;
                  | [[File:stars-unrated.png|link=Aircraft rating system#External Model]]--&amp;gt;&lt;br /&gt;
                }}&lt;br /&gt;
| label13     = {{LangSwitch&lt;br /&gt;
                  | de = Unterstützt&lt;br /&gt;
                  | en = Supports&lt;br /&gt;
                  | es = Apoya&lt;br /&gt;
                  | fr = Soutien&lt;br /&gt;
                  | it = Supporta&lt;br /&gt;
                  | th = คุณลักษณะที่สนับสนุน&lt;br /&gt;
                  | zh = 支持功能&lt;br /&gt;
                }}&lt;br /&gt;
| data13      = {{Ready|{{#titleparts:/{{{ready|}}}|1|2}}}} &amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{Ready|{{#titleparts:/{{{ready|}}}|1|3}}}} &amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{Ready|{{#titleparts:/{{{ready|}}}|1|4}}}} &amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{Ready|{{#titleparts:/{{{ready|}}}|1|5}}}} &amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{Ready|{{#titleparts:/{{{ready|}}}|1|6}}}} &amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{Ready|{{#titleparts:/{{{ready|}}}|1|7}}}} &amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{Ready|{{#titleparts:/{{{ready|}}}|1|8}}}} &amp;lt;!--&lt;br /&gt;
             --&amp;gt;{{Ready|{{#titleparts:/{{{ready|}}}|1|9}}}}&lt;br /&gt;
| label20     = {{LangSwitch&lt;br /&gt;
                  | de = Entwicklung&lt;br /&gt;
                  | en = Development&lt;br /&gt;
                  | es = Desarrollo&lt;br /&gt;
                  | fr = Développement&lt;br /&gt;
                  | it = Sviluppo&lt;br /&gt;
                  | ja = 開発&lt;br /&gt;
                  | nl = Ontwikkeling&lt;br /&gt;
                  | pl = Rozwój&lt;br /&gt;
                  | pt = Desenvolvimento&lt;br /&gt;
                  | ru = развитие&lt;br /&gt;
                  | th = ที่พัฒนา&lt;br /&gt;
                  | zh = 开发&lt;br /&gt;
                }}&lt;br /&gt;
| data20      = {{#if: {{{devel-hangar|}}}&lt;br /&gt;
                  | &amp;amp;emsp;&lt;br /&gt;
                  | {{#if: {{{devel-website|}}}&lt;br /&gt;
                      | &amp;amp;emsp;&lt;br /&gt;
                      | {{#if: {{{devel-repo|}}}&lt;br /&gt;
                          | &amp;amp;emsp;&lt;br /&gt;
                          | {{#if: {{{development|}}}&lt;br /&gt;
                              | &amp;amp;emsp;&lt;br /&gt;
                              | {{#switch: {{{hangar|none}}}&lt;br /&gt;
                                  | bermuda&lt;br /&gt;
                                  | none =&lt;br /&gt;
                                  | #default = &amp;amp;emsp;&lt;br /&gt;
                                }}&lt;br /&gt;
                            }}&lt;br /&gt;
                        }}&lt;br /&gt;
                    }}&lt;br /&gt;
                }}&lt;br /&gt;
| label21     = &amp;amp;emsp;{{LangSwitch&lt;br /&gt;
                        | de = Hangar&lt;br /&gt;
                        | en = Hangar&lt;br /&gt;
                        | es = Hangar&lt;br /&gt;
                        | fr = Hangar&lt;br /&gt;
                        | it = Hangar&lt;br /&gt;
                        | th = หน่วยงาน (&amp;quot;Hangar&amp;quot;)&lt;br /&gt;
                        | zh = 机库&lt;br /&gt;
                      }}&lt;br /&gt;
| data21      = {{hangar banner|{{{devel-hangar|}}}|size=180px}}&lt;br /&gt;
| label22     = &amp;amp;emsp;{{LangSwitch&lt;br /&gt;
                        | de = Webseite&lt;br /&gt;
                        | en = Website&lt;br /&gt;
                        | es = Página web&lt;br /&gt;
                        | fr = Site Internet&lt;br /&gt;
                        | it = Sito Web&lt;br /&gt;
                        | ja = ウェブサイト&lt;br /&gt;
                        | nl = Website&lt;br /&gt;
                        | pl = Strona&lt;br /&gt;
                        | pt = Website&lt;br /&gt;
                        | ru = веб-сайт&lt;br /&gt;
                        | th = เว็บไซต์ของหน่วยงาน&lt;br /&gt;
                        | zh = 网站&lt;br /&gt;
                      }}&lt;br /&gt;
| data22      = {{#if: {{{devel-website|}}}&lt;br /&gt;
                  | [[File:Applications-internet 32x32.png &amp;lt;!--&lt;br /&gt;
                   --&amp;gt;| 30px &amp;lt;!--&lt;br /&gt;
                   --&amp;gt;| {{LangSwitch&lt;br /&gt;
                          | de = Die Webseite für die Entwicklungen von {{{name|}}}.&lt;br /&gt;
                          | en = The website for the {{{name|}}} developments.&lt;br /&gt;
                          | es = La página web para los desarrollos de {{{name|}}}.&lt;br /&gt;
                          | fr = Le site internet des développements de {{{name|}}}.&lt;br /&gt;
                          | it = Il sito Web di sviluppo di {{{name|}}}.&lt;br /&gt;
                          | th = เว็บไซต์ของผู้ที่พัฒนา {{{name|}}}&lt;br /&gt;
                        }} &amp;lt;!--&lt;br /&gt;
                   --&amp;gt;| link={{{devel-website}}}&lt;br /&gt;
                    ]]&lt;br /&gt;
                  | {{#switch: {{{hangar|}}}&lt;br /&gt;
                      | aucafly&lt;br /&gt;
                      | buckaroo&lt;br /&gt;
                      | bulldogrs&lt;br /&gt;
                      | dave&lt;br /&gt;
                      | fgaddon&lt;br /&gt;
                      | fguk&lt;br /&gt;
                      | helijah&lt;br /&gt;
                      | herbyw&lt;br /&gt;
                      | lake of constance&lt;br /&gt;
                      | paf&lt;br /&gt;
                      | prestes =&lt;br /&gt;
                        [[File:Applications-internet 32x32.png &amp;lt;!--&lt;br /&gt;
                       --&amp;gt;| 30px &amp;lt;!--&lt;br /&gt;
                       --&amp;gt;| {{LangSwitch&lt;br /&gt;
                              | de = Die Webseite für die Entwicklungen von {{{name|}}}.&lt;br /&gt;
                              | en = The website for the {{{name|}}} developments.&lt;br /&gt;
                              | es = La página web para los desarrollos de {{{name|}}}.&lt;br /&gt;
                              | fr = Le site internet des développements de {{{name|}}}.&lt;br /&gt;
                              | fr = Il sito Web di sviluppo di {{{name|}}}.&lt;br /&gt;
                              | th = เว็บไซต์ของผู้ที่พัฒนา {{{name|}}}&lt;br /&gt;
                              | zh = 用于开发{{{name|}}}的网站&lt;br /&gt;
                            }} &amp;lt;!--&lt;br /&gt;
                       --&amp;gt;| link={{#switch: {{{hangar|}}}&lt;br /&gt;
                                   | aucafly           = https://aucafly.wordpress.com/&lt;br /&gt;
                                   | buckaroo          = http://www.buckarooshangar.com/flightgear/&lt;br /&gt;
                                   | bulldogrs         = https://bulldogrs.wordpress.com/&lt;br /&gt;
                                   | dave              = http://www.daveshangar.org/&lt;br /&gt;
                                   | fgaddon           = http://wiki.flightgear.org/FGAddon&lt;br /&gt;
                                   | fguk              = http://fguk.eu/index.php/hangar&lt;br /&gt;
                                   | helijah           = {{LangSwitch&lt;br /&gt;
                                                             | en = http://helijah.free.fr/flightgear/hangaren.htm&lt;br /&gt;
                                                             | fr = http://helijah.free.fr/flightgear/hangar.htm&lt;br /&gt;
                                                          }}&lt;br /&gt;
                                   | herbyw            = https://github.com/HerbyW&lt;br /&gt;
                                   | lake of constance = http://www.marc-kraus.de&lt;br /&gt;
                                   | paf               = http://equipe-flightgear.forumactif.com/t835-hangar-de-la-p-a-f-paf-team-hangar&lt;br /&gt;
                                   | prestes           = http://presteshangar.wikidot.com/{{{aircraft|}}}&lt;br /&gt;
                                 }}&lt;br /&gt;
                        ]]&lt;br /&gt;
                    }}&lt;br /&gt;
                }}&lt;br /&gt;
| label23     = &amp;amp;emsp;{{LangSwitch&lt;br /&gt;
                        | de = Repository&lt;br /&gt;
                        | en = Repository&lt;br /&gt;
                        | es = Repositorio&lt;br /&gt;
                        | fr = Référentiel&lt;br /&gt;
                        | it = Repository&lt;br /&gt;
                        | ja = レポジトリ&lt;br /&gt;
                        | nl = Repository&lt;br /&gt;
                        | pl = Repozytorium&lt;br /&gt;
                        | pt = Repositório&lt;br /&gt;
                        | ru = хранилище&lt;br /&gt;
                        | zh = 代码仓库&lt;br /&gt;
                      }}&lt;br /&gt;
| data23      = {{#if:{{{devel-repo|{{{development|}}}}}}&lt;br /&gt;
                  | [[File:Preferences-system 32x32.png &amp;lt;!--&lt;br /&gt;
                   --&amp;gt;| 30px &amp;lt;!--&lt;br /&gt;
                   --&amp;gt;| {{LangSwitch&lt;br /&gt;
                          | de = Die Entwicklungs-Repository des {{{name|}}}.&lt;br /&gt;
                          | en = The development repository of the {{{name|}}}.&lt;br /&gt;
                          | es = El Repositorio de desarrollo de {{{name|}}}.&lt;br /&gt;
                          | fr = Le référentiel de développement du {{{name|}}}.&lt;br /&gt;
                          | it = Il repository di sviluppo di {{{name|}}}.&lt;br /&gt;
                          | th = Repository ที่ใช้พัฒนา {{{name|}}}&lt;br /&gt;
                        }} &amp;lt;!--&lt;br /&gt;
                   --&amp;gt;| link={{{devel-repo|{{{development|}}}}}}&lt;br /&gt;
                    ]]&lt;br /&gt;
                  | {{#switch: {{{hangar|}}}&lt;br /&gt;
                      | aucafly&lt;br /&gt;
                      | bulldogrs&lt;br /&gt;
                      | emilianh&lt;br /&gt;
                      | fgaddon&lt;br /&gt;
                      | herbyw&lt;br /&gt;
                      | it0uchpods = &lt;br /&gt;
                        [[File:Preferences-system 32x32.png &amp;lt;!--&lt;br /&gt;
                       --&amp;gt;| 30px &amp;lt;!--&lt;br /&gt;
                       --&amp;gt;| {{LangSwitch&lt;br /&gt;
                              | de = Die Entwicklungs-Repository des {{{name|}}}.&lt;br /&gt;
                              | en = The development repository of the {{{name|}}}.&lt;br /&gt;
                              | es = El Repositorio de desarrollo de {{{name|}}}.&lt;br /&gt;
                              | fr = Le référentiel de développement du {{{name|}}}.&lt;br /&gt;
                              | it = Il repository di sviluppo di {{{name|}}}.&lt;br /&gt;
                              | th = Repository ที่ใช้พัฒนา {{{name|}}}&lt;br /&gt;
                            }} &amp;lt;!--&lt;br /&gt;
                       --&amp;gt;| link={{#switch: {{{hangar|}}}&lt;br /&gt;
                                   | aucafly           = {{github url|proj=aucafly|repo={{{aircraft|}}}}}&lt;br /&gt;
                                   | bulldogrs         = {{github url|proj=aucafly|repo={{{aircraft|}}}}}&lt;br /&gt;
                                   | emilianh          = {{gitlab url|user=emilianh|repo={{{aircraft|}}}}}&lt;br /&gt;
                                   | fgaddon           = {{fgaddon aircraft url|{{{aircraft|}}}}}&lt;br /&gt;
                                   | herbyw            = {{github url|user=HerbyW|repo={{{aircraft|}}}}}&lt;br /&gt;
                                   | it0uchpods        = {{github url|user=it0uchpods|repo={{{aircraft|}}}}}&lt;br /&gt;
                                 }}&lt;br /&gt;
                        ]]&lt;br /&gt;
                    }}&lt;br /&gt;
                }}&lt;br /&gt;
| label30     = {{LangSwitch&lt;br /&gt;
                  | de = Herunterladen&lt;br /&gt;
                  | en = Download&lt;br /&gt;
                  | es = Descargar&lt;br /&gt;
                  | fr = Télécharger&lt;br /&gt;
                  | it = Download&lt;br /&gt;
                  | ja = ダウンロード&lt;br /&gt;
                  | ru = загрузка&lt;br /&gt;
                  | th = ดาวน์โหลด&lt;br /&gt;
                  | zh = 下载地址&lt;br /&gt;
                }}&lt;br /&gt;
| data30      = {{#if: {{{download|{{{hangar|}}}}}}&lt;br /&gt;
                  | {{#switch: {{{download|{{{hangar|none}}}}}}&lt;br /&gt;
                      | bermuda&lt;br /&gt;
                      | prestes&lt;br /&gt;
                      | none =&lt;br /&gt;
                      | #default = [[File:Folder-downloads 32x32.png &amp;lt;!--&lt;br /&gt;
                       --&amp;gt;| 30px &amp;lt;!--&lt;br /&gt;
                       --&amp;gt;| {{#switch: {{{hangar|fgaddon}}}&lt;br /&gt;
                              | fgaddon  = {{LangSwitch&lt;br /&gt;
                                             | de = Lade das Flugzeug-Paket des {{{name|}}} für die aktuelle stabile Version ({{current release|cr}}) herunter.&lt;br /&gt;
                                             | en = Download the {{{name|}}} aircraft package for the current stable release ({{current release|cr}}).&lt;br /&gt;
                                             | es = Descargar el paquete de avion {{{name|}}} para la versión estable actua ({{current release|cr}}).&lt;br /&gt;
                                             | fr = Téléchargez le paquet de l'avion {{{name|}}} pour la version stable actuelle ({{current release|cr}}).&lt;br /&gt;
                                             | fr = Scarica il pacchetto dell'aeromobile {{{name|}}} per la versione stabile corrente ({{current release|cr}}).&lt;br /&gt;
                                             | th = ดาวน์โหลดเครื่องบิน {{{name|}}} สำหรับรุ่นปัจจุบัน({{current release|cr}})&lt;br /&gt;
                                           }}&lt;br /&gt;
                              | fgdata  = {{LangSwitch&lt;br /&gt;
                                            | de = Das UFO ist bereits im Basispaket enthalten.&lt;br /&gt;
                                            | en = The UFO comes as part of the base package.&lt;br /&gt;
                                            | es = El UFO está incluido en el paquete básico.&lt;br /&gt;
                                            | it = L'UFO è parte del pacchetto di base.&lt;br /&gt;
                                            | th = UFO จะมาพร้อมกับโปรแกรมอยู่แล้ว&lt;br /&gt;
                                           }}&lt;br /&gt;
                              | #default = {{LangSwitch&lt;br /&gt;
                                             | de = de = Lade das Flugzeug-Paket herunter.&lt;br /&gt;
                                             | en = Download the aircraft package.&lt;br /&gt;
                                             | es = Descargar el paquete de avion.&lt;br /&gt;
                                             | fr = Téléchargez le paquet de l'avion.&lt;br /&gt;
                                             | it = Scarica il pacchetto dell'aeromobile.&lt;br /&gt;
                                             | th = ดาวน์โหลดเครื่องบิน&lt;br /&gt;
                                           }}&lt;br /&gt;
                            }} &amp;lt;!--&lt;br /&gt;
                       --&amp;gt;| link={{#if:{{{download|}}}&lt;br /&gt;
                                   | {{{download}}}&lt;br /&gt;
                                   | {{#switch: {{{hangar|}}}&lt;br /&gt;
                                       | aucafly           = {{github zip file|proj=aucafly|repo={{{aircraft|}}}|full=1}}&lt;br /&gt;
                                       | buckaroo          = http://www.buckarooshangar.com/flightgear/models/{{{aircraft|}}}.zip&lt;br /&gt;
                                       | bulldogrs         = {{github zip file|proj=aucafly|repo={{{aircraft|}}}|full=1}}&lt;br /&gt;
                                       | dave              = http://www.daveshangar.org/&lt;br /&gt;
                                       | emilianh          = {{gitlab zip file|user=emilianh|repo={{{aircraft|}}}|tag=latest|full=1}}&lt;br /&gt;
                                       | fgaddon           = http://mirrors.ibiblio.org/flightgear/ftp/Aircraft/{{{aircraft|}}}.zip&lt;br /&gt;
                                       | fgdata            = https://sourceforge.net/projects/flightgear/files/&lt;br /&gt;
                                       | fguk              = http://fguk.eu/index.php/hangar&lt;br /&gt;
                                       | helijah           = {{LangSwitch&lt;br /&gt;
                                                                 | en = http://helijah.free.fr/flightgear/hangaren.htm&lt;br /&gt;
                                                                 | fr = http://helijah.free.fr/flightgear/hangar.htm&lt;br /&gt;
                                                              }}&lt;br /&gt;
                                       | herbyw            = {{github zip file|user=HerbyW|repo={{{aircraft|}}}|full=1}}&lt;br /&gt;
                                       | it0uchpods        = {{github zip file|user=it0uchpods|repo={{{aircraft|}}}|full=1}}&lt;br /&gt;
                                       | lake of constance = http://www.marc-kraus.de&lt;br /&gt;
                                       | paf               = http://equipe-flightgear.forumactif.com/t835-hangar-de-la-p-a-f-paf-team-hangar#14330&lt;br /&gt;
                                     }}&lt;br /&gt;
                                 }}&amp;lt;!--&lt;br /&gt;
                     --&amp;gt;]]&lt;br /&gt;
                    }}&lt;br /&gt;
                }}&lt;br /&gt;
| label31     = {{LangSwitch&lt;br /&gt;
                  | de = Livree&lt;br /&gt;
                  | en = Liveries&lt;br /&gt;
                  | es = Libreas&lt;br /&gt;
                  | fr = Livrée&lt;br /&gt;
                  | it = Livree&lt;br /&gt;
                  | th = ลวดลาย&lt;br /&gt;
                  | zh = 涂装&lt;br /&gt;
                }}&lt;br /&gt;
| data31{{#if:{{{liverydbid|}}}||NULL}}&lt;br /&gt;
              = [[File:Applications-graphics 32x32.png &amp;lt;!--&lt;br /&gt;
               --&amp;gt;| 30px &amp;lt;!--&lt;br /&gt;
               --&amp;gt;| {{LangSwitch&lt;br /&gt;
                      | de = Durchsuchen Sie die FlightGear Livree Datenbank für die {{{name|}}}.&lt;br /&gt;
                      | en = Browse the FlightGear livery database for the {{{name|}}}.&lt;br /&gt;
                      | es = Navegar por la FlightGear base de datos de libreas para {{{name|}}}.&lt;br /&gt;
                      | fr = Parcourez la base de données de livrée de FlightGear pour le {{{name|}}}.&lt;br /&gt;
                      | it = Sfoglia il database livree di FlightGear per il {{{name|}}}.&lt;br /&gt;
                      | th = ดูลายสายการบินสำหรับ {{{name|}}}&lt;br /&gt;
                    }} &amp;lt;!--&lt;br /&gt;
               --&amp;gt;| link=http://liveries.flightgear.org/aircraft.php?id={{{liverydbid|}}}&amp;amp;display=2 &amp;lt;!--&lt;br /&gt;
             --&amp;gt;]]&lt;br /&gt;
| label32     = {{LangSwitch&lt;br /&gt;
                  | de = Forum&lt;br /&gt;
                  | en = Forum&lt;br /&gt;
                  | fr = Forum&lt;br /&gt;
                  | it = Forum&lt;br /&gt;
                  | zh = 论坛&lt;br /&gt;
                }}&lt;br /&gt;
| data32{{#if:{{{forumtid|}}}||NULL}}&lt;br /&gt;
              = [[File:Meeting-attending 32x32.png &amp;lt;!--&lt;br /&gt;
               --&amp;gt;| 30px &amp;lt;!--&lt;br /&gt;
               --&amp;gt;| {{LangSwitch&lt;br /&gt;
                      | de = Das FlightGear Forum-Thread für die {{{name|}}}.&lt;br /&gt;
                      | en = The FlightGear forum thread for the {{{name|}}}.&lt;br /&gt;
                      | es = El FlightGear foro thread para {{{name|}}}.&lt;br /&gt;
                      | fr = Le fil de discussion dans le forum de FlightGear pour le {{{name|}}}.&lt;br /&gt;
                      | it = Il thread di discussione del forum di FlightGear per il {{{name|}}}.&lt;br /&gt;
                      | th = ดูหน้าเว็บบอรด์ FlightGear ของ {{{name|}}}&lt;br /&gt;
                    }} &amp;lt;!--&lt;br /&gt;
               --&amp;gt;| link=https://forum.flightgear.org/viewtopic.php?t={{{forumtid|}}} &amp;lt;!--&lt;br /&gt;
             --&amp;gt;]]&lt;br /&gt;
| label40     = {{LangSwitch&lt;br /&gt;
                  | de = Lizenz&lt;br /&gt;
                  | en = License&lt;br /&gt;
                  | es = Licencia&lt;br /&gt;
                  | fr = Licence&lt;br /&gt;
                  | it = Licenza&lt;br /&gt;
                  | ja = ライセンス&lt;br /&gt;
                  | pl = Licencja&lt;br /&gt;
                  | pt = Licença&lt;br /&gt;
                  | ru = лицензия&lt;br /&gt;
                  | th = ลิขสิทธิ์&lt;br /&gt;
                  | zh = 授权&lt;br /&gt;
                }}&lt;br /&gt;
| data40      = {{#if:{{{licence|{{{license|}}}}}}&lt;br /&gt;
                  | {{license|{{{licence|{{{license}}}}}}}}&lt;br /&gt;
                  | {{#switch: {{{hangar|}}}&lt;br /&gt;
                      | aucafly           = {{license|GPLv3+}}&lt;br /&gt;
                      | bulldogrs         = {{license|GPLv3+}}&lt;br /&gt;
                      | dave              = {{license|CC BY-NC-SA 4.0}}&lt;br /&gt;
                      | fgaddon           = {{license|GPLv2+}}&lt;br /&gt;
                      | herbyw            = {{license|GPLv2+}}&lt;br /&gt;
                      | prestes           = {{license|Unknown}}&lt;br /&gt;
                    }}&lt;br /&gt;
                }}&lt;br /&gt;
| data41      = {{#if:{{{licence|{{{license|}}}}}}&lt;br /&gt;
                  | {{#switch: {{{license|{{{licence|GPLv2+}}}}}}&lt;br /&gt;
                      | GPL | GPL2 | GPLv2 | GPLv2+ =&lt;br /&gt;
                      | #default =&lt;br /&gt;
                        {{non-GPL2&lt;br /&gt;
                          | width = 100%&lt;br /&gt;
                          | product =&lt;br /&gt;
                            {{#switch: {{{craft|aircraft}}}&lt;br /&gt;
                              | aircraft =&lt;br /&gt;
                                {{LangSwitch&lt;br /&gt;
                                  | de = Dieses Flugzeug&lt;br /&gt;
                                  | en = This aircraft&lt;br /&gt;
                                  | es = Este avión&lt;br /&gt;
                                  | fr = Cet aéronef&lt;br /&gt;
                                  | it = Quest'aeromobile&lt;br /&gt;
                                  | th = เครื่องบินนี้&lt;br /&gt;
                                }}&lt;br /&gt;
                              | spacecraft =&lt;br /&gt;
                                {{LangSwitch&lt;br /&gt;
                                  | de = Dieses Raumschiff&lt;br /&gt;
                                  | en = This spacecraft&lt;br /&gt;
                                  | es = Esta nave espacial&lt;br /&gt;
                                  | fr = Cet véhicule spatial&lt;br /&gt;
                                  | it = Questo veicolo spaziale&lt;br /&gt;
                                  | th = ยานอวกาศนี้&lt;br /&gt;
                                }}&lt;br /&gt;
                              | vehicle =&lt;br /&gt;
                                {{LangSwitch&lt;br /&gt;
                                  | de = Dieses Fahrzeug&lt;br /&gt;
                                  | en = This vehicle&lt;br /&gt;
                                  | es = Este vehículo&lt;br /&gt;
                                  | fr = Cet véhicule&lt;br /&gt;
                                  | it = Questo veicolo&lt;br /&gt;
                                  | th = รถยนต์นี้&lt;br /&gt;
                                }}&lt;br /&gt;
                              | seacraft =&lt;br /&gt;
                                {{LangSwitch&lt;br /&gt;
                                  | de = Dieses Wasserfahrzeug&lt;br /&gt;
                                  | en = This seacraft&lt;br /&gt;
                                  | es = Esta moto acuática&lt;br /&gt;
                                  | fr = Cette embarcation&lt;br /&gt;
                                  | it = Quest'imbarcazione&lt;br /&gt;
                                  | th = ยานพาหนะนี้&lt;br /&gt;
                                }}&lt;br /&gt;
                            }}&lt;br /&gt;
                          | meaning =&lt;br /&gt;
                            {{LangSwitch&lt;br /&gt;
                              | de = Teile davon nicht im offiziellen FlightGear-Repositorys wiederverwendet werden dürfen&lt;br /&gt;
                              | en = parts cannot be reused in the official FlightGear repositories&lt;br /&gt;
                              | es = partes no pueden ser reutilizados en los repositorios oficiales de FlightGear&lt;br /&gt;
                              | fr = des parties ne peuvent pas être réutilisées dans les dépôts officiel de FlightGear&lt;br /&gt;
                              | it = delle sue parti non possono essere riutilizzate nei repository ufficiali di FlightGear&lt;br /&gt;
                              | th = ไม่สามารถนำทั้งหมด หรือส่วนใดส่วนหนึ่ง มาใช้ใน FGAddon ได้&lt;br /&gt;
                            }}&lt;br /&gt;
                        }}&lt;br /&gt;
                    }}&lt;br /&gt;
                  | {{#switch: {{{hangar|}}}&lt;br /&gt;
                      | aucafly&lt;br /&gt;
                      | bulldogrs&lt;br /&gt;
                      | prestes&lt;br /&gt;
                      | dave              =&lt;br /&gt;
                        {{non-GPL2&lt;br /&gt;
                          | width = 100%&lt;br /&gt;
                          | product = &lt;br /&gt;
                            {{#switch: {{{craft|aircraft}}}&lt;br /&gt;
                              | aircraft =&lt;br /&gt;
                                {{LangSwitch&lt;br /&gt;
                                  | de = Dieses Flugzeug&lt;br /&gt;
                                  | en = This aircraft&lt;br /&gt;
                                  | es = Este avión&lt;br /&gt;
                                  | fr = Cet aéronef&lt;br /&gt;
                                  | it = Quest'aeromobile&lt;br /&gt;
                                  | th = เครื่องบินนี้&lt;br /&gt;
                                }}&lt;br /&gt;
                              | spacecraft =&lt;br /&gt;
                                {{LangSwitch&lt;br /&gt;
                                  | de = Dieses Raumschiff&lt;br /&gt;
                                  | en = This spacecraft&lt;br /&gt;
                                  | es = Esta nave espacial&lt;br /&gt;
                                  | fr = Cet véhicule spatial&lt;br /&gt;
                                  | it = Questo veicolo spaziale&lt;br /&gt;
                                  | th = ยานอวกาศนี้&lt;br /&gt;
                                }}&lt;br /&gt;
                              | vehicle =&lt;br /&gt;
                                {{LangSwitch&lt;br /&gt;
                                  | de = Dieses Fahrzeug&lt;br /&gt;
                                  | en = This vehicle&lt;br /&gt;
                                  | es = Este vehículo&lt;br /&gt;
                                  | fr = Cet véhicule&lt;br /&gt;
                                  | it = Questo veicolo&lt;br /&gt;
                                  | th = รถยนต์นี้&lt;br /&gt;
                                }}&lt;br /&gt;
                              | seacraft =&lt;br /&gt;
                                {{LangSwitch&lt;br /&gt;
                                  | de = Dieses Wasserfahrzeug&lt;br /&gt;
                                  | en = This seacraft&lt;br /&gt;
                                  | es = Esta moto acuática&lt;br /&gt;
                                  | fr = Cette embarcation&lt;br /&gt;
                                  | it = Quest'imbarcazione&lt;br /&gt;
                                  | th = ยานพาหนะนี้&lt;br /&gt;
                                }}&lt;br /&gt;
                            }}&lt;br /&gt;
                          | meaning = &lt;br /&gt;
                            {{LangSwitch&lt;br /&gt;
                              | de = Teile davon nicht im offiziellen FlightGear-Repositorys wiederverwendet werden dürfen&lt;br /&gt;
                              | en = parts cannot be reused in the official FlightGear repositories&lt;br /&gt;
                              | es = partes no pueden ser reutilizados en los repositorios oficiales de FlightGear&lt;br /&gt;
                              | fr = des parties ne peuvent pas être réutilisées dans les dépôts officiel de FlightGear&lt;br /&gt;
                              | it = delle sue parti non possono essere riutilizzate nei repository ufficiali di FlightGear&lt;br /&gt;
                              | th = ไม่สามารถนำทั้งหมด หรือส่วนใดส่วนหนึ่ง มาใช้ใน FGAddon ได้&lt;br /&gt;
                            }}&lt;br /&gt;
                        }}&lt;br /&gt;
                    }}&lt;br /&gt;
                }}&lt;br /&gt;
| data45      = {{#if: {{{note|}}} | {{note|{{{note}}}|width=100%|padding=0px|margin=0px}} }}&lt;br /&gt;
| float{{#if:{{{float|}}}||NULL}}&lt;br /&gt;
              = {{{float}}} &amp;lt;!-- Undocumented parameter, to be used in examples and testing situations --&amp;gt;&lt;br /&gt;
| data60      = {{#ifeq: {{{navbar|}}}&lt;br /&gt;
                  | 1&lt;br /&gt;
                  | &amp;lt;div style=&amp;quot;text-align: right; width: 300px&amp;quot;&amp;gt;{{navbar|:{{#titleparts: {{PAGENAME}} | | {{{navbarlevel|-1}}}}}/info|mini=1}}&amp;lt;/div&amp;gt;&lt;br /&gt;
                }}&lt;br /&gt;
}}&amp;lt;!--&lt;br /&gt;
--&amp;gt;{{#if: {{{image}}} | | [[Category:Image requested]]}}&amp;lt;!--&lt;br /&gt;
--&amp;gt;{{#switch: {{{hangar|}}}&lt;br /&gt;
     | aucafly           = [[Category:AUCAFLY hangar]]&lt;br /&gt;
     | bermuda           = [[Category:Bermuda Triangle]]&lt;br /&gt;
     | buckaroo          = [[Category:Buckaroo's hangar]]&lt;br /&gt;
     | bulldogrs         = [[Category:Bulldog RS hangar]]&lt;br /&gt;
     | dave              = [[Category:Dave's hangar]]&lt;br /&gt;
     | fgaddon           = [[Category:FGAddon hangar]]&lt;br /&gt;
     | fgdata            = [[Category:FGData hangar]]&lt;br /&gt;
     | fguk              = [[Category:FGUK hangar]]&lt;br /&gt;
     | grtux             = [[Category:GRTux hangar]]&lt;br /&gt;
     | helijah           = [[Category:Helijah hangar]]&lt;br /&gt;
     | herbyw            = [[Category:HerbyW's hangar]]&lt;br /&gt;
     | it0uchpods        = [[Category:it0uchpods hangar]]&lt;br /&gt;
     | lake of constance = [[Category:Lake of Constance hangar]]&lt;br /&gt;
     | paf               = [[Category:PAF hangar]]&lt;br /&gt;
     | prestes           = [[Category:Prestes hangar]]&lt;br /&gt;
     | #default          = [[Category:Unknown hangar]]&lt;br /&gt;
   }}&amp;lt;!--&lt;br /&gt;
--&amp;gt;{{#switch: {{{devel-hangar|}}}&lt;br /&gt;
     | aucafly           = [[Category:AUCAFLY hangar]]&lt;br /&gt;
     | buckaroo          = [[Category:Buckaroo's hangar]]&lt;br /&gt;
     | bulldogrs         = [[Category:Bulldog RS hangar]]&lt;br /&gt;
     | dave              = [[Category:Dave's hangar]]&lt;br /&gt;
     | fgaddon           = [[Category:FGAddon hangar]]&lt;br /&gt;
     | fgdata            = [[Category:FGData hangar]]&lt;br /&gt;
     | fguk              = [[Category:FGUK hangar]]&lt;br /&gt;
     | grtux             = [[Category:GRTux hangar]]&lt;br /&gt;
     | helijah           = [[Category:Helijah hangar]]&lt;br /&gt;
     | herbyw            = [[Category:HerbyW's hangar]]&lt;br /&gt;
     | it0uchpods        = [[Category:it0uchpods hangar]]&lt;br /&gt;
     | lake of constance = [[Category:Lake of Constance hangar]]&lt;br /&gt;
     | paf               = [[Category:PAF hangar]]&lt;br /&gt;
     | prestes           = [[Category:Prestes hangar]]&lt;br /&gt;
   }}&amp;lt;!--&lt;br /&gt;
--&amp;gt;{{#switch: {{{craft|aircraft}}}&lt;br /&gt;
     | aircraft   = [[Category:All aircraft]]&lt;br /&gt;
     | spacecraft = [[Category:All spacecraft]]&lt;br /&gt;
     | vehicle    = [[Category:All vehicles]]&lt;br /&gt;
     | seacraft   = [[Category:All seacraft]]&lt;br /&gt;
   }}&amp;lt;!--&lt;br /&gt;
--&amp;gt;&amp;lt;/includeonly&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{Informative template|1=&lt;br /&gt;
== Goal ==&lt;br /&gt;
This infobox is used to summarize the key points of an aircraft, spacecraft, vehicle, or seacraft.  The focus is on FlightGear – the template is not designed to replicate the content of the corresponding Wikipedia article.  If a graphic is present – either a hangar logo or screenshot – the infobox will be set to a width of 300 px.&lt;br /&gt;
&lt;br /&gt;
== Usage ==&lt;br /&gt;
For instructions on how to use this template in a translation-friendly way, please see the [[#Translations - using subpages]] section below.&lt;br /&gt;
 {{obr}}'''infobox aircraft'''&lt;br /&gt;
 {{!}} ''name''           =&lt;br /&gt;
 {{!}} ''hangar''         =&lt;br /&gt;
 {{!}} ''aircraft''       =&lt;br /&gt;
 {{!}} ''image''          =&lt;br /&gt;
 {{!}} ''alt''            =&lt;br /&gt;
 {{!}} ''image2''         =&lt;br /&gt;
 {{!}} ''alt2''           =&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 {{!}} ''type''           =&lt;br /&gt;
 {{!}} ''config''         =&lt;br /&gt;
 {{!}} ''propulsion''     =&lt;br /&gt;
 {{!}} ''manufacturer''   =&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 {{!}} ''authors''        =&lt;br /&gt;
 {{!}} ''author1''        =&lt;br /&gt;
 ...&lt;br /&gt;
 {{!}} ''author30''       =&lt;br /&gt;
 {{!}} ''devel-team''     =&lt;br /&gt;
 {{!}} ''fdm''            =&lt;br /&gt;
 {{!}} ''fgname''         =&lt;br /&gt;
 {{!}} ''fgname1''        =&lt;br /&gt;
 ...&lt;br /&gt;
 {{!}} ''fgname10''       =&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 {{!}} ''status-fdm''     =&lt;br /&gt;
 {{!}} ''status-systems'' =&lt;br /&gt;
 {{!}} ''status-cockpit'' =&lt;br /&gt;
 {{!}} ''status-model''   =&lt;br /&gt;
 {{!}} ''status''         =&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 {{!}} ''ready''          =&lt;br /&gt;
 {{!}} ''devel-hangar''   =&lt;br /&gt;
 {{!}} ''devel-website''  =&lt;br /&gt;
 {{!}} ''devel-repo''     =&lt;br /&gt;
 {{!}} ''download''       =&lt;br /&gt;
 {{!}} ''liverydbid''     =&lt;br /&gt;
 {{!}} ''forumtid''       =&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 {{!}} ''license''        =&lt;br /&gt;
 {{!}} ''note''           =&lt;br /&gt;
 {{!}} ''craft''          =&lt;br /&gt;
 {{!}} ''navbar''         =&lt;br /&gt;
 {{!}} ''navbarlevel''    =&lt;br /&gt;
 {{cbr}}&lt;br /&gt;
&lt;br /&gt;
All parameters are optional.&lt;br /&gt;
&lt;br /&gt;
=== Basic data ===&lt;br /&gt;
{{caution|For multi-part parameters using &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt; separators, these are limited by the constraints of the [https://www.mediawiki.org/wiki/Help:Extension:ParserFunctions#.23titleparts Mediawiki &amp;lt;code&amp;gt;#titleparts:&amp;lt;/code&amp;gt; function].  Therefore a maximum of 25 elements and 255 characters are allowed.  Links, URLs, or underscores are not supported, so a number of alternative numbered parameters are provided.  If you have other requirements, please discuss this on the [[{{TALKPAGENAME}}|discussion page]].}}&lt;br /&gt;
&lt;br /&gt;
; name:  The name of the aircraft.  This will be displayed at the top of the infobox.&lt;br /&gt;
&lt;br /&gt;
; hangar:  The optional aircraft hangar.  This adds the hangar logo at 300 px or text and a link for the hanger, automatically creates development repository and download links for hangars which support this, and adds a hangar specific category to the article.  This can currently be one of {{param||fgaddon}}, {{param||buckaroo}}, {{param||fguk}}, {{param|helijah}}, {{param|herbyw}}, {{param|lake of constance}}, {{param|paf}}.&lt;br /&gt;
&lt;br /&gt;
; aircraft:  The name of the aircraft in the hangar.  This is only used if the {{param|hangar}} parameter is supplied.  For [[FGAddon]], this corresponds to the aircraft directory in &amp;lt;code&amp;gt;[[$FG_AIRCRAFT]]/Aircraft/&amp;lt;aircraft-dir&amp;gt;&amp;lt;/code&amp;gt;.  For other hangars, this is currently unused.&lt;br /&gt;
&lt;br /&gt;
; image:  Screenshot of the aircraft without the &amp;lt;code&amp;gt;File:&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;Image:&amp;lt;/code&amp;gt; prefix.  The graphic will be set to a width of 300 px.&lt;br /&gt;
&lt;br /&gt;
; alt:  Caption for the screenshot.&lt;br /&gt;
&lt;br /&gt;
; image2:  Additional screenshot without the &amp;lt;code&amp;gt;File:&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;Image:&amp;lt;/code&amp;gt; prefix (''preferably a cockpit screenshot'').  The graphic will be set to a width of 300 px.&lt;br /&gt;
&lt;br /&gt;
; alt2:  Caption for the second screenshot.&lt;br /&gt;
&lt;br /&gt;
; type:  The type of aircraft, spacecraft, vehicle, or seacraft.  Although this can be any text, special parameter values, independent of capitalisation, will be associated with a category.  This will result in the automatic addition of a internal wiki link to the category in the infobox as well as appending the category to the article.  See the [[#Craft types|Craft types]] section below for a table of values.  Multiple values for the parameter can be supplied when each type is separated by &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt;.  For example &amp;lt;code&amp;gt;{{!}} type = Civil utility aircraft/Military utility aircraft&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
; config:  The configuration of the aircraft, spacecraft, vehicle, or seacraft.  Although this can be any text, special parameter values, independent of capitalisation, will be associated with a category.  This will result in the automatic addition of a internal wiki link to the category in the infobox as well as appending the category to the article.  See the [[#Craft configurations|Craft configurations]] section below for a table of values.  Multiple values for the parameter can be supplied when each configuration is separated by &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt;.  For example &amp;lt;code&amp;gt;{{!}} config = Biplane aircraft/Delta-wing aircraft&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
; propulsion:  The aircraft, spacecraft, vehicle, or seacraft propulsion.  Although this can be any text, special parameter values, independent of capitalisation, will be associated with a category.  This will result in the automatic addition of a internal wiki link to the category in the infobox as well as appending the category to the article.  See the [[#Craft propulsion|Craft propulsion]] section below for a table of values.  Multiple values for the parameter can be supplied when each value is separated by &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt;.  For example &amp;lt;code&amp;gt;{{!}} propulsion = Twin-engined aircraft/Propeller aircraft&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
; manufacturer:  The aircraft, spacecraft, vehicle, or seacraft manufacturer.  Although this can be any text, special parameter values, independent of capitalisation, will be associated with a category.  This will result in the automatic addition of a internal wiki link to the category in the infobox as well as appending the category to the article.  See the [[#Craft manufacturer|Craft manufacturer]] section below for a table of values.  Multiple values for the parameter can be supplied when each value is separated by &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt;.  For example &amp;lt;code&amp;gt;{{!}} manufacturer = Boeing/Rockwell&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
; authors:  The list of aircraft authors.  The special slash character &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt; can be used to separate authors, for example: &amp;lt;code&amp;gt;{{!}} fgname = me/you&amp;lt;/code&amp;gt;, resulting in each author being placed on a separate line.  The &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt; character cannot be used within a single author element so instead the &amp;lt;code&amp;gt;,&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;&amp;amp;&amp;lt;/code&amp;gt; separating characters should be used.&lt;br /&gt;
&lt;br /&gt;
; author{1-30}:  Optional aircraft authors to add to the list.  These should be given in order from {{param|author1}} upwards.  This bypasses the [https://www.mediawiki.org/wiki/Help:Extension:ParserFunctions#.23titleparts Mediawiki &amp;lt;code&amp;gt;#titleparts:&amp;lt;/code&amp;gt; function], allowing for the author name to be a link.&lt;br /&gt;
&lt;br /&gt;
; devel-team:  The optional name of the development team.  If this parameter is supplied, then the author list will be packed into a collapsible element that is, by default, not shown but has a &amp;lt;code&amp;gt;[Expand]&amp;lt;/code&amp;gt; link to see the authors.&lt;br /&gt;
&lt;br /&gt;
; fdm:  The [[Flight Dynamics Model]] of the aircraft.  If one of the values of {{param|JSBSim}}, {{param|YASim}}, {{param|UIUC}}, or {{param|LaRCsim}} are supplied, independent of capitalisation, then an automatic link to the corresponding wiki page will be created.  Multiple values for the parameter can be supplied when each type is separated by &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt;, for example &amp;lt;code&amp;gt;{{!}} type = UIUC/YASim/JSBSim/magic carpet&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
; fgname:  The name(s) of the aircraft to use when launching FlightGear from the command line.  If multiple aircraft in different &amp;lt;code&amp;gt;*-set.xml&amp;lt;/code&amp;gt; files are available, each name should be separated by the slash character &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt;.  For example &amp;lt;code&amp;gt;{{!}} fgname = dhc6/dhc6F/dhc6S&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; fgname{1-10}:  An alternative way to specify the fgname, if the [https://www.mediawiki.org/wiki/Help:Extension:ParserFunctions#.23titleparts Mediawiki &amp;lt;code&amp;gt;#titleparts:&amp;lt;/code&amp;gt; function] is problematic.  This is necessary if there are underscores in the name.&lt;br /&gt;
&lt;br /&gt;
; status-fdm:  The [[Aircraft rating system#Flight Dynamics Model .28FDM.29|status of the Flight Dynamics Model]].  For details, please [[#Aircraft status|see below]].&lt;br /&gt;
&lt;br /&gt;
; status-systems:  The [[Aircraft rating system#Systems|status of the systems]]  For details, please [[#Aircraft status|see below]].&lt;br /&gt;
&lt;br /&gt;
; status-cockpit:  The [[Aircraft rating system#Cockpit|status of the cockpit]]  For details, please [[#Aircraft status|see below]].&lt;br /&gt;
&lt;br /&gt;
; status-model:  The [[Aircraft rating system#External Model|status of the external model]]  For details, please [[#Aircraft status|see below]].&lt;br /&gt;
&lt;br /&gt;
; status:  The fall-back status text, if none of the other {{param|status-*}} parameters are set.  This corresponds to the old [[Aircraft rating system]].&lt;br /&gt;
&lt;br /&gt;
; ready:  Add icons to display certain capabilities supported by the aircraft.  Please see the [[#Ready icons]] section below for details.&lt;br /&gt;
&lt;br /&gt;
; devel-hangar:  The hangar where aircraft developments occur.  This is similar to the {{param|hangar}} parameter, and will add the hangar banner to the infobox.  The aim is to point readers to the hangar responsible for the current developments, so as to minimise duplicated developments.&lt;br /&gt;
&lt;br /&gt;
; devel-website:  The URL for the development website.&lt;br /&gt;
&lt;br /&gt;
; devel-repo:  The URL for the development repository.  If the {{param|hangar}} parameter is supplied, the development link may be automatically created.  Note that hardcoded URLs should be avoided where ever possible and the [[:Category:Repository link templates|family of repository link templates]] should be used instead.&lt;br /&gt;
&lt;br /&gt;
; development:  Depreciated.  This has been replaced by the {{param|devel-repo}} parameter.&lt;br /&gt;
&lt;br /&gt;
; download:  The URL for downloading the aircraft.  If the {{param|hangar}} parameter is supplied, the download link may be automatically created.  For repository snapshots, please avoid hardcoded URLs and instead use the [[:Category:Repository link templates|family of repository link templates]].&lt;br /&gt;
&lt;br /&gt;
; liverydbid:  The [[FlightGear livery database|livery database]] ID of the aircraft.&lt;br /&gt;
&lt;br /&gt;
; forumtid:  The [https://forum.flightgear.org FlightGear forum] topic ID for the aircraft.  This is the number after the &amp;lt;code&amp;gt;t=&amp;lt;/code&amp;gt; part of the URL.&lt;br /&gt;
&lt;br /&gt;
; license:  Also {{param|licence}}.  This will add licensing information to the infobox.  Please see the [[#Licensing]] section below for a list of special values.&lt;br /&gt;
&lt;br /&gt;
; note:  A special note to show within a {{tl|note}} message box at the end of the aircraft infobox.&lt;br /&gt;
&lt;br /&gt;
; craft:  The craft type, defaulting to {{param||aircraft}}.  This can be one of {{param||aircraft}}, {{param||spacecraft}}, {{param||vehicle}}, or {{param||seacraft}}.  This will be used to add one of the categories [[:Category:All aircraft]], [[:Category:All spacecraft]], [[:Category:All vehicles]], or [[:Category:All seacraft]] to the page.&lt;br /&gt;
&lt;br /&gt;
; navbar:  If this is set to {{param||1}}, a {{tl|navbar}} element will be added to the very end of infobox.  This is very useful when using [[#Translations - using subpages|subpages]].  It will have the form of &amp;lt;code&amp;gt;{{navbar|{{PAGENAME}}|mini=1}}&amp;lt;/code&amp;gt;.  Note that the navbar will point to pages of the form &amp;lt;code&amp;gt;{{obr}}PAGENAME{{cbr}}/info&amp;lt;/code&amp;gt;, excluding the language code part of the page name.&lt;br /&gt;
&lt;br /&gt;
; navbarlevel:  This is used if the {{param|navbar}} parameter is set.  It allows for &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt; characters in the base PAGENAME.  If a single slash is present, then this should be set to {{param||-2}}.&lt;br /&gt;
&lt;br /&gt;
; float:  A parameter reserved solely for template developers.  This corresponds to the {{tl|Infobox}} {{param|float}} parameter.&lt;br /&gt;
&lt;br /&gt;
{{craft type/doc}}&lt;br /&gt;
&lt;br /&gt;
{{craft configuration/doc}}&lt;br /&gt;
&lt;br /&gt;
{{craft propulsion/doc}}&lt;br /&gt;
&lt;br /&gt;
{{craft manufacturer/doc}}&lt;br /&gt;
&lt;br /&gt;
=== Aircraft status ===&lt;br /&gt;
Instead of a custom {{param|status}} text, you can use the [[aircraft rating system]]. The overall status is auto-calculated and will be displayed. If you use the aircraft rating system, the {{param|status}} parameter will be ignored.&lt;br /&gt;
&lt;br /&gt;
See [[Aircraft rating system]] for instructions on how to rate your aircraft.&lt;br /&gt;
&lt;br /&gt;
=== Ready icons ===&lt;br /&gt;
Several icons are available for highlighting certain capabilities of the aircraft.  Separate them with the slash character &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt;, for example &amp;lt;code&amp;gt;{{!}} ready = airrefuel/bombable&amp;lt;/code&amp;gt;.  The allowed values are:&lt;br /&gt;
&lt;br /&gt;
{{ready/doc table}}&lt;br /&gt;
&lt;br /&gt;
This is implemented using the {{tl|ready}} template.&lt;br /&gt;
&lt;br /&gt;
=== Translations - using subpages ===&lt;br /&gt;
When using this template in an article, the use of subpage organisation is recommended for facilitating translations.&lt;br /&gt;
&lt;br /&gt;
==== Transclusion of the subpage ====&lt;br /&gt;
&lt;br /&gt;
Instead of transcluding this template directly into the article, the subpage &amp;lt;code&amp;gt;{{obr}}{{mediawiki|Help:Magic_words#Page_names|PAGENAME}}{{cbr}}/info&amp;lt;/code&amp;gt; can be created.  Using the example of the [[de Havilland Canada DHC-6 Twin Otter]], to the very start of the article simply add:&lt;br /&gt;
&lt;br /&gt;
 {{obr}}:{{obr}}{{mediawiki|Help:Magic_words#Page_names|PAGENAME}}{{cbr}}/info{{cbr}}&lt;br /&gt;
&lt;br /&gt;
For translations, e.g. [[De/de Havilland Canada DHC-6 Twin Otter]] and [[Fr/de Havilland Canada DHC-6 Twin Otter]], a different syntax is needed to strip out the language prefix from the page name.  The text to copy and paste to the top of the article is:&lt;br /&gt;
&lt;br /&gt;
 {{obr}}:{{obr}}#{{mediawiki|Help:Extension:ParserFunctions##titleparts|titleparts}}:{{obr}}PAGENAME{{cbr}}{{!}}{{!}}2{{cbr}}/info{{cbr}}&lt;br /&gt;
&lt;br /&gt;
==== Subpage structure ====&lt;br /&gt;
&lt;br /&gt;
Then create your &amp;lt;code&amp;gt;{{obr}}PAGENAME{{cbr}}/info&amp;lt;/code&amp;gt; multi-language page with, for the example of [[de Havilland Canada DHC-6 Twin Otter/info]] (also see the [[#de Havilland Canada DHC-6 Twin Otter|DHC-6 example]] below):&lt;br /&gt;
&lt;br /&gt;
 &amp;amp;lt;includeonly&amp;amp;gt;{{obr}}infobox aircraft&lt;br /&gt;
 {{!}} name           = de Havilland Canada DHC-6 Twin Otter&lt;br /&gt;
 {{!}} hangar         = fgaddon&lt;br /&gt;
 {{!}} aircraft       = dhc6&lt;br /&gt;
 {{!}} image          = Dhc6-splash1.jpg&lt;br /&gt;
 {{!}} alt            = {{obr}}LangSwitch&lt;br /&gt;
                      {{!}} de = Die DHC-6 Twin Otter im Flug&lt;br /&gt;
                      {{!}} en = The DHC-6 Twin Otter in flight&lt;br /&gt;
                      {{!}} fr = Le DHC-6 Twin Otter en vol&lt;br /&gt;
                    {{cbr}}&lt;br /&gt;
 {{!}} image2         = Twin Otter - interior shadows.jpg&lt;br /&gt;
 {{!}} alt2           = {{obr}}LangSwitch&lt;br /&gt;
                      {{!}} de = Cockpit des Twin Otter mit Innenbeschattung&lt;br /&gt;
                      {{!}} en = Cockpit of the Twin Otter with interior shading&lt;br /&gt;
                      {{!}} fr = Cockpit du Twin Otter avec un ombrage intérieur&lt;br /&gt;
                    {{cbr}}&lt;br /&gt;
 {{!}} type           = Civil utility aircraft/Military utility aircraft/Seaplanes and flying boat&lt;br /&gt;
 {{!}} config         = High wing aircraft/Fixed gear aircraft/Tricycle landing gear aircraft&lt;br /&gt;
 {{!}} propulsion     = Twin-engine aircraft/Propeller aircraft&lt;br /&gt;
 {{!}} manufacturer   = de Havilland Canada&lt;br /&gt;
 {{!}} authors        = Syd Adams (Initial model)/Christian Thiriot (3D, Textures)/Bo Lan (Nasal, FDM, Systems)/Jonathan Schellhase (3D, Nasal, Systems, Sound, misc)/others (see below)&lt;br /&gt;
 {{!}} devel-team     = {{obr}}LangSwitch&lt;br /&gt;
                      {{!}} de = DHC-6 Twin Otter Entwicklungsteam&lt;br /&gt;
                      {{!}} en = DHC-6 Twin Otter team&lt;br /&gt;
                      {{!}} fr = L'équipe du DHC-6 Twin Otter&lt;br /&gt;
                    {{cbr}}&lt;br /&gt;
 {{!}} fdm            = YASim&lt;br /&gt;
 {{!}} fgname         = dhc6/dhc6F/dhc6S&lt;br /&gt;
 {{!}} status-fdm     = 4&lt;br /&gt;
 {{!}} status-systems = 4&lt;br /&gt;
 {{!}} status-cockpit = 5&lt;br /&gt;
 {{!}} status-model   = 5&lt;br /&gt;
 {{!}} ready          = checklist/tutorials/rembrandt&lt;br /&gt;
 {{!}} liverydbid     = 57&lt;br /&gt;
 {{!}} forumtid       = 21965&lt;br /&gt;
 {{!}} navbar         = 1&lt;br /&gt;
 {{cbr}}&amp;amp;lt;/includeonly&amp;amp;gt;&amp;amp;lt;noinclude&amp;amp;gt;&lt;br /&gt;
 This is the aircraft infobox subpage of the [[[[de Havilland Canada DHC-6 Twin Otter]]]].&lt;br /&gt;
 [[[[:Category:Aircraft infobox documentation]]]]&lt;br /&gt;
 &amp;amp;lt;/noinclude&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;&amp;amp;lt;includeonly&amp;amp;gt;&amp;lt;/code&amp;gt; tags prevent the &amp;lt;code&amp;gt;{{obr}}PAGENAME{{cbr}}/info&amp;lt;/code&amp;gt; pages from being scattered throughout the [[:Category:Controllable craft]] subcategories (by temporarily removing or deleting a character in the initial tag, the infobox can be previewed).  The &amp;lt;code&amp;gt;&amp;amp;lt;noinclude&amp;amp;gt;&amp;lt;/code&amp;gt; tags means that only the &amp;lt;code&amp;gt;{{obr}}PAGENAME{{cbr}}/info&amp;lt;/code&amp;gt; page will be added to the [[:Category:Aircraft infobox documentation]] category.&lt;br /&gt;
&lt;br /&gt;
Note the use of the {{param|navbar}} parameter.  This is allows the &amp;lt;code&amp;gt;{{obr}}PAGENAME{{cbr}}/info&amp;lt;/code&amp;gt; subpage to be easily accessed from the main article.&lt;br /&gt;
&lt;br /&gt;
==== Full translation ====&lt;br /&gt;
&lt;br /&gt;
For a full translation of the aircraft infobox, a number of templates on top of this one need to be translated:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;div class=&amp;quot;plainlinks&amp;quot;&amp;gt;[{{fullurl:Template:{{PAGENAME}}|action=edit}} Edit this template]&amp;lt;div&amp;gt;&lt;br /&gt;
* &amp;lt;div class=&amp;quot;plainlinks&amp;quot;&amp;gt;[{{fullurl:Template:Craft type|action=edit}} Edit Template:Craft_type]&amp;lt;/div&amp;gt;&lt;br /&gt;
* &amp;lt;div class=&amp;quot;plainlinks&amp;quot;&amp;gt;[{{fullurl:Template:Craft configuration|action=edit}} Edit Template:Craft_configuration]&amp;lt;/div&amp;gt;&lt;br /&gt;
* &amp;lt;div class=&amp;quot;plainlinks&amp;quot;&amp;gt;[{{fullurl:Template:Craft propulsion|action=edit}} Edit Template:Craft_propulsion]&amp;lt;/div&amp;gt;&lt;br /&gt;
* &amp;lt;div class=&amp;quot;plainlinks&amp;quot;&amp;gt;[{{fullurl:Template:Craft manufacturer|action=edit}} Edit Template:Craft_manufacturer]&amp;lt;/div&amp;gt;&lt;br /&gt;
* &amp;lt;div class=&amp;quot;plainlinks&amp;quot;&amp;gt;[{{fullurl:Template:hangar banner|action=edit}} Edit Template:Hangar_banner]&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Licensing ===&lt;br /&gt;
&lt;br /&gt;
If the {{param|license}} or {{param|licence}} parameter has one of the special values listed in the following table, a link to the licensing information will be automatically created.&lt;br /&gt;
&lt;br /&gt;
{{license/doc table}}&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
Apart from the examples below, see the [[Special:WhatLinksHere/Template:infobox aircraft|articles using this template]] to learn how to use it.&lt;br /&gt;
&lt;br /&gt;
=== Empty template ===&lt;br /&gt;
&lt;br /&gt;
 {{obr}}Infobox aircraft{{cbr}}&lt;br /&gt;
&lt;br /&gt;
{{infobox aircraft|float=none}}&lt;br /&gt;
&lt;br /&gt;
=== Base package aircraft ===&lt;br /&gt;
&lt;br /&gt;
==== Cessna 172P Skyhawk ====&lt;br /&gt;
This is an example for the [[Cessna 172P]] article, specifically in the [[Cessna 172P/info]] subpage.&lt;br /&gt;
&lt;br /&gt;
 {{obr}}infobox aircraft&lt;br /&gt;
 {{!}} name           = Cessna 172P Skyhawk&lt;br /&gt;
 {{!}} hangar         = fgdata&lt;br /&gt;
 {{!}} image          = c172p-thumbnail.jpg&lt;br /&gt;
 {{!}} type           = Civil aircraft/Civil utility aircraft&lt;br /&gt;
 {{!}} config         = High wing aircraft/Fixed gear aircraft&lt;br /&gt;
 {{!}} propulsion     = Propeller aircraft/Single-engine aircraft&lt;br /&gt;
 {{!}} manufacturer   = Cessna&lt;br /&gt;
 {{!}} authors        = David Megginson/Gilberto Agostinho/Wayne Bragg/Juan Vera del Campo/onox/Fernando Barbosa/Daniel Dubreuil/Jonathan Schellhase/Israel Hernandez/Tuomas Kuosmanen/Anders Gidenstam/Waldo Kitty/algefaen&lt;br /&gt;
 {{!}} devel-team     = C172P development team&lt;br /&gt;
 {{!}} fdm            = JSBSim&lt;br /&gt;
 {{!}} fgname         = c172p&lt;br /&gt;
 {{!}} status-fdm     = 4&lt;br /&gt;
 {{!}} status-systems = 5&lt;br /&gt;
 {{!}} status-cockpit = 5&lt;br /&gt;
 {{!}} status-model   = 4&lt;br /&gt;
 {{!}} ready          = dualcontrol/tutorials/checklist&lt;br /&gt;
 {{!}} devel-repo     = {{obr}}github url{{!}}user=Juanvvc{{!}}repo=c172p-detailed{{cbr}}&lt;br /&gt;
 {{!}} download       = {{obr}}github zip file{{!}}user=Juanvvc{{!}}repo=c172p-detailed{{!}}full=1{{cbr}}&lt;br /&gt;
 {{!}} liverydbid     = 70&lt;br /&gt;
 {{!}} forumtid       = 25157&lt;br /&gt;
 {{!}} note           = This is the default FlightGear aircraft and is distributed as part of the base package.&lt;br /&gt;
 {{!}} navbar         = 1&lt;br /&gt;
 {{cbr}}&lt;br /&gt;
&lt;br /&gt;
{{infobox aircraft&lt;br /&gt;
| name           = Cessna 172P Skyhawk&lt;br /&gt;
| hangar         = fgdata&lt;br /&gt;
| image          = c172p-thumbnail.jpg&lt;br /&gt;
| type           = Civil aircraft/Civil utility aircraft&lt;br /&gt;
| config         = High wing aircraft/Fixed gear aircraft&lt;br /&gt;
| propulsion     = Propeller aircraft/Single-engine aircraft&lt;br /&gt;
| manufacturer   = Cessna&lt;br /&gt;
| authors        = David Megginson/Gilberto Agostinho/Wayne Bragg/Juan Vera del Campo/onox/Fernando Barbosa/Daniel Dubreuil/Jonathan Schellhase/Israel Hernandez/Tuomas Kuosmanen/Anders Gidenstam/Waldo Kitty/algefaen&lt;br /&gt;
| devel-team     = C172P development team&lt;br /&gt;
| fdm            = JSBSim&lt;br /&gt;
| fgname         = c172p&lt;br /&gt;
| status-fdm     = 4&lt;br /&gt;
| status-systems = 5&lt;br /&gt;
| status-cockpit = 5&lt;br /&gt;
| status-model   = 4&lt;br /&gt;
| ready          = dualcontrol/tutorials/checklist&lt;br /&gt;
| devel-repo     = {{github url|user=Juanvvc|repo=c172p-detailed}}&lt;br /&gt;
| download       = {{github zip file|user=Juanvvc|repo=c172p-detailed|full=1}}&lt;br /&gt;
| liverydbid     = 70&lt;br /&gt;
| forumtid       = 25157&lt;br /&gt;
| note           = This is the default FlightGear aircraft and is distributed as part of the base package.&lt;br /&gt;
| navbar         = 1&lt;br /&gt;
| float          = none&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Official FGAddon hangar ===&lt;br /&gt;
&lt;br /&gt;
==== Space Shuttle ====&lt;br /&gt;
This is an example for the [[Space Shuttle]] article, specifically in the [[Space Shuttle/info]] subpage.&lt;br /&gt;
&lt;br /&gt;
 {{obr}}infobox aircraft&lt;br /&gt;
 {{!}} name           = Space Shuttle&lt;br /&gt;
 {{!}} hangar         = fgaddon&lt;br /&gt;
 {{!}} aircraft       = SpaceShuttle&lt;br /&gt;
 {{!}} image          = Shuttle FG01.jpg&lt;br /&gt;
 {{!}} alt            = Space Shuttle &amp;lt;nowiki&amp;gt;''Atlantis''&amp;lt;/nowiki&amp;gt; in orbit&lt;br /&gt;
 {{!}} image2         = Shuttle_Cockpit.jpg&lt;br /&gt;
 {{!}} alt2           = Space Shuttle cockpit (April 2015)&lt;br /&gt;
 {{!}} type           = Spaceplane/Glider aircraft/Hypersonic aircraft&lt;br /&gt;
 {{!}} config         = Delta-wing aircraft&lt;br /&gt;
 {{!}} authors        = Thorsten Renk (flight dynamics)/Richard Harrison (cockpit and avionics)/Chris Kuhn (cockpit)/NASA/japreja (3D)/HerbyW (3D)&lt;br /&gt;
 {{!}} devel-team     = Shuttle development team&lt;br /&gt;
 {{!}} fdm            = JSBSim&lt;br /&gt;
 {{!}} fgname         = SpaceShuttle/SpaceShuttle-orbit/SpaceShuttle-launch/SpaceShuttle-entry/SpaceShuttle-approach/SpaceShuttle-TAEM&lt;br /&gt;
 {{!}} status-fdm     = 4&lt;br /&gt;
 {{!}} status-systems = 4&lt;br /&gt;
 {{!}} status-cockpit = 2&lt;br /&gt;
 {{!}} status-model   = 3&lt;br /&gt;
 {{!}} devel-website  = https://sourceforge.net/projects/fgspaceshuttledev/&lt;br /&gt;
 {{!}} devel-repo     = {{obr}}[[Template:sourceforge url|sourceforge url]]{{!}}proj=fgspaceshuttledev{{!}}repo=code{{!}}branch=development{{cbr}}&lt;br /&gt;
 {{!}} forumtid       = 25747&lt;br /&gt;
 {{!}} navbar         = 1&lt;br /&gt;
 {{cbr}}&lt;br /&gt;
&lt;br /&gt;
{{infobox aircraft&lt;br /&gt;
| name           = Space Shuttle&lt;br /&gt;
| hangar         = fgaddon&lt;br /&gt;
| aircraft       = SpaceShuttle&lt;br /&gt;
| image          = Shuttle FG01.jpg&lt;br /&gt;
| alt            = Space Shuttle ''Atlantis'' in orbit&lt;br /&gt;
| image2         = Shuttle_Cockpit.jpg&lt;br /&gt;
| alt2           = Space Shuttle cockpit (April 2015)&lt;br /&gt;
| type           = Spaceplane/Glider aircraft/Hypersonic aircraft&lt;br /&gt;
| config         = Delta-wing aircraft&lt;br /&gt;
| authors        = Thorsten Renk (flight dynamics)/Richard Harrison (cockpit and avionics)/Chris Kuhn (cockpit)/NASA/japreja (3D)/HerbyW (3D)&lt;br /&gt;
| devel-team     = Shuttle development team&lt;br /&gt;
| fdm            = JSBSim&lt;br /&gt;
| fgname         = SpaceShuttle/SpaceShuttle-orbit/SpaceShuttle-launch/SpaceShuttle-entry/SpaceShuttle-approach/SpaceShuttle-TAEM&lt;br /&gt;
| status-fdm     = 4&lt;br /&gt;
| status-systems = 4&lt;br /&gt;
| status-cockpit = 2&lt;br /&gt;
| status-model   = 3&lt;br /&gt;
| devel-website  = https://sourceforge.net/projects/fgspaceshuttledev/&lt;br /&gt;
| devel-repo     = {{sourceforge url|proj=fgspaceshuttledev|repo=code|branch=development}}&lt;br /&gt;
| forumtid       = 25747&lt;br /&gt;
| navbar         = 1&lt;br /&gt;
| float          = none&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== de Havilland Canada DHC-6 Twin Otter ====&lt;br /&gt;
This is an example for the [[de Havilland Canada DHC-6 Twin Otter]] article, specifically in the [[de Havilland Canada DHC-6 Twin Otter/info]] subpage.&lt;br /&gt;
&lt;br /&gt;
 {{obr}}infobox aircraft&lt;br /&gt;
 {{!}} name           = de Havilland Canada DHC-6 Twin Otter&lt;br /&gt;
 {{!}} hangar         = fgaddon&lt;br /&gt;
 {{!}} aircraft       = dhc6&lt;br /&gt;
 {{!}} image          = Dhc6-splash1.jpg&lt;br /&gt;
 {{!}} alt            = {{obr}}LangSwitch&lt;br /&gt;
                      {{!}} de = Die DHC-6 Twin Otter im Flug&lt;br /&gt;
                      {{!}} en = The DHC-6 Twin Otter in flight&lt;br /&gt;
                      {{!}} fr = Le DHC-6 Twin Otter en vol&lt;br /&gt;
                    {{cbr}}&lt;br /&gt;
 {{!}} image2         = Twin Otter - interior shadows.jpg&lt;br /&gt;
 {{!}} alt2           = {{obr}}LangSwitch&lt;br /&gt;
                      {{!}} de = Cockpit des Twin Otter mit Innenbeschattung&lt;br /&gt;
                      {{!}} en = Cockpit of the Twin Otter with interior shading&lt;br /&gt;
                      {{!}} fr = Cockpit du Twin Otter avec un ombrage intérieur&lt;br /&gt;
                    {{cbr}}&lt;br /&gt;
 {{!}} type           = Civil utility aircraft/Military utility aircraft/Seaplanes and flying boat&lt;br /&gt;
 {{!}} config         = High wing aircraft/Monoplane aircraft/Fixed gear aircraft/Tricycle landing gear aircraft&lt;br /&gt;
 {{!}} propulsion     = Twin-engine aircraft/Propeller aircraft&lt;br /&gt;
 {{!}} manufacturer   = de Havilland Canada&lt;br /&gt;
 {{!}} authors        = Syd Adams (Initial model)/Christian Thiriot (3D, Textures)/Bo Lan (Nasal, FDM, Systems)/Jonathan Schellhase (3D, Nasal, Systems, Sound, misc)/others (see below)&lt;br /&gt;
 {{!}} devel-team     = {{obr}}LangSwitch&lt;br /&gt;
                      {{!}} de = DHC-6 Twin Otter Entwicklungsteam&lt;br /&gt;
                      {{!}} en = DHC-6 Twin Otter team&lt;br /&gt;
                      {{!}} fr = L'équipe du DHC-6 Twin Otter&lt;br /&gt;
                    {{cbr}}&lt;br /&gt;
 {{!}} fdm            = YASim&lt;br /&gt;
 {{!}} fgname         = dhc6/dhc6F/dhc6S&lt;br /&gt;
 {{!}} status-fdm     = 4&lt;br /&gt;
 {{!}} status-systems = 4&lt;br /&gt;
 {{!}} status-cockpit = 5&lt;br /&gt;
 {{!}} status-model   = 5&lt;br /&gt;
 {{!}} ready          = checklist/tutorials/rembrandt&lt;br /&gt;
 {{!}} liverydbid     = 57&lt;br /&gt;
 {{!}} forumtid       = 21965&lt;br /&gt;
 {{!}} navbar         = 1&lt;br /&gt;
 {{cbr}}&lt;br /&gt;
&lt;br /&gt;
{{infobox aircraft&lt;br /&gt;
| name           = de Havilland Canada DHC-6 Twin Otter&lt;br /&gt;
| hangar         = fgaddon&lt;br /&gt;
| aircraft       = dhc6&lt;br /&gt;
| image          = Dhc6-splash1.jpg&lt;br /&gt;
| alt            = {{LangSwitch&lt;br /&gt;
                     | de = Die DHC-6 Twin Otter im Flug&lt;br /&gt;
                     | en = The DHC-6 Twin Otter in flight&lt;br /&gt;
                     | fr = Le DHC-6 Twin Otter en vol&lt;br /&gt;
                   }}&lt;br /&gt;
| image2         = Twin Otter - interior shadows.jpg&lt;br /&gt;
| alt2           = {{LangSwitch&lt;br /&gt;
                     | de = Cockpit des Twin Otter mit Innenbeschattung&lt;br /&gt;
                     | en = Cockpit of the Twin Otter with interior shading&lt;br /&gt;
                     | fr = Cockpit du Twin Otter avec un ombrage intérieur&lt;br /&gt;
                   }}&lt;br /&gt;
| type           = Civil utility aircraft/Military utility aircraft/Seaplanes and flying boat&lt;br /&gt;
| config         = High wing aircraft/Monoplane aircraft/Fixed gear aircraft/Tricycle landing gear aircraft&lt;br /&gt;
| propulsion     = Twin-engine aircraft/Propeller aircraft&lt;br /&gt;
| manufacturer   = de Havilland Canada&lt;br /&gt;
| authors        = Syd Adams (Initial model)/Christian Thiriot (3D, Textures)/Bo Lan (Nasal, FDM, Systems)/Jonathan Schellhase (3D, Nasal, Systems, Sound, misc)/others (see below)&lt;br /&gt;
| devel-team     = {{LangSwitch&lt;br /&gt;
                     | de = DHC-6 Twin Otter Entwicklungsteam&lt;br /&gt;
                     | en = DHC-6 Twin Otter team&lt;br /&gt;
                     | fr = L'équipe du DHC-6 Twin Otter&lt;br /&gt;
                   }}&lt;br /&gt;
| fdm            = YASim&lt;br /&gt;
| fgname         = dhc6/dhc6F/dhc6S&lt;br /&gt;
| status-fdm     = 4&lt;br /&gt;
| status-systems = 4&lt;br /&gt;
| status-cockpit = 5&lt;br /&gt;
| status-model   = 5&lt;br /&gt;
| ready          = checklist/tutorials/rembrandt&lt;br /&gt;
| liverydbid     = 57&lt;br /&gt;
| forumtid       = 21965&lt;br /&gt;
| navbar         = 1&lt;br /&gt;
| float          = none&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== Piper Seneca II ====&lt;br /&gt;
This is an example for the [[Piper PA34-200T Seneca II]] article, specifically in the [[Piper PA34-200T Seneca II/info]] subpage.&lt;br /&gt;
&lt;br /&gt;
 {{obr}}infobox aircraft&lt;br /&gt;
 {{!}} name           = Piper PA34-200T Seneca II&lt;br /&gt;
 {{!}} hangar         = fgaddon&lt;br /&gt;
 {{!}} aircraft       = SenecaII&lt;br /&gt;
 {{!}} image          = Piper_SenecaII.jpg&lt;br /&gt;
 {{!}} type           = Civil aircraft/Civil utility aircraft&lt;br /&gt;
 {{!}} propulsion     = Twin-engine aircraft&lt;br /&gt;
 {{!}} manufacturer   = Piper&lt;br /&gt;
 {{!}} authors        = Torsten Dreyer&lt;br /&gt;
 {{!}} fdm            = JSBSim&lt;br /&gt;
 {{!}} fgname         = SenecaII&lt;br /&gt;
 {{!}} status-fdm     = 5&lt;br /&gt;
 {{!}} status-systems = 5&lt;br /&gt;
 {{!}} status-cockpit = 4&lt;br /&gt;
 {{!}} status-model   = 3&lt;br /&gt;
 {{!}} ready          = tutorials&lt;br /&gt;
 {{!}} navbar         = 1&lt;br /&gt;
 {{cbr}}&lt;br /&gt;
&lt;br /&gt;
{{infobox aircraft&lt;br /&gt;
| name           = Piper PA34-200T Seneca II&lt;br /&gt;
| hangar         = fgaddon&lt;br /&gt;
| aircraft       = SenecaII&lt;br /&gt;
| image          = Piper_SenecaII.jpg&lt;br /&gt;
| type           = Civil aircraft/Civil utility aircraft&lt;br /&gt;
| propulsion     = Twin-engine aircraft&lt;br /&gt;
| manufacturer   = Piper&lt;br /&gt;
| authors        = Torsten Dreyer&lt;br /&gt;
| fdm            = JSBSim&lt;br /&gt;
| fgname         = SenecaII&lt;br /&gt;
| status-fdm     = 5&lt;br /&gt;
| status-systems = 5&lt;br /&gt;
| status-cockpit = 4&lt;br /&gt;
| status-model   = 3&lt;br /&gt;
| ready          = tutorials&lt;br /&gt;
| navbar         = 1&lt;br /&gt;
| float          = none&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== Follow me ====&lt;br /&gt;
This is an example for the [[Follow me]] article, specifically in the [[Follow me/info]] subpage.&lt;br /&gt;
&lt;br /&gt;
 {{obr}}infobox aircraft&lt;br /&gt;
 {{!}} name           = Follow me&lt;br /&gt;
 {{!}} hangar         = fgaddon&lt;br /&gt;
 {{!}} aircraft       = followme&lt;br /&gt;
 {{!}} image          = Follow_me.jpg&lt;br /&gt;
 {{!}} type           = Automobile/Utility vehicle&lt;br /&gt;
 {{!}} authors        = Gijs de Rooy&lt;br /&gt;
 {{!}} fdm            = JSBSim&lt;br /&gt;
 {{!}} fgname         = followme&lt;br /&gt;
 {{!}} status-fdm     = 4&lt;br /&gt;
 {{!}} status-systems = 2&lt;br /&gt;
 {{!}} status-cockpit = 3&lt;br /&gt;
 {{!}} status-model   = 4&lt;br /&gt;
 {{!}} forumtid       = 858&lt;br /&gt;
 {{!}} craft          = vehicle&lt;br /&gt;
 {{!}} navbar         = 1&lt;br /&gt;
 {{cbr}}&lt;br /&gt;
&lt;br /&gt;
{{infobox aircraft&lt;br /&gt;
| name           = Follow me&lt;br /&gt;
| hangar         = fgaddon&lt;br /&gt;
| aircraft       = followme&lt;br /&gt;
| image          = Follow_me.jpg&lt;br /&gt;
| type           = Automobile/Utility vehicle&lt;br /&gt;
| authors        = Gijs de Rooy&lt;br /&gt;
| fdm            = JSBSim&lt;br /&gt;
| fgname         = followme&lt;br /&gt;
| status-fdm     = 4&lt;br /&gt;
| status-systems = 2&lt;br /&gt;
| status-cockpit = 3&lt;br /&gt;
| status-model   = 4&lt;br /&gt;
| craft          = vehicle&lt;br /&gt;
| forumtid       = 858&lt;br /&gt;
| navbar         = 1&lt;br /&gt;
| float          = none&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== Wright Flyer ====&lt;br /&gt;
This is an example for the [[Wright Flyer]] article, specifically in the [[Wright Flyer/info]] subpage.&lt;br /&gt;
&lt;br /&gt;
 {{obr}}infobox aircraft&lt;br /&gt;
 {{!}} name           = Wright Flyer&lt;br /&gt;
 {{!}} hangar         = fgaddon&lt;br /&gt;
 {{!}} aircraft       = wrightFlyer1903&lt;br /&gt;
 {{!}} image          = 1903 Wright Flyer.jpg&lt;br /&gt;
 {{!}} alt            = The ''Wright Flyer'' on the ground.&lt;br /&gt;
 {{!}} type           = First airplane/Experimental aircraft&lt;br /&gt;
 {{!}} config         = Biplane aircraft/Canard aircraft&lt;br /&gt;
 {{!}} propulsion     = Propeller aircraft&lt;br /&gt;
 {{!}} manufacturer   = Wright brothers&lt;br /&gt;
 {{!}} authors        = Jim Wilson (3D model)&lt;br /&gt;
 {{!}} author1        = Prof. &amp;lt;nowiki&amp;gt;&amp;lt;span class=&amp;quot;plainlinks&amp;quot;&amp;gt;[http://www.ae.illinois.edu/directory/profile/m-selig Michael Selig]&amp;lt;/span&amp;gt;&amp;lt;/nowiki&amp;gt; (UIUC FDM)&lt;br /&gt;
 {{!}} author2        = Erik Hofman (JSBSim FDM)&lt;br /&gt;
 {{!}} fdm            = UIUC/JSBSim&lt;br /&gt;
 {{!}} fgname         = wrightFlyer1903/wrightFlyer1903-jsbsim&lt;br /&gt;
 {{!}} status         = Production&lt;br /&gt;
 {{!}} navbar         = 1&lt;br /&gt;
 {{cbr}}&lt;br /&gt;
&lt;br /&gt;
{{infobox aircraft&lt;br /&gt;
| name           = Wright Flyer&lt;br /&gt;
| hangar         = fgaddon&lt;br /&gt;
| aircraft       = wrightFlyer1903&lt;br /&gt;
| image          = 1903 Wright Flyer.jpg&lt;br /&gt;
| alt            = The ''Wright Flyer'' on the ground.&lt;br /&gt;
| type           = First airplane/Experimental aircraft&lt;br /&gt;
| config         = Biplane aircraft/Canard aircraft&lt;br /&gt;
| propulsion     = Propeller aircraft&lt;br /&gt;
| manufacturer   = Wright brothers&lt;br /&gt;
| authors        = Jim Wilson (3D model)&lt;br /&gt;
| author1        = Prof. &amp;lt;span class=&amp;quot;plainlinks&amp;quot;&amp;gt;[http://www.ae.illinois.edu/directory/profile/m-selig Michael Selig]&amp;lt;/span&amp;gt; (UIUC FDM)&lt;br /&gt;
| author2        = Erik Hofman (JSBSim FDM)&lt;br /&gt;
| fdm            = UIUC/JSBSim&lt;br /&gt;
| fgname         = wrightFlyer1903/wrightFlyer1903-jsbsim&lt;br /&gt;
| status         = Production&lt;br /&gt;
| navbar         = 1&lt;br /&gt;
| float          = none&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== Farman IV ====&lt;br /&gt;
This is an example for the [[Farman IV]] article, specifically in the [[Farman IV/info]] subpage.&lt;br /&gt;
 {{obr}}infobox aircraft&lt;br /&gt;
 {{!}} name           = Farman IV&lt;br /&gt;
 {{!}} hangar         = fgaddon&lt;br /&gt;
 {{!}} aircraft       = Farman-IV&lt;br /&gt;
 {{!}} image          = Farman-IV.jpg&lt;br /&gt;
 {{!}} type           = Historical aircraft/Military aircraft&lt;br /&gt;
 {{!}} config         = Biplane aircraft &lt;br /&gt;
 {{!}} propulsion     = Propeller aircraft/Twin-engine piston aircraft&lt;br /&gt;
 {{!}} manufacturer   = Farman&lt;br /&gt;
 {{!}} authors        = Emmanuel Baranger (3D, FDM)&lt;br /&gt;
 {{!}} fdm            = YASim&lt;br /&gt;
 {{!}} fgname         = farman-IV&lt;br /&gt;
 {{!}} status-fdm     = 2&lt;br /&gt;
 {{!}} status-systems = 1&lt;br /&gt;
 {{!}} status-cockpit = 1&lt;br /&gt;
 {{!}} status-model   = 4&lt;br /&gt;
 {{!}} devel-hangar   = helijah&lt;br /&gt;
 {{!}} navbar         = 1&lt;br /&gt;
 {{cbr}}&lt;br /&gt;
&lt;br /&gt;
{{infobox aircraft&lt;br /&gt;
| name           = Farman IV&lt;br /&gt;
| hangar         = fgaddon&lt;br /&gt;
| aircraft       = Farman-IV&lt;br /&gt;
| image          = Farman-IV.jpg&lt;br /&gt;
| type           = Historical aircraft/Military aircraft&lt;br /&gt;
| config         = Biplane aircraft &lt;br /&gt;
| propulsion     = Propeller aircraft/Twin-engine piston aircraft&lt;br /&gt;
| manufacturer   = Farman&lt;br /&gt;
| authors        = Emmanuel Baranger (3D, FDM)&lt;br /&gt;
| fdm            = YASim&lt;br /&gt;
| fgname         = farman-IV&lt;br /&gt;
| status-fdm     = 2&lt;br /&gt;
| status-systems = 1&lt;br /&gt;
| status-cockpit = 1&lt;br /&gt;
| status-model   = 4&lt;br /&gt;
| devel-hangar   = helijah&lt;br /&gt;
| navbar         = 1&lt;br /&gt;
| float          = none&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== Boeing-Sikorsky RAH-66 Comanche ====&lt;br /&gt;
This is an example for the [[Boeing-Sikorsky RAH-66 Comanche]] article, specifically in the [[Boeing-Sikorsky RAH-66 Comanche/info]] subpage.&lt;br /&gt;
&lt;br /&gt;
 {{obr}}infobox aircraft&lt;br /&gt;
 {{!}} name           = Boeing-Sikorsky RAH-66 Comanche&lt;br /&gt;
 {{!}} hangar         = fgaddon&lt;br /&gt;
 {{!}} aircraft       = rah-66&lt;br /&gt;
 {{!}} image          = RAH-66 splash.png&lt;br /&gt;
 {{!}} image2         = rah-66-cockpit.png&lt;br /&gt;
 {{!}} type           = Helicopter/Military helicopter/Military reconnaissance aircraft/Attack aircraft &lt;br /&gt;
 {{!}} manufacturer   = Boeing/Sikorsky&lt;br /&gt;
 {{!}} author1        = {{obr}}[[Template:usr|usr]]{{!}}pjedvaj{{!}}Petar Jedvaj{{cbr}}&lt;br /&gt;
 {{!}} author2        = Edin Hozic&lt;br /&gt;
 {{!}} author3        = Stephen Madeira&lt;br /&gt;
 {{!}} author4        = Gary Brown&lt;br /&gt;
 {{!}} fdm            = YASim &lt;br /&gt;
 {{!}} fgname         = rah-66&lt;br /&gt;
 {{!}} status-fdm     = 4&lt;br /&gt;
 {{!}} status-systems = 2&lt;br /&gt;
 {{!}} status-cockpit = 3&lt;br /&gt;
 {{!}} status-model   = 5&lt;br /&gt;
 {{!}} forumtid       = 14908&lt;br /&gt;
 {{!}} navbar         = 1&lt;br /&gt;
 {{cbr}}&lt;br /&gt;
&lt;br /&gt;
{{infobox aircraft&lt;br /&gt;
| name           = Boeing-Sikorsky RAH-66 Comanche&lt;br /&gt;
| hangar         = fgaddon&lt;br /&gt;
| aircraft       = rah-66&lt;br /&gt;
| image          = RAH-66 splash.png&lt;br /&gt;
| image2         = rah-66-cockpit.png&lt;br /&gt;
| type           = Helicopter/Military helicopter/Military reconnaissance aircraft/Attack aircraft &lt;br /&gt;
| manufacturer   = Boeing/Sikorsky&lt;br /&gt;
| author1        = {{usr|pjedvaj|Petar Jedvaj}}&lt;br /&gt;
| author2        = Edin Hozic&lt;br /&gt;
| author3        = Stephen Madeira&lt;br /&gt;
| author4        = Gary Brown&lt;br /&gt;
| fdm            = YASim &lt;br /&gt;
| fgname         = rah-66&lt;br /&gt;
| status-fdm     = 4&lt;br /&gt;
| status-systems = 2&lt;br /&gt;
| status-cockpit = 3&lt;br /&gt;
| status-model   = 5&lt;br /&gt;
| forumtid       = 14908&lt;br /&gt;
| navbar         = 1&lt;br /&gt;
| float          = none&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Aucafly hangar ===&lt;br /&gt;
&lt;br /&gt;
==== Aucafly T1 ====&lt;br /&gt;
This is an example for the [[Aucafly T1]] article.&lt;br /&gt;
&lt;br /&gt;
 {{obr}}infobox aircraft&lt;br /&gt;
 {{!}} name           = Aucafly T1&lt;br /&gt;
 {{!}} hangar         = aucafly&lt;br /&gt;
 {{!}} aircraft       = AUCAFLYT1&lt;br /&gt;
 {{!}} image          = Aucafly T1.png&lt;br /&gt;
 {{!}} alt            = Aucafly T1 leaving San Francisco International Airport&lt;br /&gt;
 {{!}} type           = Civil aircraft/Fictional aircraft&lt;br /&gt;
 {{!}} propulsion     = Propeller aircraft&lt;br /&gt;
 {{!}} manufacturer   = Aucafly&lt;br /&gt;
 {{!}} authors        = Ausdkunst/D-Echo (FDM)&lt;br /&gt;
 {{!}} fdm            = YASim&lt;br /&gt;
 {{!}} fgname         = aucaflyt1&lt;br /&gt;
 {{!}} status-fdm     = 0&lt;br /&gt;
 {{!}} status-systems = 2&lt;br /&gt;
 {{!}} status-cockpit = 2&lt;br /&gt;
 {{!}} status-model   = 2&lt;br /&gt;
 {{!}} devel-website  = https://aucafly.wordpress.com/2016/06/07/t1-world-premiere/&lt;br /&gt;
 {{!}} craft          = vehicle&lt;br /&gt;
 {{cbr}}&lt;br /&gt;
&lt;br /&gt;
{{infobox aircraft&lt;br /&gt;
| name           = Aucafly T1&lt;br /&gt;
| hangar         = aucafly&lt;br /&gt;
| aircraft       = AUCAFLYT1&lt;br /&gt;
| image          = Aucafly T1.png&lt;br /&gt;
| alt            = Aucafly T1 leaving San Francisco International Airport&lt;br /&gt;
| type           = Civil aircraft/Fictional aircraft&lt;br /&gt;
| propulsion     = Propeller aircraft&lt;br /&gt;
| manufacturer   = Aucafly&lt;br /&gt;
| authors        = Ausdkunst/D-Echo (FDM)&lt;br /&gt;
| fdm            = YASim&lt;br /&gt;
| fgname         = aucaflyt1&lt;br /&gt;
| status-fdm     = 0&lt;br /&gt;
| status-systems = 2&lt;br /&gt;
| status-cockpit = 2&lt;br /&gt;
| status-model   = 2&lt;br /&gt;
| devel-website  = https://aucafly.wordpress.com/2016/06/07/t1-world-premiere/&lt;br /&gt;
| craft          = vehicle&lt;br /&gt;
| float          = none&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Buckaroo's hangar ===&lt;br /&gt;
&lt;br /&gt;
==== Velocity XL RG ====&lt;br /&gt;
This is an example for the [[Velocity XL RG]] article, specifically in the [[Velocity XL RG/info]] subpage.&lt;br /&gt;
&lt;br /&gt;
 {{obr}}infobox aircraft&lt;br /&gt;
 {{!}} name           = Velocity XL RG&lt;br /&gt;
 {{!}} hangar         = buckaroo&lt;br /&gt;
 {{!}} aircraft       = Velocity_XL_RG&lt;br /&gt;
 {{!}} image          = Velocity-XL-RG.jpg&lt;br /&gt;
 {{!}} alt            = Velocity XL RG in flight&lt;br /&gt;
 {{!}} image2         = Velocity-XL-RG cabin 01.jpg&lt;br /&gt;
 {{!}} alt2           = Velocity XL RG cabin&lt;br /&gt;
 {{!}} type           = Civil aircraft/Civil utility aircraft&lt;br /&gt;
 {{!}} config         = Canard aircraft/Pusher aircraft&lt;br /&gt;
 {{!}} propulsion     = Propeller aircraft/Single-engine aircraft&lt;br /&gt;
 {{!}} manufacturer   = Velocity&lt;br /&gt;
 {{!}} authors        = Gary Neely&lt;br /&gt;
 {{!}} fdm            = YASim&lt;br /&gt;
 {{!}} fgname         = Velocity-XL-RG&lt;br /&gt;
 {{!}} navbar         = 1&lt;br /&gt;
 {{cbr}}&lt;br /&gt;
&lt;br /&gt;
{{infobox aircraft&lt;br /&gt;
| name           = Velocity XL RG&lt;br /&gt;
| hangar         = buckaroo&lt;br /&gt;
| aircraft       = Velocity_XL_RG&lt;br /&gt;
| image          = Velocity-XL-RG.jpg&lt;br /&gt;
| alt            = Velocity XL RG in flight&lt;br /&gt;
| image2         = Velocity-XL-RG cabin 01.jpg&lt;br /&gt;
| alt2           = Velocity XL RG cabin&lt;br /&gt;
| type           = Civil aircraft/Civil utility aircraft&lt;br /&gt;
| config         = Canard aircraft/Pusher aircraft&lt;br /&gt;
| propulsion     = Propeller aircraft/Single-engine aircraft&lt;br /&gt;
| manufacturer   = Velocity&lt;br /&gt;
| authors        = Gary Neely&lt;br /&gt;
| fdm            = YASim&lt;br /&gt;
| fgname         = Velocity-XL-RG&lt;br /&gt;
| navbar         = 1&lt;br /&gt;
| float          = none&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Dave's hangar ===&lt;br /&gt;
&lt;br /&gt;
==== McDonnell F-4 Phantom II ====&lt;br /&gt;
This is an example for the [[McDonnell F-4 Phantom II]] article, specifically in the [[McDonnell F-4 Phantom II/info]] subpage.&lt;br /&gt;
&lt;br /&gt;
 {{obr}}infobox aircraft&lt;br /&gt;
 {{!}} name           = McDonnell Douglas F-4 Phantom II&lt;br /&gt;
 {{!}} hangar         = dave&lt;br /&gt;
 {{!}} image          = F4N.JPG&lt;br /&gt;
 {{!}} type           = Military aircraft/Interceptor aircraft/Fighter aircraft/Bomber aircraft&lt;br /&gt;
 {{!}} manufacturer   = McDonnell/McDonnell Douglas&lt;br /&gt;
 {{!}} authors        = Dave Culp&lt;br /&gt;
 {{!}} fdm            = JSBSim&lt;br /&gt;
 {{!}} fgname         = F-4N&lt;br /&gt;
 {{!}} download       = http://www.daveshangar.org/aircraft/F-4N.tar.gz&lt;br /&gt;
 {{!}} navbar         = 1&lt;br /&gt;
 {{cbr}}&lt;br /&gt;
&lt;br /&gt;
{{infobox aircraft&lt;br /&gt;
| name           = McDonnell Douglas F-4 Phantom II&lt;br /&gt;
| hangar         = dave&lt;br /&gt;
| image          = F4N.JPG&lt;br /&gt;
| type           = Military aircraft/Interceptor aircraft/Fighter aircraft/Bomber aircraft&lt;br /&gt;
| manufacturer   = McDonnell/McDonnell Douglas&lt;br /&gt;
| authors        = Dave Culp&lt;br /&gt;
| fdm            = JSBSim&lt;br /&gt;
| fgname         = F-4N&lt;br /&gt;
| download       = http://www.daveshangar.org/aircraft/F-4N.tar.gz&lt;br /&gt;
| navbar         = 1&lt;br /&gt;
| float          = none&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Emilian H's hangar ===&lt;br /&gt;
&lt;br /&gt;
==== IAR 80 ====&lt;br /&gt;
This is an example for the [[IAR 80]] article, specifically in the [[IAR 80/info]] subpage.&lt;br /&gt;
&lt;br /&gt;
 {{obr}}infobox aircraft&lt;br /&gt;
 {{!}} name           = IAR 80&lt;br /&gt;
 {{!}} hangar         = emilianh&lt;br /&gt;
 {{!}} aircraft       = IAR80&lt;br /&gt;
 {{!}} image          = Iar80-flight.jpg&lt;br /&gt;
 {{!}} alt            = The IAR 80 in its the default livery.&lt;br /&gt;
 {{!}} image2         = Iar80-cockpit-dusk.jpg&lt;br /&gt;
 {{!}} alt2           = The IAR 80's cockpit as dusk&lt;br /&gt;
 {{!}} type           = Fighter aircraft&lt;br /&gt;
 {{!}} config         = Low wing aircraft&lt;br /&gt;
 {{!}} propulsion     = Propeller aircraft/Single-engine aircraft&lt;br /&gt;
 {{!}} manufacturer   = Industria Aeronautică Română (IAR)&lt;br /&gt;
 {{!}} authors        = Emilian Huminiuc (3D model, textures, YASim FDM)/Ron Jensen (JSBSim FDM)&lt;br /&gt;
 {{!}} fdm            = YASim/JSBSim&lt;br /&gt;
 {{!}} fgname         = IAR80-YASim&lt;br /&gt;
 {{!}} status-fdm     = 5&lt;br /&gt;
 {{!}} status-systems = 4&lt;br /&gt;
 {{!}} status-cockpit = 5&lt;br /&gt;
 {{!}} status-model   = 5&lt;br /&gt;
 {{!}} license        = CC-BY-NC-ND 4.0/GPLv2&lt;br /&gt;
 {{!}} note           = The JSBSim FDM is in beta&lt;br /&gt;
 {{!}} navbar         = 1&lt;br /&gt;
 {{cbr}}&lt;br /&gt;
&lt;br /&gt;
{{infobox aircraft&lt;br /&gt;
| name           = IAR 80&lt;br /&gt;
| hangar         = emilianh&lt;br /&gt;
| aircraft       = IAR80&lt;br /&gt;
| image          = Iar80-flight.jpg&lt;br /&gt;
| alt            = The IAR 80 in its the default livery.&lt;br /&gt;
| image2         = Iar80-cockpit-dusk.jpg&lt;br /&gt;
| alt2           = The IAR 80's cockpit as dusk&lt;br /&gt;
| type           = Fighter aircraft&lt;br /&gt;
| config         = Low wing aircraft&lt;br /&gt;
| propulsion     = Propeller aircraft/Single-engine aircraft&lt;br /&gt;
| manufacturer   = Industria Aeronautică Română (IAR)&lt;br /&gt;
| authors        = Emilian Huminiuc (3D model, textures, YASim FDM)/Ron Jensen (JSBSim FDM)&lt;br /&gt;
| fdm            = YASim/JSBSim&lt;br /&gt;
| fgname         = IAR80-YASim&lt;br /&gt;
| status-fdm     = 5&lt;br /&gt;
| status-systems = 4&lt;br /&gt;
| status-cockpit = 5&lt;br /&gt;
| status-model   = 5&lt;br /&gt;
| license        = CC-BY-NC-ND 4.0/GPLv2&lt;br /&gt;
| note           = The JSBSim FDM is in beta&lt;br /&gt;
| navbar         = 1&lt;br /&gt;
| float          = none&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== HerbyW's hangar ===&lt;br /&gt;
&lt;br /&gt;
==== Space Shuttle (FG Space Program) ====&lt;br /&gt;
This is an example for the [[Space Shuttle (FG Space Program)]] article, specifically in the [[Space Shuttle (FG Space Program)/info]] subpage.&lt;br /&gt;
&lt;br /&gt;
 {{obr}}infobox aircraft&lt;br /&gt;
 {{!}} name           = Shuttle&lt;br /&gt;
 {{!}} hangar         = herbyw&lt;br /&gt;
 {{!}} aircraft       = shuttle&lt;br /&gt;
 {{!}} image          = Atlantis.png&lt;br /&gt;
 {{!}} alt            = Shuttle ''Atlantis''&lt;br /&gt;
 {{!}} type           = Spaceplane&lt;br /&gt;
 {{!}} config         = Delta-wing aircraft&lt;br /&gt;
 {{!}} authors        = HerbyW (FDM)/Firefly (3D)/Original Project Jon S. Berndt&lt;br /&gt;
 {{!}} fdm            = JSBSim&lt;br /&gt;
 {{!}} fgname         = shuttle/shuttle-Atlantis/shuttle-Columbia/shuttle-Launcher&lt;br /&gt;
 {{!}} status-fdm     = 2&lt;br /&gt;
 {{!}} status-systems = 1&lt;br /&gt;
 {{!}} status-cockpit = 0&lt;br /&gt;
 {{!}} status-model   = 3&lt;br /&gt;
 {{!}} ready          = rembrandt&lt;br /&gt;
 {{!}} craft          = spacecraft&lt;br /&gt;
 {{!}} navbar         = 1&lt;br /&gt;
 {{cbr}}&lt;br /&gt;
&lt;br /&gt;
{{infobox aircraft&lt;br /&gt;
| name           = Shuttle&lt;br /&gt;
| hangar         = herbyw&lt;br /&gt;
| aircraft       = shuttle&lt;br /&gt;
| image          = Atlantis.png&lt;br /&gt;
| alt            = Shuttle ''Atlantis''&lt;br /&gt;
| type           = Spaceplane&lt;br /&gt;
| config         = Delta-wing aircraft&lt;br /&gt;
| authors        = HerbyW (FDM)/Firefly (3D)/Original Project Jon S. Berndt&lt;br /&gt;
| fdm            = JSBSim&lt;br /&gt;
| fgname         = shuttle/shuttle-Atlantis/shuttle-Columbia/shuttle-Launcher&lt;br /&gt;
| status-fdm     = 2&lt;br /&gt;
| status-systems = 1&lt;br /&gt;
| status-cockpit = 0&lt;br /&gt;
| status-model   = 3&lt;br /&gt;
| ready          = rembrandt&lt;br /&gt;
| craft          = spacecraft&lt;br /&gt;
| navbar         = 1&lt;br /&gt;
| float          = none&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Lake of Constance hangar ===&lt;br /&gt;
&lt;br /&gt;
==== Boeing 707-420 ====&lt;br /&gt;
This is an example for the [[Boeing 707-420]] article, specifically in the [[Boeing 707-420/info]] subpage.&lt;br /&gt;
&lt;br /&gt;
 {{obr}}infobox aircraft&lt;br /&gt;
 {{!}} name           = Boeing 707-420/430&lt;br /&gt;
 {{!}} hangar         = lake of constance&lt;br /&gt;
 {{!}} image          = Splash707-420.png&lt;br /&gt;
 {{!}} alt            = {{LangSwitch&lt;br /&gt;
                      {{!}} de = Splash Screen der Boeing 707-420/430&lt;br /&gt;
                      {{!}} en = The 707-420/430's splash screen&lt;br /&gt;
                    }}&lt;br /&gt;
 {{!}} type           = Airliner/Military tanker aircraft&lt;br /&gt;
 {{!}} config         = Low wing aircraft/Monoplane aircraft/Retractable gear aircraft/Tricycle landing gear aircraft&lt;br /&gt;
 {{!}} propulsion     = Quadjet&lt;br /&gt;
 {{!}} manufacturer   = Boeing&lt;br /&gt;
 {{!}} fdm            = JSBSim&lt;br /&gt;
 {{!}} authors        = {{LangSwitch&lt;br /&gt;
                      {{!}} de = Marc Kraus - Lake of Constance Hangar/Original von Innis Cunningham&lt;br /&gt;
                      {{!}} en = Marc Kraus - Lake of Constance Hangar/Original model by Innis Cunningham&lt;br /&gt;
                    }}&lt;br /&gt;
 {{!}} fgname         = 707/707-TT/EC-137D&lt;br /&gt;
 {{!}} status-fdm     = 4&lt;br /&gt;
 {{!}} status-systems = 5&lt;br /&gt;
 {{!}} status-cockpit = 5&lt;br /&gt;
 {{!}} status-model   = 5&lt;br /&gt;
 {{!}} ready          = tutorials/checklist/rembrandt/airrefuel&lt;br /&gt;
 {{!}} download       = http://www.marc-kraus.de&lt;br /&gt;
 {{!}} navbar         = 1&lt;br /&gt;
 {{cbr}}&lt;br /&gt;
&lt;br /&gt;
{{infobox aircraft&lt;br /&gt;
| name           = Boeing 707-420/430&lt;br /&gt;
| hangar         = lake of constance&lt;br /&gt;
| image          = Splash707-420.png&lt;br /&gt;
| alt            = {{LangSwitch&lt;br /&gt;
                     | de = Splash Screen der Boeing 707-420/430&lt;br /&gt;
                     | en = The 707-420/430's splash screen&lt;br /&gt;
                   }}&lt;br /&gt;
| type           = Airliner/Military tanker aircraft&lt;br /&gt;
| config         = Low wing aircraft/Monoplane aircraft/Retractable gear aircraft/Tricycle landing gear aircraft&lt;br /&gt;
| propulsion     = Quadjet&lt;br /&gt;
| manufacturer   = Boeing&lt;br /&gt;
| fdm            = JSBSim&lt;br /&gt;
| authors        = {{LangSwitch&lt;br /&gt;
                     | de = Marc Kraus - Lake of Constance Hangar/Original von Innis Cunningham&lt;br /&gt;
                     | en = Marc Kraus - Lake of Constance Hangar/Original model by Innis Cunningham&lt;br /&gt;
                   }}&lt;br /&gt;
| fgname         = 707/707-TT/EC-137D&lt;br /&gt;
| status-fdm     = 4&lt;br /&gt;
| status-systems = 5&lt;br /&gt;
| status-cockpit = 5&lt;br /&gt;
| status-model   = 5&lt;br /&gt;
| ready          = tutorials/checklist/rembrandt/airrefuel&lt;br /&gt;
| download       = http://www.marc-kraus.de&lt;br /&gt;
| navbar         = 1&lt;br /&gt;
| float          = none&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== PAF hangar ===&lt;br /&gt;
&lt;br /&gt;
==== Douglas C-47 Skytrain ====&lt;br /&gt;
This is an example for the [[Douglas C-47 Skytrain]] article, specifically in the [[Douglas C-47 Skytrain/info]] subpage.&lt;br /&gt;
&lt;br /&gt;
 {{obr}}infobox aircraft&lt;br /&gt;
 {{!}} name           = Douglas DC-3 C-47&lt;br /&gt;
 {{!}} hangar         = paf&lt;br /&gt;
 {{!}} image          = Dc-3-splash.png&lt;br /&gt;
 {{!}} type           = Airliner/Military transport aircraft&lt;br /&gt;
 {{!}} config         = Low wing aircraft&lt;br /&gt;
 {{!}} propulsion     = Twin-engine piston aircraft&lt;br /&gt;
 {{!}} manufacturer   = Douglas&lt;br /&gt;
 {{!}} authors        = PAF team (FDM, Hydraulic, Electric, Dual Control, Instruments, 3D)/Emmanuel Baranger (Exterior &amp;amp; interior 3D model)&lt;br /&gt;
 {{!}} status-fdm     = 4&lt;br /&gt;
 {{!}} status-systems = 4&lt;br /&gt;
 {{!}} status-cockpit = 4&lt;br /&gt;
 {{!}} status-model   = 4&lt;br /&gt;
 {{!}} fdm            = YASim/JSBSim&lt;br /&gt;
 {{!}} fgname         = dc-3-jsbsim (wheels)/dc-3-yasim (wheels)/dc-3A (Amphibius)/dc-3-copilot/dc-3-psg1/dc-3-psg2/dc-3-psg3/dc-3-psg4&lt;br /&gt;
 {{!}} ready          = dualcontrol/tutorials&lt;br /&gt;
 {{!}} devel-website  = &amp;lt;nowiki&amp;gt;http://equipe-flightgear.forumactif.com/t756-douglas-dc-3-c-47-part-2-2&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 {{!}} download       = &amp;lt;nowiki&amp;gt;http://clement.delhamaide.free.fr/PAF/Douglas-Dc3.tar.gz&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 {{!}} liverydbid     = 76&lt;br /&gt;
 {{!}} navbar         = 1&lt;br /&gt;
 {{cbr}}&lt;br /&gt;
&lt;br /&gt;
{{infobox aircraft&lt;br /&gt;
| name           = Douglas DC-3 C-47&lt;br /&gt;
| hangar         = paf&lt;br /&gt;
| image          = Dc-3-splash.png&lt;br /&gt;
| type           = Airliner/Military transport aircraft&lt;br /&gt;
| config         = Low wing aircraft&lt;br /&gt;
| propulsion     = Twin-engine piston aircraft&lt;br /&gt;
| manufacturer   = Douglas&lt;br /&gt;
| authors        = PAF team (FDM, Hydraulic, Electric, Dual Control, Instruments, 3D)/Emmanuel Baranger (Exterior &amp;amp; interior 3D model)&lt;br /&gt;
| status-fdm     = 4&lt;br /&gt;
| status-systems = 4&lt;br /&gt;
| status-cockpit = 4&lt;br /&gt;
| status-model   = 4&lt;br /&gt;
| fdm            = YASim/JSBSim&lt;br /&gt;
| fgname         = dc-3-jsbsim (wheels)/dc-3-yasim (wheels)/dc-3A (Amphibius)/dc-3-copilot/dc-3-psg1/dc-3-psg2/dc-3-psg3/dc-3-psg4&lt;br /&gt;
| ready          = dualcontrol/tutorials &lt;br /&gt;
| devel-website  = http://equipe-flightgear.forumactif.com/t756-douglas-dc-3-c-47-part-2-2&lt;br /&gt;
| download       = http://clement.delhamaide.free.fr/PAF/Douglas-Dc3.tar.gz&lt;br /&gt;
| liverydbid     = 76&lt;br /&gt;
| navbar         = 1&lt;br /&gt;
| float          = none&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Prestes hangar ===&lt;br /&gt;
&lt;br /&gt;
==== Boeing 707-400 ====&lt;br /&gt;
This is an example for the [[Boeing 707-400]] article, specifically in the [[Boeing 707-400/info]] subpage.&lt;br /&gt;
&lt;br /&gt;
 {{obr}}infobox aircraft&lt;br /&gt;
 {{!}} name           = Boeing 707-400&lt;br /&gt;
 {{!}} hangar         = prestes&lt;br /&gt;
 {{!}} aircraft       = boeing-707-400&lt;br /&gt;
 {{!}} image          = 707-400.png&lt;br /&gt;
 {{!}} alt            = Lufthanse 707-400&lt;br /&gt;
 {{!}} image2         = 707-400b.png&lt;br /&gt;
 {{!}} alt2           = The VARIG 707-400 PAX&lt;br /&gt;
 {{!}} type           = Airliner&lt;br /&gt;
 {{!}} config         = Low wing aircraft&lt;br /&gt;
 {{!}} propulsion     = Jet aircraft/Four-engine aircraft&lt;br /&gt;
 {{!}} manufacturer   = Boeing&lt;br /&gt;
 {{!}} authors        = Isaias V. Prestes/Innis Cunningham/Erik Hofman (FDM)&lt;br /&gt;
 {{!}} fdm            = JSBSim&lt;br /&gt;
 {{!}} fgname         = 707-400&lt;br /&gt;
 {{!}} status         = Alpha&lt;br /&gt;
 {{!}} navbar         = 1&lt;br /&gt;
 {{cbr}}&lt;br /&gt;
&lt;br /&gt;
{{infobox aircraft&lt;br /&gt;
| name           = Boeing 707-400&lt;br /&gt;
| hangar         = prestes&lt;br /&gt;
| aircraft       = boeing-707-400&lt;br /&gt;
| image          = 707-400.png&lt;br /&gt;
| alt            = Lufthanse 707-400&lt;br /&gt;
| image2         = 707-400b.png&lt;br /&gt;
| alt2           = The VARIG 707-400 PAX&lt;br /&gt;
| type           = Airliner&lt;br /&gt;
| config         = Low wing aircraft&lt;br /&gt;
| propulsion     = Jet aircraft/Four-engine aircraft&lt;br /&gt;
| manufacturer   = Boeing&lt;br /&gt;
| authors        = Isaias V. Prestes/Innis Cunningham/Erik Hofman (FDM)&lt;br /&gt;
| fdm            = JSBSim&lt;br /&gt;
| fgname         = 707-400&lt;br /&gt;
| status         = Alpha&lt;br /&gt;
| navbar         = 1&lt;br /&gt;
| float          = none&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Lost aircraft ===&lt;br /&gt;
&lt;br /&gt;
==== C-17 Globemaster III ====&lt;br /&gt;
This is an example for the [[C-17 Globemaster III]] article, specifically in the [[C-17 Globemaster III/info]] subpage.&lt;br /&gt;
&lt;br /&gt;
 {{obr}}infobox aircraft&lt;br /&gt;
 {{!}} name           = C-17 Globemaster III&lt;br /&gt;
 {{!}} hangar         = bermuda&lt;br /&gt;
 {{!}} image          = C17inflight.png&lt;br /&gt;
 {{!}} type           = Military transport aircraft/Strategic aircraft/Tactical airlifter&lt;br /&gt;
 {{!}} config         = High wing aircraft&lt;br /&gt;
 {{!}} propulsion     = Jet aircraft/Four-engine aircraft&lt;br /&gt;
 {{!}} manufacturer   = McDonnell Douglas/Boeing&lt;br /&gt;
 {{!}} authors        = Jon Bourgeois (FDM)/Adam Fothergill (3D)&lt;br /&gt;
 {{!}} fdm            = JSBSim&lt;br /&gt;
 {{!}} fgname         = C-17&lt;br /&gt;
 {{!}} status         = Not released yet&lt;br /&gt;
 {{!}} note           = The &amp;lt;nowiki&amp;gt;[http://cid-4501304d324ef633.office.live.com/self.aspx/.Public/C-17/C-17%2020100418.zip original download link]&amp;lt;/nowiki&amp;gt; is dead.&lt;br /&gt;
 {{!}} navbar         = 1&lt;br /&gt;
 {{cbr}}&lt;br /&gt;
&lt;br /&gt;
{{infobox aircraft&lt;br /&gt;
| name           = C-17 Globemaster III&lt;br /&gt;
| hangar         = bermuda&lt;br /&gt;
| image          = C17inflight.png&lt;br /&gt;
| type           = Military transport aircraft/Strategic aircraft/Tactical airlifter&lt;br /&gt;
| config         = High wing aircraft&lt;br /&gt;
| propulsion     = Jet aircraft/Four-engine aircraft&lt;br /&gt;
| manufacturer   = McDonnell Douglas/Boeing&lt;br /&gt;
| authors        = Jon Bourgeois (FDM)/Adam Fothergill (3D)&lt;br /&gt;
| fdm            = JSBSim&lt;br /&gt;
| fgname         = C-17&lt;br /&gt;
| status         = Not released yet&lt;br /&gt;
| note           = The [http://cid-4501304d324ef633.office.live.com/self.aspx/.Public/C-17/C-17%2020100418.zip original download link] is dead.&lt;br /&gt;
| navbar         = 1&lt;br /&gt;
| float          = none&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== No hangar ===&lt;br /&gt;
&lt;br /&gt;
==== Pipistrel Virus SW ====&lt;br /&gt;
This is an example for the [[Pipistrel Virus SW]] article, specifically in the [[Pipistrel Virus SW/info]] subpage.&lt;br /&gt;
&lt;br /&gt;
 {{obr}}infobox aircraft&lt;br /&gt;
 {{!}} name           = Pipistrel Virus SW&lt;br /&gt;
 {{!}} image          = Pipistrel Virus SW.png&lt;br /&gt;
 {{!}} type           = Civil aircraft/Civil utility aircraft&lt;br /&gt;
 {{!}} propulsion     = Propeller aircraft/Single-engine aircraft&lt;br /&gt;
 {{!}} manufacturer   = Pipistrel&lt;br /&gt;
 {{!}} author1        = {{obr}}usr{{!}}Nick R{{cbr}}&lt;br /&gt;
 {{!}} fdm            = JSBSim&lt;br /&gt;
 {{!}} fgname         = virus-sw&lt;br /&gt;
 {{!}} status         = Development&lt;br /&gt;
 {{!}} devel-repo     = {{obr}}[[Template:github url|github url]]{{!}}user=Nick-R9{{!}}repo=pipistrel-virus-sw{{cbr}}&lt;br /&gt;
 {{!}} download       = &amp;lt;nowiki&amp;gt;http://www.fgpipistrel.org/downloads/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 {{!}} navbar         = 1&lt;br /&gt;
 {{cbr}}&lt;br /&gt;
&lt;br /&gt;
{{infobox aircraft&lt;br /&gt;
| name           = Pipistrel Virus SW&lt;br /&gt;
| image          = Pipistrel Virus SW.png&lt;br /&gt;
| type           = Civil aircraft/Civil utility aircraft&lt;br /&gt;
| propulsion     = Propeller aircraft/Single-engine aircraft&lt;br /&gt;
| manufacturer   = Pipistrel&lt;br /&gt;
| author1        = {{usr|Nick R}}&lt;br /&gt;
| fdm            = JSBSim&lt;br /&gt;
| fgname         = virus-sw&lt;br /&gt;
| status         = Development&lt;br /&gt;
| devel-repo     = {{github url|user=Nick-R9|repo=pipistrel-virus-sw}}&lt;br /&gt;
| download       = http://www.fgpipistrel.org/downloads/&lt;br /&gt;
| navbar         = 1&lt;br /&gt;
| float          = none&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Infobox templates|Aircraft]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Elgaton</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Template:Hangar_banner&amp;diff=112862</id>
		<title>Template:Hangar banner</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Template:Hangar_banner&amp;diff=112862"/>
		<updated>2017-12-09T15:30:41Z</updated>

		<summary type="html">&lt;p&gt;Elgaton: Translate the template to Italian&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{#switch: {{{1|fgaddon}}}&lt;br /&gt;
  | aucafly           = [[File:Aucafly banner.jpg|{{{size|300px}}}|AUCAFLY hangar|alt=AUCAFLY hangar|link=https://aucafly.wordpress.com/]]&lt;br /&gt;
  | bermuda           = [[File:Bermudastriangle.png|{{{size|300px}}}|Bermuda Triangle disappearance|alt=Bermuda Triangle disappearance|link=:Category:Bermuda Triangle|]]&lt;br /&gt;
  | buckaroo          = &amp;lt;big&amp;gt;&amp;lt;big&amp;gt;[http://www.buckarooshangar.com/flightgear Buckaroo's Hangar]&amp;lt;/big&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
  | bulldogrs           = [[File:BulldogRS_banner.jpg|{{{size|300px}}}|Bulldog_RS_hangar|alt=Bulldog RS hangar|link=https://bulldogrs.wordpress.com/]]&lt;br /&gt;
  | dave              = [[File:Dave's hangar logo.png|{{{size|300px}}}|Dave's hangar|alt=Dave's hangar|link=http://www.daveshangar.org/]]&lt;br /&gt;
  | fgaddon           = [[File:FGAddon logo.png|{{{size|300px}}}&lt;br /&gt;
                          | {{LangSwitch&lt;br /&gt;
                              | ar = FGAddon: حظيرة الطائرات الخاصة بفلايت جير&lt;br /&gt;
                              | de = FGAddon: Der offizielle FlightGear-Flugzeughangar&lt;br /&gt;
                              | en = FGAddon: The official FlightGear hangar&lt;br /&gt;
                              | es = FGADDON: El hangar official de FlightGear&lt;br /&gt;
                              | fr = FGAddon: Le hangar d'aéronef officiel de FlightGear&lt;br /&gt;
                              | it = FGAddon: l'hangar ufficiale di FlightGear&lt;br /&gt;
                              | th = FGAddon: ที่รวบรวมเครื่องบินของ FlightGear เอง&lt;br /&gt;
&lt;br /&gt;
                            }}&lt;br /&gt;
                          | alt=FGAddon|link=FGAddon&lt;br /&gt;
                        ]]&lt;br /&gt;
  | fgdata            = [[File:FGData_logo.png|{{{size|300px}}}&lt;br /&gt;
                          | {{LangSwitch&lt;br /&gt;
                              | ar = FGData: طائرات الحزمة الرئيسية لدى فلايت جير&lt;br /&gt;
                              | de = FGData: Flugzeuge des FlightGear-Basispakets.&lt;br /&gt;
                              | en = FGData: Aircraft of the base FlightGear package.&lt;br /&gt;
                              | fr = FGData: Les aéronefs FlightGear de base.&lt;br /&gt;
                              | it = FGData: gli aeromobili del pacchetto FlightGear di base.&lt;br /&gt;
                              | th = FGData: มาพร้อมกับโปรแกรม&lt;br /&gt;
                            }}&lt;br /&gt;
                          | alt=FlightGear|link=FlightGear&lt;br /&gt;
                        ]]&lt;br /&gt;
  | fguk              = [[File:Fguk.png|{{{size|300px}}}|FGUK hangar|alt=FGUK hangar|link=http://www.fguk.eu/index.php/hangar]]&lt;br /&gt;
  | grtux             = &amp;lt;big&amp;gt;&amp;lt;big&amp;gt;[https://sites.google.com/site/grtuxhangar/ GRTux hangar]&amp;lt;/big&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
  | helijah           = [[File:Helijahlogo300whiteframed.png|{{{size|300px}}}|Helijah hangar|alt=Helijah hangar|link=http://helijah.free.fr/flightgear/hangar.htm]]&lt;br /&gt;
  | herbyw            = [[File:Herbywlogo.png|{{{size|300px}}}|HerbyW's hangar|alt=HerbyW's hangar|link=https://github.com/HerbyW]]&lt;br /&gt;
  | it0uchpods        = [[File:Ithhq.png|{{{size|300px}}}|It0uchpods hangar|alt=it0uchpods Hangar|link=https://github.com/it0uchpods]]&lt;br /&gt;
  | lake of constance = [[File:Lakeofconstance.png|{{{size|300px}}}|Lake of Constance hangar|alt=Lake of Constance hangar|link=http://www.marc-kraus.de]]&lt;br /&gt;
  | paf               = &amp;lt;big&amp;gt;&amp;lt;big&amp;gt;[http://equipe-flightgear.forumactif.com/t835-hangar-de-la-paf-paf-team-hangar#14330 PAF hangar]&amp;lt;/big&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
  | prestes           = &amp;lt;big&amp;gt;&amp;lt;big&amp;gt;[http://presteshangar.wikidot.com/ Prestes hangar]&amp;lt;/big&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
}}&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{Informative template|1=&lt;br /&gt;
== Goal ==&lt;br /&gt;
This template is used to generate and embed an aircraft hangar banner graphic or text, linking to the hangar's website.&lt;br /&gt;
&lt;br /&gt;
== Usage ==&lt;br /&gt;
 {{obr}}hangar banner&lt;br /&gt;
 {{!}} hangar =&lt;br /&gt;
 {{!}} ''size''   =&lt;br /&gt;
 {{cbr}}&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
=== AUCAFLY hangar ===&lt;br /&gt;
 {{obr}}hangar banner{{!}}aucafly{{cbr}}&lt;br /&gt;
&lt;br /&gt;
{{hangar banner|aucafly}}&lt;br /&gt;
&lt;br /&gt;
=== Bermuda Triangle ===&lt;br /&gt;
 {{obr}}hangar banner{{!}}bermuda{{cbr}}&lt;br /&gt;
&lt;br /&gt;
{{hangar banner|bermuda}}&lt;br /&gt;
&lt;br /&gt;
=== Buckaroo's hangar ===&lt;br /&gt;
 {{obr}}hangar banner{{!}}buckaroo{{cbr}}&lt;br /&gt;
&lt;br /&gt;
{{hangar banner|buckaroo}}&lt;br /&gt;
&lt;br /&gt;
=== Bulldog RS hangar ===&lt;br /&gt;
 {{obr}}hangar banner{{!}}bulldogrs{{cbr}}&lt;br /&gt;
&lt;br /&gt;
{{hangar banner|bulldogrs}}&lt;br /&gt;
&lt;br /&gt;
=== Dave's hangar ===&lt;br /&gt;
 {{obr}}hangar banner{{!}}dave{{cbr}}&lt;br /&gt;
&lt;br /&gt;
{{hangar banner|dave}}&lt;br /&gt;
&lt;br /&gt;
=== FGAddon hangar ===&lt;br /&gt;
 {{obr}}hangar banner{{!}}fgaddon{{cbr}}&lt;br /&gt;
&lt;br /&gt;
{{hangar banner|fgaddon}}&lt;br /&gt;
&lt;br /&gt;
=== FGData hangar ===&lt;br /&gt;
 {{obr}}hangar banner{{!}}fgdata{{cbr}}&lt;br /&gt;
&lt;br /&gt;
{{hangar banner|fgdata}}&lt;br /&gt;
&lt;br /&gt;
=== FGUK hangar ===&lt;br /&gt;
 {{obr}}hangar banner{{!}}fguk{{cbr}}&lt;br /&gt;
&lt;br /&gt;
{{hangar banner|fguk}}&lt;br /&gt;
&lt;br /&gt;
=== GRTux hangar ===&lt;br /&gt;
 {{obr}}hangar banner{{!}}grtux{{cbr}}&lt;br /&gt;
&lt;br /&gt;
{{hangar banner|grtux}}&lt;br /&gt;
&lt;br /&gt;
=== Helijah's hangar ===&lt;br /&gt;
 {{obr}}hangar banner{{!}}helijah{{cbr}}&lt;br /&gt;
&lt;br /&gt;
{{hangar banner|helijah}}&lt;br /&gt;
&lt;br /&gt;
=== HerbyW's hangar ===&lt;br /&gt;
 {{obr}}hangar banner{{!}}herbyw{{cbr}}&lt;br /&gt;
&lt;br /&gt;
{{hangar banner|herbyw}}&lt;br /&gt;
&lt;br /&gt;
=== it0uchpods hangar ===&lt;br /&gt;
 {{obr}}hangar banner{{!}}it0uchpods{{cbr}}&lt;br /&gt;
&lt;br /&gt;
{{hangar banner|it0uchpods}}&lt;br /&gt;
&lt;br /&gt;
=== Lake of Constance hangar ===&lt;br /&gt;
 {{obr}}hangar banner{{!}}lake of constance{{cbr}}&lt;br /&gt;
&lt;br /&gt;
{{hangar banner|lake of constance}}&lt;br /&gt;
&lt;br /&gt;
=== PAF hangar ===&lt;br /&gt;
 {{obr}}hangar banner{{!}}paf{{cbr}}&lt;br /&gt;
&lt;br /&gt;
{{hangar banner|paf}}&lt;br /&gt;
&lt;br /&gt;
=== Prestes hangar ===&lt;br /&gt;
 {{obr}}hangar banner{{!}}prestes{{cbr}}&lt;br /&gt;
&lt;br /&gt;
{{hangar banner|prestes}}&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Templates]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Elgaton</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Template:Cessna&amp;diff=112861</id>
		<title>Template:Cessna</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Template:Cessna&amp;diff=112861"/>
		<updated>2017-12-09T15:28:47Z</updated>

		<summary type="html">&lt;p&gt;Elgaton: Translate the template to Italian&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Navbox&lt;br /&gt;
| name      = Cessna&lt;br /&gt;
| title     = {{LangSwitch&lt;br /&gt;
                | ar = [[:Category:Cessna|Cessna]] طائرات&lt;br /&gt;
                | de = [[:Category:Cessna|Cessna]] Flugzeuge&lt;br /&gt;
                | en = [[:Category:Cessna|Cessna]] aircraft&lt;br /&gt;
                | es = Aeronaves [[:Category:Cessna|Cessna]] &lt;br /&gt;
                | fr = Aéronefs [[:Category:Cessna|Cessna]]&lt;br /&gt;
                | it = Aeromobili [[:Category:Cessna|Cessna]]&lt;br /&gt;
                | zh = [[:Category:Cessna|赛斯纳]]飞机 &lt;br /&gt;
              }}&lt;br /&gt;
| listclass = hlist&lt;br /&gt;
&lt;br /&gt;
| group1 = {{LangSwitch&lt;br /&gt;
             | de = Zivile Flugzeuge&lt;br /&gt;
             | en = Civilian aircraft&lt;br /&gt;
             | es = Aeronaves Civiles&lt;br /&gt;
             | fr = Aéronefs civil&lt;br /&gt;
             | it = Aeromobili civili&lt;br /&gt;
             | zh = 民用飞机&lt;br /&gt;
           }}&lt;br /&gt;
| list1  =&lt;br /&gt;
* [[Cessna 150|150L]]&lt;br /&gt;
* {{LangSwitch&lt;br /&gt;
    | de = [[:de:Cessna 172P|172P]]&lt;br /&gt;
    | en = [[Cessna 172P|172P]]&lt;br /&gt;
    | es = [[:es:Cessna 172P|172P]]&lt;br /&gt;
    | fr = [[:fr:Cessna 172P|172P]]&lt;br /&gt;
    | it = [[:it:Cessna 172P|172P]]&lt;br /&gt;
    | nl = [[:nl:Cessna 172P|172P]]&lt;br /&gt;
    | zh = [[:zh:Cessna 172P|172P]]&lt;br /&gt;
  }}&lt;br /&gt;
* [[Cessna 172R Skyhawk|172R]]&lt;br /&gt;
* [[Cessna 182S|182S]]&lt;br /&gt;
* [[Cessna C310|310]]&lt;br /&gt;
* {{LangSwitch&lt;br /&gt;
    | de = [[:de:Cessna 337G Skymaster|337G Skymaster]]&lt;br /&gt;
    | en = [[Cessna 337G Skymaster|337G Skymaster]]&lt;br /&gt;
    | es = [[:es:Cessna 337G Skymaster|337G Skymaster]]&lt;br /&gt;
    | fr = [[:fr:Cessna 337G Skymaster|337G Skymaster]]&lt;br /&gt;
    | it = [[:it:Cessna 337G Skymaster|337G Skymaster]]&lt;br /&gt;
  }}&lt;br /&gt;
* [[Cessna 550 Citation II|550 Citation II]]&lt;br /&gt;
* [[Cessna Citation Bravo|Citation Bravo]]&lt;br /&gt;
* {{LangSwitch&lt;br /&gt;
    | de = [[:de:Cessna Citation X|Citation X]]&lt;br /&gt;
    | en = [[Cessna Citation X|Citation X]]&lt;br /&gt;
    | es = [[:es:Cessna Citation X|Citation X]]&lt;br /&gt;
    | fr = [[:fr:Cessna Citation X|Citation X]]&lt;br /&gt;
    | it = [[:it:Cessna Citation X|Citation X]]&lt;br /&gt;
  }}&lt;br /&gt;
&lt;br /&gt;
| group2 = {{LangSwitch&lt;br /&gt;
             | de = Militärische Flugzeuge&lt;br /&gt;
             | en = Military aircraft&lt;br /&gt;
             | es = Aeronaves Militar&lt;br /&gt;
             | fr = Aéronefs militaire&lt;br /&gt;
             | it = Aeromobili militari&lt;br /&gt;
             | zh = 军用飞机&lt;br /&gt;
           }}&lt;br /&gt;
| list2  =&lt;br /&gt;
* [[Cessna T-37|T-37]]&lt;br /&gt;
}}&amp;lt;includeonly&amp;gt;{{main other| [[Category:Cessna]] }}&amp;lt;/includeonly&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{Informative template|1=&lt;br /&gt;
__NOTOC__&lt;br /&gt;
== Goal ==&lt;br /&gt;
This navigation template links together Cessna aircraft.&lt;br /&gt;
&lt;br /&gt;
Adding this template to a page in the article namespace will automatically add [[:Category:Cessna]] to that page.&lt;br /&gt;
&lt;br /&gt;
== Usage ==&lt;br /&gt;
Put this line before the categories and the language links at the bottom of the article.&lt;br /&gt;
&lt;br /&gt;
 {{obr}}'''Cessna'''{{cbr}}&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Manufacturer navigation templates]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Elgaton</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Howto:Set_up_a_multiplayer_server&amp;diff=111397</id>
		<title>Howto:Set up a multiplayer server</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Howto:Set_up_a_multiplayer_server&amp;diff=111397"/>
		<updated>2017-10-22T13:10:42Z</updated>

		<summary type="html">&lt;p&gt;Elgaton: Moved GitLab repository URLs to SourceForge repository URLs&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is dedicated to providing a short overview of installing the [[FlightGear Multiplayer Server]] ('fgms'). The reader is assumed to be reasonably familiar with working in a Unix/Linux shell environment.&lt;br /&gt;
&lt;br /&gt;
== Pre-Requisites ==&lt;br /&gt;
* A computer running a variant of *nix to compile and host the server. Speed of the machine isn't of great consequence as the protocol is a multiplexer which doesn't require much processing grunt.&lt;br /&gt;
** For specific documentation for setting up on FreeBSD see [[Howto:Set up a multiplayer server on FreeBSD]].&lt;br /&gt;
* direct/physical or remote access to the server (i.e. SSH/telnet, a conventional web hosting package will usually '''not''' be sufficient!)-suitable hosting packages are: dedicated root servers, virtual private servers, shell servers - for a collection of '''free''' shell account providers that may be suitable for fgms, see [[Free Shell Providers]] (you may want to check this out if you are interested in running fgms but don't have hosting yet)&lt;br /&gt;
* if the server is meant to be a public internet server: an internet connection, featuring sufficient upstream/downstream capabilities (see below for details concerning bandwidth requirements). &lt;br /&gt;
* firewall policies will need to be set up to allow for incoming and outgoing UDP traffic for the corresponding ports, the same applies to the administration port (TCP)&lt;br /&gt;
* permission to run unattended background processes (this may only be an issue with certain limited hosting packages)&lt;br /&gt;
* a working GNU toolchain including gcc/g++ (compiler), make &amp;amp;  cmake&lt;br /&gt;
* fgms source code, currently version 0.10.23&lt;br /&gt;
* about 5-10 MB of hard disk space (mainly required for building the binary)&lt;br /&gt;
&lt;br /&gt;
== Traffic &amp;amp; Bandwidth Considerations ==&lt;br /&gt;
&lt;br /&gt;
Note: Currently (May 2008), the server code basically boils down to a packet multiplexer (i.e. most data is -unconditionally- transmitted to all 'active' clients), which may thus create considerable amounts of traffic; this ought to be taken into consideration due to bandwidth limitations in most hosting packages (i.e. '''fgms may create considerable amounts of traffic!'''). For basic calculations: inbound traffic is 25 Kilobit per second while outbound is 25 Kbits per second for each plane/client that can 'see' another. &lt;br /&gt;
&lt;br /&gt;
By default, assuming a 10hz update interval, each active fgfs client will currently cause I/O traffic of approximately 5 kbytes/sec (one update consuming ~500 bytes) [http://www.mail-archive.com/flightgear-devel@lists.sourceforge.net/msg16016.html].&lt;br /&gt;
&lt;br /&gt;
As client updates have to be propagated to all other active clients by the server, this number has to be multiplied by the number of active clients -1 (i.e. clients within a configurable range, minus the originating client). &lt;br /&gt;
In addition, the fgms system allows for traffic updates to be sort of 'mirrored' on (relayed to) other configurable multiplayer/relay servers. &lt;br /&gt;
&lt;br /&gt;
This feature makes it possible for users/clients to use an arbitrary server (with acceptable latency), but still see clients/vehicles connected to different servers. Thus, such relay servers may additionally increase inbound/outbound traffic considerably as all traffic is mirrored/propagated to such relays.&lt;br /&gt;
&lt;br /&gt;
Having more servers should actually decrease the load on each server in high load situations, i.e. when most of the clients are within range of each other. See this&lt;br /&gt;
[http://www.gidenstam.org/FlightGear/fgms/fgms_bandwidth_estimates.txt brief note on the theoretical bandwidth behaviour of fgms.]&lt;br /&gt;
&lt;br /&gt;
=== Facts ===&lt;br /&gt;
In March 2008, the main fgms multiplayer server (pigeond.net) was reported to consume approximately 15 gb of bandwidth per '''day''', with an average throughput of 200 kB/sec and peak loads of up to ~ 650 kB/sec [http://www.mail-archive.com/flightgear-devel@lists.sourceforge.net/msg16016.html].&lt;br /&gt;
&lt;br /&gt;
During the same month (the much less used but interconnected) mpserver06.flightgear.org had on average 742 MB incoming and 688 MB outgoing traffic per day (i.e. 72 kbit/sec respective 66 kbit/sec on average).&lt;br /&gt;
&lt;br /&gt;
In September 2009, mpserver 05 had a massive peak bandwidth of 1.0 MB/sec. Average bandwidth consumed was about 9 GB of bandwidth per day. The average bandwidth usage per day is climbing due to more users moving from 02 to 05.&lt;br /&gt;
&lt;br /&gt;
In July 2013, mpserver01 load was reported averaging at 10 MBit/sec&lt;br /&gt;
&lt;br /&gt;
=== Reducing bandwidth requirements ===&lt;br /&gt;
Total network traffic is mainly determined by the number of active clients that 'see eachother' and configured mirrors. &lt;br /&gt;
If traffic considerations are relevant, the following options exist to reduce overall server/network load:&lt;br /&gt;
&lt;br /&gt;
* configure a relatively low &amp;quot;server.out_of_reach&amp;quot; value, so that clients outside a certain range are not provided with updates (usually about 100 nm on the main server network)&lt;br /&gt;
* for virtual gatherings (i.e. fly-ins), have clients use airports and places that do not have lots of other traffic (i.e. in other words, avoid places like standard airports such as KSFO)&lt;br /&gt;
* avoid the use of unnecessary relay servers&lt;br /&gt;
* if you are not interested in your server being publicly available, only share its address with your friends privately&lt;br /&gt;
* for local testing/development purposes, you may want to run only a private fgms session, that may be specific to your LAN or even computer.&lt;br /&gt;
&lt;br /&gt;
== Getting &amp;amp; Building fgms ==&lt;br /&gt;
* You will need the build tools cmake and make, and also g++ to compile the fgms application. These can usually be found in the package manager for most the common Linux distributions. You will also need the git client to fetch the source code from the repository, if you plan to download it from the command line interface (see below).&lt;br /&gt;
* Once the build tools are installed on your machine, create a directory to hold the source code. This could be named anything, such as fgms. Create it in your user home directory. Note that this WILL NOT be the directory where the program will be compiled.&lt;br /&gt;
* Now 'cd' into the directory you just made, where you will run the command to fetch the source code from the git repository (see below). &lt;br /&gt;
* To download the latest stable version via HTTP, you can use direct your browse to the URL https://sourceforge.net/projects/fgms/. Download and unzip the source code, and place it in the directory you created above.&lt;br /&gt;
* To download a file directly to your server from an ssh session, you can use git tools with the following command:&lt;br /&gt;
:&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;git clone https://git.code.sf.net/p/fgms/src&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Compiling FGMS ==&lt;br /&gt;
&lt;br /&gt;
For FreeBSD-specific instructions, please see [[Howto:Set up a multiplayer server on FreeBSD]]&lt;br /&gt;
&lt;br /&gt;
NOTE: In general, on any current machine this process should not take longer than about 60 seconds.&lt;br /&gt;
&lt;br /&gt;
* Once you have the source code, 'cd' into the ~/fgms/ directory and note the presence of the CMakeLists.txt file and the README.cmake file. Open the README.cmake file and take a minute to read it over. Also, note the path to the CMakeLists.txt file, as you will need this in the following steps.&lt;br /&gt;
&lt;br /&gt;
* Now create a build-fgms directory in your home directory, and 'cd' into it. From inside the ~/build-fgms/ directory, run the cmake command using the path to the CMakeLists.txt as an argument. For example: cmake /home/&amp;lt;user_name&amp;gt;/fgms/&lt;br /&gt;
&lt;br /&gt;
* Once the build finishes, you can either run the &amp;quot;cmake --build ...&amp;quot; command as shown in the README.cmake file, or you can simply use &amp;quot;make&amp;quot; to build the program.&lt;br /&gt;
&lt;br /&gt;
* Once the compilation process finishes, you need to install the program using &amp;quot;make install&amp;quot; (as user), or you can also install as root.&lt;br /&gt;
&lt;br /&gt;
* Once the program has been installed, you need to copy the fgms_example.conf file from the /fgms/src/server directory, into the build-fgms directory. To do this from inside the /fgms/src/server directory, you can use this command: cp ./fgms_example.conf ~/build-fgms/&lt;br /&gt;
&lt;br /&gt;
* Now 'cd' into the build-fgms directory, and rename the file you just copied as &amp;quot;fgms.conf&amp;quot; so that fgms can find the proper configuration.&lt;br /&gt;
&lt;br /&gt;
== Setting up the config file ==&lt;br /&gt;
&lt;br /&gt;
At this point you should have a working 'fgms' binary in the build-fgms directory. If the server will be offline or for private use (i.e. LAN-only, please comment out the relay servers section. This will save bandwidth from the server being consumed.&lt;br /&gt;
&lt;br /&gt;
* Edit the fgms.conf file according to the instructions found elsewhere on this page, then save and close the file.&lt;br /&gt;
&lt;br /&gt;
{{cquote|As long as you are not absolutly sure what you are doing you should:&lt;br /&gt;
- disable tracking&lt;br /&gt;
- disable HUB setting&amp;lt;ref&amp;gt;{{cite web |url=http://www.mail-archive.com/flightgear-devel@lists.sourceforge.net/msg40454.html|title=&amp;lt;nowiki&amp;gt;Re: [Flightgear-devel] New FlightGear Multiplayer Server&amp;lt;/nowiki&amp;gt;|author=Oliver Schröder|date=Wed, 10 Jul 2013 13:53:55 -0700}}&amp;lt;/ref&amp;gt;|Oliver Schröder}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{cquote|fgms will ignore traffic comming from unknown relays and since the multiplayer network is a star topology you should list only mpserver01&lt;br /&gt;
as your only relay. Currently mpserver01 is the only HUB, Although multiple HUBs should work I have not tested a multi HUB environment yet.&lt;br /&gt;
And for those interrested: Current traffic load on mpserver01 is around 10 MBit/s&amp;lt;ref&amp;gt;{{cite web |url=http://www.mail-archive.com/flightgear-devel@lists.sourceforge.net/msg40454.html|title=&amp;lt;nowiki&amp;gt;Re: [Flightgear-devel] New FlightGear Multiplayer Server&amp;lt;/nowiki&amp;gt;|author=Oliver Schröder|date=Wed, 10 Jul 2013 13:53:55 -0700}}&amp;lt;/ref&amp;gt;|Oliver Schröder}}&lt;br /&gt;
&lt;br /&gt;
{{cquote|your fgms.conf should look like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# basic setting&lt;br /&gt;
server.name = mpserver02&lt;br /&gt;
server.port = 5000&lt;br /&gt;
&lt;br /&gt;
# you can telnet to this port with this username/password&lt;br /&gt;
# and see statistics (nice cisco like CLI)&lt;br /&gt;
server.admin_port = 6002&lt;br /&gt;
server.admin_user = fred&lt;br /&gt;
server.admin_pass = fred&lt;br /&gt;
&lt;br /&gt;
server.admin_enable = fred&lt;br /&gt;
&lt;br /&gt;
# mpserver01 does this&lt;br /&gt;
server.tracked = false&lt;br /&gt;
&lt;br /&gt;
# mpserver01 is hub&lt;br /&gt;
server.is_hub = false&amp;lt;/pre&amp;gt;&amp;lt;ref&amp;gt;{{cite web |url=http://www.mail-archive.com/flightgear-devel@lists.sourceforge.net/msg40454.html|title=&amp;lt;nowiki&amp;gt;Re: [Flightgear-devel] New FlightGear Multiplayer Server&amp;lt;/nowiki&amp;gt;|author=Oliver Schröder|date=Wed, 10 Jul 2013 13:53:55 -0700}}&amp;lt;/ref&amp;gt;|Oliver Schröder}}&lt;br /&gt;
&lt;br /&gt;
{{cquote|&amp;lt;pre&amp;gt;# don't set this too high&lt;br /&gt;
server.out_of_reach = 100&lt;br /&gt;
&lt;br /&gt;
# your only relay should be mpserver01&lt;br /&gt;
relay.host = mpserver01.flightgear.org&lt;br /&gt;
relay.port = 5000&lt;br /&gt;
&lt;br /&gt;
# you don't need a crossfeed, it's only interresting for fgms-developers&lt;br /&gt;
# crossfeed.host = foo.example.com&lt;br /&gt;
# crossfeed.port = 5002&lt;br /&gt;
&lt;br /&gt;
# you can add static entries of IPs which get blocked,&lt;br /&gt;
# but it's generally not needed and you can add them via&lt;br /&gt;
# the admin CLI&lt;br /&gt;
# blacklist = 123.123.123.123&amp;lt;/pre&amp;gt;&amp;lt;ref&amp;gt;{{cite web |url=http://www.mail-archive.com/flightgear-devel@lists.sourceforge.net/msg40454.html|title=&amp;lt;nowiki&amp;gt;Re: [Flightgear-devel] New FlightGear Multiplayer Server&amp;lt;/nowiki&amp;gt;|author=Oliver Schröder|date=Wed, 10 Jul 2013 13:53:55 -0700}}&amp;lt;/ref&amp;gt;|Oliver Schröder}}&lt;br /&gt;
&lt;br /&gt;
== Running FGMS for the first time ==&lt;br /&gt;
&lt;br /&gt;
In addition to its configuration file, FGMS supports a number of configuration parameters that can be passed at startup (and that will by default override any configuration file settings), to get a summary of supported parameters, you may want to run:&lt;br /&gt;
 $ ./fgms --help&lt;br /&gt;
&lt;br /&gt;
Which should present you with the following output:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
options are:&lt;br /&gt;
-h            print this help screen&lt;br /&gt;
-a PORT       listen to PORT for telnet&lt;br /&gt;
-c config     read 'config' as configuration file&lt;br /&gt;
-p PORT       listen to PORT&lt;br /&gt;
-t TTL        Time a client is active while not sending packets&lt;br /&gt;
-o OOR        nautical miles two players must be apart to be out of reach&lt;br /&gt;
-l LOGFILE    Log to LOGFILE&lt;br /&gt;
-v LEVEL      verbosity (loglevel) in range 1 (few) and 5 (much)&lt;br /&gt;
-d            do _not_ run as a daemon (stay in foreground)&lt;br /&gt;
-D            do run as a daemon&lt;br /&gt;
&lt;br /&gt;
the default is to run as a daemon, which can be overridden in the&lt;br /&gt;
config file.&lt;br /&gt;
commandline parameters always override config file options&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After having finished the fgms configuration, you can try running fgms and start up fgfs to use the new server.&lt;br /&gt;
=== Public Server ===&lt;br /&gt;
If you'd like to make it a public server, you can simply use your external (public) IP address to set up the multiplayer in fgfs.&lt;br /&gt;
&lt;br /&gt;
For others to know about your public server you should notify the developers of the existence of your server by posting a message to the [[Mailing list|developers mailing list]].&lt;br /&gt;
&lt;br /&gt;
Add your server to this list: http://wiki.flightgear.org/Howto:Multiplayer#Servers&lt;br /&gt;
&lt;br /&gt;
== Related content ==&lt;br /&gt;
* [http://fgms.freeflightsim.org/ Website: fgms.freeflightsim.org]&lt;br /&gt;
* [[Howto: Multiplayer|Multiplayer howto]]&lt;br /&gt;
* [[MPmap]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Howto]]&lt;br /&gt;
[[Category:Multiplayer]]&lt;br /&gt;
&lt;br /&gt;
[[fr:Installer un serveur multijoueur]]&lt;/div&gt;</summary>
		<author><name>Elgaton</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Howto:Translate_FlightGear&amp;diff=108653</id>
		<title>Howto:Translate FlightGear</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Howto:Translate_FlightGear&amp;diff=108653"/>
		<updated>2017-06-28T22:08:04Z</updated>

		<summary type="html">&lt;p&gt;Elgaton: Add shortcut file and man pages translation instructions&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;FlightGear supports localization, that is, showing the user interface in the user's native language rather than in English. At the time of writing (June 2017), not all parts of the simulator are localized, but efforts are underway to make it so.&lt;br /&gt;
&lt;br /&gt;
This page will help you translate FlightGear to a new language or improve the existing translations.&lt;br /&gt;
&lt;br /&gt;
== What can be translated ==&lt;br /&gt;
The following parts of the simulator can be translated:&lt;br /&gt;
* the menus, splash screens, startup tips and the text shown when the &amp;lt;code&amp;gt;--help&amp;lt;/code&amp;gt; command-line option is used (FlightGear 2.7.0 and later);&lt;br /&gt;
* the shortcut file on Linux systems (FlightGear 2017.1 and later);&lt;br /&gt;
* the man pages (FlightGear 2017.3 and later).&lt;br /&gt;
&lt;br /&gt;
== How to translate the interface ==&lt;br /&gt;
# Determine the two letter ISO 639-1 language code for the language you want to translate FlightGear to. A list can be found on the [https://www.loc.gov/standards/iso639-2/php/code_list.php Library of Congress Web site].&lt;br /&gt;
# Check whether your language already has a subdirectory below [{{fgdata url|path=Translations}} the Translations directory]. If it does not, create an empty directory in it named after the language code, then [{{fgdata url|path=Translations/en}} download the latest English resources] and copy the files to the directory of your language.&lt;br /&gt;
# Open the XML files in the subdirectory of your language and translate the English strings in them. Do not translate the filenames and do not change the order, structure or indentation of the XML files (this helps with future maintenance when the language resources need to be updated for another FlightGear version).&lt;br /&gt;
# Start FlightGear to test your translation. By default, the simulator will select the locale of your operating system as the language to use; you can explicitly select a language using the command-line option &amp;lt;code&amp;gt;--language=&amp;lt;i&amp;gt;language code&amp;lt;/i&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Note that the user interface might have not full Unicode support (some special/accented characters might not be shown): should you encounter such a location, please write to the flightgear-devel mailing list at {{Mailing list e-mail address|flightgear-devel}}.&lt;br /&gt;
&lt;br /&gt;
== How to translate the shortcut file ==&lt;br /&gt;
Open [{{flightgear url|path=package/org.flightgear.FlightGear.desktop}} the FlightGear &amp;lt;code&amp;gt;.desktop&amp;lt;/code&amp;gt; file] and translate the ''GenericName'', ''Comment'' and ''Keywords'' keys (add the ''GenericName[xx]'', ''Comment[xx]'' and ''Keywords[xx]'' keys, where ''xx'' is the two letter ISO 639-1 code of the language).&lt;br /&gt;
&lt;br /&gt;
== How to translate the man pages ==&lt;br /&gt;
# Determine the two letter ISO 639-1 language code for the language you want to translate the man pages to.&lt;br /&gt;
# Check whether your language already has a subdirectory below [{{flightgear url|path=man}} the man pages directory]. If it does not, create an empty directory in it named after the language code, then copy &amp;lt;code&amp;gt;man1&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;man5&amp;lt;/code&amp;gt; from the man pages directory to the directory of your language.&lt;br /&gt;
# Edit [{{flightgear url|path=man/CMakeLists.txt}} man/CMakeLists.txt] and add the instruction &amp;lt;code&amp;gt;add_subdirectory(xx)&amp;lt;/code&amp;gt; in the &amp;lt;code&amp;gt;if(NOT WIN32)&amp;lt;/code&amp;gt; block (where ''xx'' is the language code).&lt;br /&gt;
# Edit &amp;lt;code&amp;gt;man/xx/man1/CMakeLists.txt&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;man/xx/man5/CMakeLists.txt&amp;lt;/code&amp;gt;: on the last row, set the installation directory (&amp;lt;code&amp;gt;DESTINATION&amp;lt;/code&amp;gt;), respectively, to &amp;lt;code&amp;gt;${CMAKE_INSTALL_MANDIR}/xx/man1&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;${CMAKE_INSTALL_MANDIR}/xx/man5&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Open the man pages in the subdirectory of your language and translate them.&lt;br /&gt;
&lt;br /&gt;
== Related content ==&lt;br /&gt;
* [[Howto: Translate FlightGear Launch Control‎‎]]&lt;br /&gt;
* [[Translation requests]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Howto|Translate FlightGear]]&lt;/div&gt;</summary>
		<author><name>Elgaton</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Mumble&amp;diff=100675</id>
		<title>Mumble</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Mumble&amp;diff=100675"/>
		<updated>2016-06-29T07:08:34Z</updated>

		<summary type="html">&lt;p&gt;Elgaton: Remove empty section for now&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox Software&lt;br /&gt;
| title               = Mumble&lt;br /&gt;
| logo                = &lt;br /&gt;
| image               = &lt;br /&gt;
| alt                 = &lt;br /&gt;
| developedby         = Various&lt;br /&gt;
| initialrelease      = 2005&lt;br /&gt;
| latestrelease       = 1.2.16 (stable)&lt;br /&gt;
| writtenin           = C++&lt;br /&gt;
| os                  = Windows, OS X, Linux, Android, iOS&lt;br /&gt;
| platform            = PC, Mac, smartphones&lt;br /&gt;
| developmentstatus   = &lt;br /&gt;
| developmentprogress = &lt;br /&gt;
| type                = Voice chat software&lt;br /&gt;
| license             = [https://github.com/mumble-voip/mumble/blob/master/LICENSE Open source]&lt;br /&gt;
| website             = http://wiki.mumble.info/wiki/Main_Page&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
'''Mumble''' is a free, open source VoIP software used by some ATCs and pilots on the multiplayer network.&lt;br /&gt;
&lt;br /&gt;
== Installation and configuration ==&lt;br /&gt;
# Download Mumble from its [http://wiki.mumble.info/wiki/Main_Page official website] (choose the links from the ''Stable Release'' column). If you're on Linux, you can usually install it using your package manager.&lt;br /&gt;
# Start it and follow the instructions on your screen to configure the program.&lt;br /&gt;
{{tip|We suggest to choose the '''Push-To-Talk''' mode in the '''Voice Activity Detection''' step; if you choose another mode, make sure to calibrate the volume levels correctly (follow the on-screen instructions carefully). This way, your voice will be transmitted only when you mean to, and there will be less background noise on the channel.}}&lt;br /&gt;
&lt;br /&gt;
== Connecting ==&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Click on {{Menu item|Server|Connect}}.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;If this is the first time you connect to the FlightGear Mumble server, click on {{button|Add New...}} at the bottom of the window and input the following parameters, then click {{button|OK}}:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Label'''&lt;br /&gt;
| &amp;lt;tt&amp;gt;FlightGear ATC&amp;lt;/tt&amp;gt; (or another descriptive name of your choice)&lt;br /&gt;
|-&lt;br /&gt;
| '''Address'''&lt;br /&gt;
| &amp;lt;tt&amp;gt;mumble.allfex.org&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| '''Port'''&lt;br /&gt;
| &amp;lt;tt&amp;gt;64738&amp;lt;/tt&amp;gt; (the default value)&lt;br /&gt;
|-&lt;br /&gt;
| '''Username'''&lt;br /&gt;
| A username (callsign) of your choice&lt;br /&gt;
|}&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Select '''FlightGear ATC''' from the server list and click {{button|Connect}}.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
====Other Flighgear Related Servers====&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Click on '''Server'''-&amp;gt;'''Connect'''.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Click on '''Add New...''' at the bottom of the window and input the following parameters, then click '''OK''':&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''Label'''&lt;br /&gt;
| &amp;lt;tt&amp;gt;Alternate FlightGear Server&amp;lt;/tt&amp;gt; (or another descriptive name of your choice)&lt;br /&gt;
|-&lt;br /&gt;
| '''Address'''&lt;br /&gt;
| &amp;lt;tt&amp;gt;mumble-us.cleanvoice.com&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| '''Port'''&lt;br /&gt;
| &amp;lt;tt&amp;gt;39506&amp;lt;/tt&amp;gt; (You must change it)&lt;br /&gt;
|-&lt;br /&gt;
| '''Username'''&lt;br /&gt;
| A username (callsign) of your choice&lt;br /&gt;
|}&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Select '''Alternate FlightGear Server''' or whatever you chose from the server list and click '''Connect'''.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Using Mumble ==&lt;br /&gt;
When you are connected, Mumble will show a hierarchical list of channels on the right side of the main window.&lt;br /&gt;
* To enter an existing channel, right click on it and choose {{Menu item|Join Channel}}.&lt;br /&gt;
* To create a new channel (e.g. if you're acting as a controller), right click on the ''FlightGear'' channel and choose {{Menu item|Add}}. Input a name and (optionally) a description, then click {{button|OK}}.&lt;br /&gt;
{{note|The new channel is temporary and will be deleted when the last person in it exits the channel.}}&lt;br /&gt;
* To mute yourself, click the {{button|Mute}} button in the main toolbar.&lt;br /&gt;
&lt;br /&gt;
== OpenRadar flickering when using Mumble ==&lt;br /&gt;
If you're using Mumble and OpenRadar at the same time, you might notice that the OpenRadar screen flickers. A solution is disabling the Mumble overlay (in Mumble, click on {{Menu item|Configure|Settings}}, open the '''Overlay''' section, deselect '''Enable Overlay''' and click {{button|OK}}).&lt;br /&gt;
&lt;br /&gt;
[[Category:Air Traffic Control]]&lt;br /&gt;
[[Category:Software]]&lt;/div&gt;</summary>
		<author><name>Elgaton</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=FlightGear_Newsletter_June_2016&amp;diff=100024</id>
		<title>FlightGear Newsletter June 2016</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=FlightGear_Newsletter_June_2016&amp;diff=100024"/>
		<updated>2016-06-19T09:29:30Z</updated>

		<summary type="html">&lt;p&gt;Elgaton: Use the Appendix template for references&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{draft|newsletter|Please feel free to add content that you think will be of interest to the FlightGear community.&amp;lt;br&amp;gt;You can read the latest newsletter at [[FlightGear Newsletter May 2016]].}}&lt;br /&gt;
&lt;br /&gt;
{{Newsletter-header|June 2016}}&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-bottom:3px double #BBB;&amp;quot;&amp;gt;&lt;br /&gt;
{| width=&amp;quot;100%&amp;quot; |&lt;br /&gt;
 | valign=&amp;quot;top&amp;quot; width=&amp;quot;33%&amp;quot; |&lt;br /&gt;
{{Newsletter-cover-header|Development news}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{Newsletter-cover-header|In the hangar}}&amp;lt;br&amp;gt;&lt;br /&gt;
[[#Aucafly T1|Aucafly T1]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[#GTA V Washington|GTA V Washington]]&amp;lt;br&amp;gt;&lt;br /&gt;
 | valign=&amp;quot;top&amp;quot; width=&amp;quot;33%&amp;quot; |&lt;br /&gt;
{{Newsletter-cover-header|Scenery Corner}}&amp;lt;br&amp;gt;&lt;br /&gt;
{{Newsletter-cover-header|Community News}}&amp;lt;br&amp;gt;&lt;br /&gt;
 | valign=&amp;quot;top&amp;quot; width=&amp;quot;33%&amp;quot; |&lt;br /&gt;
{{Newsletter-cover-header|Contributing}}&amp;lt;br&amp;gt;&lt;br /&gt;
[[#Translators required|Translators required]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[#FlightGear logos|FlightGear logos]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[#Screenshots|Screenshots]]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;small&amp;gt;[[#Screenshot of the Month|Screenshot of the Month]]&amp;lt;/small&amp;gt;&lt;br /&gt;
|}&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Development news ==&lt;br /&gt;
&lt;br /&gt;
== In the hangar ==&lt;br /&gt;
=== Aucafly T1 ===&lt;br /&gt;
[[Aucafly T1]] has been released.  It can be found in {{github source|proj=aucafly|repo=AUCAFLYT1|text=GitHub}}.  See also the [https://aucafly.wordpress.com official website].&lt;br /&gt;
=== GTA V Washington ===&lt;br /&gt;
[[GTA V Washington]] has been released.  It can be found in {{github source|proj=aucafly|repo=GTAWAS|text=GitHub}}.  See also the [https://aucafly.wordpress.com official website].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery mode=&amp;quot;packed&amp;quot;&amp;gt;&lt;br /&gt;
Aucafly_T1.png|[[Aucafly T1]]&lt;br /&gt;
GTA_V_Washington.jpg|GTA V Washington&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Scenery corner ==&lt;br /&gt;
As part of the new release, there's an opportunity for us to include some carrier aviation if we wanted to. The Marinha do Brasil (Brazilian Navy) operates the aircraft carrier São Paulo, which happens to have previously been the French aircraft carrier Foch, which we have a working model for. They also happen to operate Douglas AF-1 Skyhawks (aka [[Douglas A-4 Skyhawk|A4 Skyhawk]]), which we also have, albeit not in the appropriate livery and not quite up to date avionics. If anyone is interested in doing so, it might be a nice enhancement to include an AI scenario with the Foch off the coast of Rio, and include livery support on the A4 to match the Marinha do Brasil. As Brazil is one of the few countries operating CATOBAR aircraft carriers, it seems a fine opportunity to add an additional international flavour to the sim for the upcoming release.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://sourceforge.net/p/flightgear/mailman/message/35147566/ &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; [Flightgear-devel] Naval aviation in Brazil &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; Stuart Buchanan &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  Jun 9th, 2016 &lt;br /&gt;
  |added  =  Jun 9th, 2016 &lt;br /&gt;
  |script_version = 0.40 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
===Canary Islands===&lt;br /&gt;
[https://forum.flightgear.org/viewtopic.php?f=5&amp;amp;t=29773 Some work] in the Canary Islands, in [[Custom Spain and Portugal Scenery|Spain]]; dedicated textures for sandy and arid landscapes, airport buildings and structures (GXCO, GCLA, GCGM, GCHI, GCLB and others), shared objects (canary houses and hotel) and airport layout regeneration by [[User:D-ECHO|D-ECHO]] and [[User:Catalanoic|Catalanoic]].&lt;br /&gt;
&lt;br /&gt;
== Community news ==&lt;br /&gt;
&lt;br /&gt;
== Contributing ==&lt;br /&gt;
=== Translators required ===&lt;br /&gt;
{|&lt;br /&gt;
| [[File:en.gif]]&lt;br /&gt;
| The FlightGear Wiki still needs help for translating it into various languages. If you are interested in making the FlightGear Wiki multilingual, you can start by looking at [[Help:Translate]].&lt;br /&gt;
|-&lt;br /&gt;
| [[File:fr.gif]]&lt;br /&gt;
| Le wiki de FlightGear a toujours besoin d'aide pour être traduit en différentes langues. Si vous êtes intéressé par le rendre multilingue, commencez par lire [[:fr:Help:Traduire|Help:Traduire]].&lt;br /&gt;
|-&lt;br /&gt;
| [[File:de.gif]]&lt;br /&gt;
| Das FlightGear Wiki braucht noch Hilfe für sie in verschiedene Sprachen zu übersetzen. Wenn Sie bei der Herstellung der FlightGear Wiki mehrsprachiger interessiert sind, können Sie, indem Sie auf [[:de:Help:Übersetzen|Help:Übersetzen]] beginnen.&lt;br /&gt;
|-&lt;br /&gt;
| [[File:nl.gif]]&lt;br /&gt;
| De FlightGear Wiki kan nog steed hulp gebruiken bij het vertalen van artikelen. Als je interesse hebt om de wiki meertalig te maken, raden we je aan om een kijkje te nemen bij [[:nl:Help:Vertalen|Help:Vertalen]].&lt;br /&gt;
|-&lt;br /&gt;
| [[File:es.gif]]&lt;br /&gt;
| La wiki de FlightGear todavía necesita ayuda para traducirla a varios lenguajes. Si estás interesado en hacer la FlightGear wiki multilingüe, entonces comienza en [[:es:Help:Traducir|Help:Traducir]].&lt;br /&gt;
|-&lt;br /&gt;
| [[File:cat.gif]]&lt;br /&gt;
| La wiki de FlightGear encara necessita ajuda per traduir-la a diverses llengües. Si esteu interessat en fer la wiki de FlightGear multilingüe, llavors comenceu a [[:ca:Help:Traduir|Help:Traduir]].&lt;br /&gt;
|-&lt;br /&gt;
| [[File:pt.gif]]&lt;br /&gt;
| A wiki de FlightGear ainda necessita de ajuda para traduzi-la em vários idiomas. Se estás interessado em tornar a wiki de FlightGear multi-lingual, por favor começa em [[:pt:Help:Traduzir|Help:Traduzir]].&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== FlightGear logos ===&lt;br /&gt;
If you want some graphic elements for your FlightGear-related site (such as a hangar or YouTube channel), please feel free to visit [[FlightGear logos]] for a repository of logos. And if you have some art skills, please don't hesitate to contribute with your own design creations.&lt;br /&gt;
&lt;br /&gt;
=== Screenshots ===&lt;br /&gt;
The FlightGear project always needs screenshots, which show features that were added since the last release. These should be of good quality, especially in content and technical image properties. It is therefore recommended to use the best viable filter settings ([[anti-aliasing]], texture sharpening, etc.). More info at [[Howto:Make nice screenshots]].&lt;br /&gt;
&lt;br /&gt;
==== Screenshot of the Month ====&lt;br /&gt;
Entries for this month's best screenshot can be submitted to [https://forum.flightgear.org/viewtopic.php?f=19&amp;amp;t=29720 this] forum topic. Be sure to see the [https://forum.flightgear.org/viewtopic.php?f=19&amp;amp;t=29720#p287514 first post] for participation rules. For purposes of convenience and organization, after all the entries have been submitted, a new forum topic will be started containing all shots in an easy-to-view layout. The voting will then take place there. Once the voting has finished, the best screenshot will be presented on this page.&lt;br /&gt;
&lt;br /&gt;
{{Appendix}}&lt;br /&gt;
&lt;br /&gt;
[[Category:FlightGear Newsletter|2016 06]]&lt;br /&gt;
[[Category:Changes after 2016.2]]&lt;br /&gt;
&lt;br /&gt;
[[de:FlightGear Newsletter Juni 2016]]&lt;/div&gt;</summary>
		<author><name>Elgaton</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=FlightGear_wiki:Village_pump&amp;diff=99117</id>
		<title>FlightGear wiki:Village pump</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=FlightGear_wiki:Village_pump&amp;diff=99117"/>
		<updated>2016-06-02T08:41:01Z</updated>

		<summary type="html">&lt;p&gt;Elgaton: /* Categorizing aircraft infoboxes by hangar */ Feedback&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Archives|[[/Archive 2012|2012]]|[[/Archive 2013|2013]]|[[/Archive 2014|2014]]|[[/Archive 2015|2015]]}}&lt;br /&gt;
{{shortcut|FGW:VP}}&lt;br /&gt;
Welcome to the '''Village Pump'''. This page is used to discuss the technical issues, operations and guidelines of the [[FlightGear wiki]].&lt;br /&gt;
&lt;br /&gt;
Please &amp;lt;span class=&amp;quot;plainlinks&amp;quot;&amp;gt;[{{fullurl:{{FULLPAGENAME}}|action=edit&amp;amp;section=new}} add new topics]&amp;lt;/span&amp;gt; to the '''bottom''' of this page.&lt;br /&gt;
&lt;br /&gt;
Old discussion should be moved to a [[FlightGear wiki:Village pump/Archive YEAR]]. These discussions can then be moved to a relevant talk page if appropriate.&lt;br /&gt;
&lt;br /&gt;
== Welcome template? ==&lt;br /&gt;
I have been thinking about suggesting a welcome template, for example named {{obr}}welcome{{cbr}}, to place on top of (at least) new users user discussion pages.&lt;br /&gt;
&lt;br /&gt;
It should welcome the (new) user&lt;br /&gt;
&lt;br /&gt;
In addition, it should probably mention and/or link to pages mentioning:&lt;br /&gt;
* The introduction page/tutorial (Hmm, I do not think I did finish that one. See [[Help talk:Tutorial]] ([http://wiki.flightgear.org/index.php?title=Help_talk:Tutorial&amp;amp;oldid=70843 perm])).&lt;br /&gt;
* Help pages&lt;br /&gt;
* How to use categories (in particular not like #tags, ;-) but also that image and article categories should be separate, but link to each other)&lt;br /&gt;
* The portals&lt;br /&gt;
* The style manual&lt;br /&gt;
* Discussion pages and where to discuss what:&lt;br /&gt;
** How to use discussion pages&lt;br /&gt;
** The wiki in general:  The village pump (this page)&lt;br /&gt;
** Wiki articles:  Article discussion pages&lt;br /&gt;
** Wiki user actions:  User discussion pages&lt;br /&gt;
&lt;br /&gt;
Maybe it should also mention that FGAddon aircraft, effects, other features etc. (except for their articles) and their bugs should be discussed on the forum, unless developers say otherwise, and that core features should be discussed on the developer mailing list and core bugs on the bug tracker.&lt;br /&gt;
&lt;br /&gt;
—[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 20:31, 30 January 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
: I think this is a great idea.  A nice concise summary with links to help a new user navigate the FlightGear jungle would be a great addition.  It should however remain very short with simple sentences - while being complete - as many users are not native speakers.  So maybe there should be translations of the template with manually added links at the bottom for easy access to all the translations?&lt;br /&gt;
&lt;br /&gt;
: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 03:35, 12 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: Regarding an introduction article, I have come to the conclusion that a complete but long article is probably not as helpful as short but specific help pages.  In essence the latter would be easier to navigate and absorb.  I have therefore started to slowly split up some of the help pages and have added one more section to [[Help:Contents]].&lt;br /&gt;
:: I think that a welcome phrase, a link to that page and the [[FlightGear wiki:Manual of Style|style manual]] might actually suffice for a welcome template for now.  It is at least better than what we currently have (i.e. more or less nothing).&lt;br /&gt;
:: —[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 14:47, 4 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: I now consider&lt;br /&gt;
::* A Welcome message&lt;br /&gt;
::* A link to this page&lt;br /&gt;
::* A link to the help pages&lt;br /&gt;
::* A link to the manual of style&lt;br /&gt;
::* Some final welcoming words&lt;br /&gt;
&lt;br /&gt;
:: A welcome template should probably also very briefly mention a pet peeve of mine: the categories.&lt;br /&gt;
:: Many (if not most) image uploaders seem to treat them like tags, but if say all screenshots of aircraft (probably &amp;gt;2000) would end up at [[:Category:Aircraft]] (instead of under a subcategory to [[:Category:Screenshots of aircraft]]), of what use would that page be when looking for a specific one?  If people would like to be able to search for an aircraft, a concise but comprehensive image description is very hard to beat.&lt;br /&gt;
:: How do I convey all that in a way that is, short, to the point and easy to absorb (and act by)? And where is the best place?&lt;br /&gt;
:: —[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 02:46, 8 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: An early draft is now at [[User:Johan G/Template:Welcome to the wiki]]&lt;br /&gt;
:: —[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 02:52, 18 April 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
::: Some comments on the draft:&lt;br /&gt;
::: * I'm not fully sure about using a prominent box - I think it stands out a bit too much. Wikipedia {{wikipedia|Template:Welcome|uses a simple thread on the Talk page}}; as an alternative, we could use lighter colors.&lt;br /&gt;
::: * I've also expanded the text a bit. My proposal would be (I've put it in a box, but I'm for the &amp;quot;thread&amp;quot; solution):&lt;br /&gt;
&amp;lt;div style=&amp;quot;background: #fff; border: 1px #585858 solid; padding: 12px; margin: 12px&amp;quot;&amp;gt;&lt;br /&gt;
[[Image:Example.png|left]] '''Welcome to the FlightGear wiki, {{#if: {{{name|}}} | {{{name}}} | {{BASEPAGENAME}}}}'''! We hope you will enjoy your stay!&lt;br /&gt;
&lt;br /&gt;
See [[Help:Contents#Reading|Reading]] to learn how wikis work. You can also [[Special:CategoryTree/Root category|browse the existing page categories]].&lt;br /&gt;
&lt;br /&gt;
Should you wish to create or edit some articles, ''do so''! Here are some resources to get you started:&lt;br /&gt;
* [[Help:Contents#Editing|How to edit pages]]&lt;br /&gt;
* [[Help:Discussion pages|Discussion pages]], where we discuss and agree on potential improvements&lt;br /&gt;
* [[FlightGear wiki:Manual of Style|The Manual of Style]], a set of guidelines to help editors maintain a consistent style and formatting (please follow them)&lt;br /&gt;
* [[Help:Contents|Wiki help page]]&lt;br /&gt;
&lt;br /&gt;
If you have any questions, just start a topic on the [[FlightGear wiki:Village pump|''Discuss!'' page]]. Again, welcome!&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
::: ...where the image on the left is an appropriately chosen icon.&lt;br /&gt;
::: Finally, we could use the {{mediawiki|Extension:NewUserMessage|NewUserMessage extension}} to have the wiki software automatically post the message to the new user's talk page.&lt;br /&gt;
::: ---- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 17:30, 1 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Permanently removing spam bots ==&lt;br /&gt;
For permanently removing spam bots, has the [https://www.mediawiki.org/wiki/Extension:UserMerge UserMerge] Mediawiki extension been considered?  I use that regularly on [http://wiki.nmr-relax.com my own wiki], though there we have also reverted to communicating to the person via email before manually granting access (probably not an option here), as all of the Mediawiki captcha methods were recently cracked.&lt;br /&gt;
&lt;br /&gt;
[[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 03:15, 12 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
: Oh, for the extension, we simply have a user called 'Spam bot' in a blocked state, and merge the spam bot accounts into this one, deleting the old account.&lt;br /&gt;
: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 03:20, 12 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: I'd use the [https://www.mediawiki.org/wiki/Extension:AbuseFilter abuse filter extension] instead (much more powerful and automated) - other users have also proposed different remedies, see [http://forum.flightgear.org/viewtopic.php?f=42&amp;amp;t=28734 this forum thread]. Anyway, Gijs is going to upgrade MediaWiki shortly and review the current anti-spam measures.&lt;br /&gt;
:: -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 06:26, 13 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
::: A lot of the spam bots are using their name as advertising nowadays, so the [https://www.mediawiki.org/wiki/Extension:UserMerge UserMerge] extension is the only one I know which will allow a user and associated name to be permanently deleted.&lt;br /&gt;
&lt;br /&gt;
::: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 12:04, 14 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:::: The problem now is that they're also adding the information to the page title, so that it will still show up in the deletion logs [http://wiki.flightgear.org/Special:Log/delete] in other words, there's still some SEO juice associated with deleted entries ... Another idea would be to allow admins to temporarily disable wiki registrations/article creation, e.g. if more than 2 admins agree, this could be done to protect the wiki from spam attacks.&lt;br /&gt;
&lt;br /&gt;
::::: Hooray, you should sign your posts ;)  The bots don't target the deletion logs, as that's a little pointless.  It's a Special:* page, and the default Mediawiki robots.txt file tells all search engines to not index these pages.  User pages, page histories, etc. are however normally indexed.&lt;br /&gt;
&lt;br /&gt;
::::: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 14:36, 19 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: The point was not what the bots are targeting, but what shows up in the logs - i.e. SEO-wise - Gijs' article blacklist stuff should help with that hopefully. PS: I could not find the signature button on the mobile device I am using, and I am not too good at remembering the correct number of tildes ;-) [[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 15:04, 19 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
== WIP vs. Under construction ==&lt;br /&gt;
I have been beginning to miss the under construction template[http://wiki.flightgear.org/index.php?title=Template:Under_Construction&amp;amp;direction=prev&amp;amp;oldid=46229] more and more (though I could it definitively could be improved).&lt;br /&gt;
&lt;br /&gt;
I have begun to appreciate the need to differentiate between letting readers that a page is to be considered a yet to be finished construction site (though we in a way have that through the {{tl|incomplete}} template) and letting the reader (and other editors) that a page will receive a large amount of work for some hours or even days, usually the use for {{tl|WIP}}.&lt;br /&gt;
&lt;br /&gt;
In summary i miss templates giving a clear distinction between conditions akin to &amp;quot;Under construction&amp;quot; and &amp;quot;Caution - Wet floors&amp;quot;, rather than &amp;quot;being worked on&amp;quot; and &amp;quot;could need more work&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
—[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 10:11, 17 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
== [[Fr/Pilote automatique]] ==&lt;br /&gt;
Bonjour,&lt;br /&gt;
&lt;br /&gt;
Je viens de créer la page de traduction en français de l'article original en anglais [[Autopilot]]. Vu mes faibles compétences en matière de pilotage, vu que je n'ai pas sur ma version téléchargée d'avion avec un pilote automatique, la traduction doit souffrir quelques approximations, si ce n'est des contresens plus ennuyeux. Si quelques bonnes âmes plus qualifiées pouvaient me faire la grâce d'une relecture... merci d'avance.&lt;br /&gt;
&lt;br /&gt;
Cordialement, et Hop ! --[[User:F-WTSS|F-WTSS]] ([[User talk:F-WTSS|talk]]) 15:30, 18 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
== MediaWiki updated to 1.26.2 ==&lt;br /&gt;
I've updated MediaWiki to the latest stable release (1.26.2) today. I've still got to update some of the extensions, so there may be regressions for now. Please report bugs if you find any. For a list of changes, see https://www.mediawiki.org/wiki/Release_notes/1.26&lt;br /&gt;
&lt;br /&gt;
[[User:Gijs|Gijs]] ([[User talk:Gijs|talk]]) 10:47, 19 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
: Cheers!  I was hoping that it would solve the uneditable Chinese, Russian, and other non-latin character-based pages (Polish strangely as well), but unfortunately [[FlightGear_wiki:Village_pump/Archive_2015#UTF-8_language_pages_cannot_be_edited|that issue remains]].&lt;br /&gt;
&lt;br /&gt;
: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 10:54, 19 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: Hm, looks that will require quite some attention indeed. I'm afraid that'll has to wait for now.&lt;br /&gt;
:: [[User:Gijs|Gijs]] ([[User talk:Gijs|talk]]) 12:29, 19 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
=== Nasal Syntaxhighlighting ===&lt;br /&gt;
: Thanks for your efforts, btw: Nasal syntax highlighting is gone again.&lt;br /&gt;
: {{unsigned|17:22, 19 February 2016‎|Hooray}}&lt;br /&gt;
&lt;br /&gt;
:: Unfortunately this time it isn't me forgetting to copy a file. The SyntaxHighlight extension no longer uses GeSHi, but has switched to Pygments. This means our Nasal mapping no longer works and has to be re-written. If anyone is interested, be my guest. See http://pygments.org/docs/lexerdevelopment/&lt;br /&gt;
:: [[User:Gijs|Gijs]] ([[User talk:Gijs|talk]]) 12:29, 19 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
::: Hi Gijs,&lt;br /&gt;
::: I'm interested in making a Pygments Nasal lexer, but unfortunately I won't be able to work on it until the end of March at the earliest.&lt;br /&gt;
::: [[User:Red_Leader|&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;'''''Red Leader'''''&amp;lt;/span&amp;gt;]] ([[User_talk:Red_Leader|Talk]], [[Special:Contributions/Red_Leader|contribs]]) 16:59, 23 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:::: Unless Gijs is facing any problems, I don't think it's necessarily needed, see my comment/suggestion in this revision: [http://wiki.flightgear.org/index.php?title=FlightGear_wiki:Village_pump&amp;amp;oldid=93166] [[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 17:20, 23 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:::Hi Gijs,&lt;br /&gt;
:::Here's the code for a Nasal lexer. Be warned, it's thoroughly untested, but has the following features:&lt;br /&gt;
:::* Full support for all three string types (backtick, single quote, and double quote), including escapes and formatting strings (e.g., for {{func link|sprintf}}).&lt;br /&gt;
:::* All kinds of numbers, including numbers in scientific notation and octal and hex numbers.&lt;br /&gt;
:::* All global functions and variables as of FG v2016.1.1.&lt;br /&gt;
:::* Some of the commonly-used &amp;lt;code&amp;gt;props.Node&amp;lt;/code&amp;gt; methods.&lt;br /&gt;
:::* All the other things that can be expected (keywords, punctuation, etc.).&lt;br /&gt;
:::I have also created a lexer based on the XML lexer for XML with embedded Nasal, which I thought would be useful.&lt;br /&gt;
:::Regards,&lt;br /&gt;
:::[[User:Red_Leader|&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;'''''Red Leader'''''&amp;lt;/span&amp;gt;]] ([[User_talk:Red_Leader|Talk]], [[Special:Contributions/Red_Leader|contribs]]) 16:35, 2 April 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:::http://pygments.org/docs/lexerdevelopment/#adding-and-testing-a-new-lexer&lt;br /&gt;
:::&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
	Lexer for Nasal.&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
from pygments.lexer import RegexLexer, words, include, inherit, bygroups, using&lt;br /&gt;
from pygments.token import Text, Keyword, Name, String, Number, Operator, Punctuation, Comment&lt;br /&gt;
from pygments.lexers.html import XmlLexer&lt;br /&gt;
&lt;br /&gt;
__all__ = ['NasalLexer', 'XMLNasalLexer']&lt;br /&gt;
&lt;br /&gt;
class NasalLexer(RegexLexer):&lt;br /&gt;
&lt;br /&gt;
	name = 'Nasal'&lt;br /&gt;
	aliases = ['nasal']&lt;br /&gt;
	filenames = ['*.nas']&lt;br /&gt;
&lt;br /&gt;
	tokens = {&lt;br /&gt;
		'formatters': [&lt;br /&gt;
			(r'%[-#0 +]*(?:[0-9]+)?(?:\.[0-9]+)?[dis%couxXeEfFgG]', String.Interpol),&lt;br /&gt;
		],&lt;br /&gt;
		'backtick': [&lt;br /&gt;
			(r'`', String.Backtick, '#pop'),&lt;br /&gt;
			(r'[^`\\]+', String.Backtick),&lt;br /&gt;
			(r'\\n|\\r|\\t|\\`|\\\\|\\x[0-9a-fA-F]{2}', String.Escape),&lt;br /&gt;
		],&lt;br /&gt;
		'sqstring': [&lt;br /&gt;
			(r&amp;quot;'&amp;quot;, String.Single, '#pop'),&lt;br /&gt;
			(r&amp;quot;[^'\\%]+&amp;quot;, String.Single),&lt;br /&gt;
			(r&amp;quot;\\'&amp;quot;, String.Escape),&lt;br /&gt;
			include('formatters'),&lt;br /&gt;
		],&lt;br /&gt;
		'dqstring': [&lt;br /&gt;
			(r'&amp;quot;', String.Double, '#pop'),&lt;br /&gt;
			(r'[^&amp;quot;\\%]+', String.Double),&lt;br /&gt;
			(r'\\n|\\r|\\t|\\&amp;quot;|\\\\|\\x[0-9a-fA-F]{2}', String.Escape),&lt;br /&gt;
			include('formatters'),&lt;br /&gt;
		],&lt;br /&gt;
		'root': [&lt;br /&gt;
			(r'\s+', Text),&lt;br /&gt;
			(r'#.*?$'m, Comment.Single),&lt;br /&gt;
			(r':|\?|[!=&amp;lt;&amp;gt;+\-*\/~&amp;amp;|^]=?', Operator),&lt;br /&gt;
			(words(('or', 'and'), suffix=r'\b'), Operator.Word),&lt;br /&gt;
			(r'[{(\[})\]\.;,]', Punctuation),&lt;br /&gt;
			(words(('for', 'foreach', 'forindex', 'while', 'break', 'return', 'continue', 'if', 'else', 'elsif'), suffix=r'\b'), Keyword),&lt;br /&gt;
			(words(('var', 'func'), suffix=r'\b'), Keyword.Declaration),&lt;br /&gt;
			(words(('nil'), suffix=r'\b'), Keyword.Constant),&lt;br /&gt;
			(words(('me', 'arg'), suffix=r'\b'), Name.Builtin.Pseudo),&lt;br /&gt;
			(words(('new', 'del', 'getNode', 'getParent', 'getChild', 'getChildren', 'removeChild', 'removeChildren', 'removeAllChildren', 'getName', 'getIndex', 'getType', 'getAttribute', 'setAttribute', 'getValue', 'setValue', 'setIntValue', 'setBoolValue', 'setDoubleValue', 'unalias', 'alias', 'getPath', 'getBoolValue', 'remove', 'setValues', 'getValues', 'initNode'), suffix=r'\b'), Keyword.Pseudo),&lt;br /&gt;
			(r'0o[0-7]+', Number.Oct),&lt;br /&gt;
			(r'0x[0-9a-fA-F]+', Number.Hex),&lt;br /&gt;
			(r'\d*(?:\.\d*)?[eE][+-]?\d+', Number.Float),&lt;br /&gt;
			(r'\d*\.\d*', Number.Float),&lt;br /&gt;
			(r'\b[0-9]+\b', Number.Integer),&lt;br /&gt;
			(words(('D2R', 'R2D', 'FT2M', 'M2FT', 'IN2M', 'M2IN', 'NM2M', 'M2NM', 'KT2MPS', 'MPS2KT', 'FPS2KT', 'KT2FPS', 'LB2KG', 'KG2LB', 'GAL2L', 'L2GAL'), suffix=r'\b'), Name.Variable.Global),&lt;br /&gt;
			(words(('abort', 'abs', 'addcommand', 'airportinfo', 'airwaysRoute', 'assert', 'carttogeod', 'cmdarg', 'courseAndDistance', 'createViaTo', 'createDiscontinuity', 'createWP', 'createWPFrom', 'defined', 'directory', 'fgcommand', 'findAirportsByICAO', 'findAirportsWithinRange', 'findFixesByID', 'findNavaidByFrequency', 'findNavaidsByFrequency', 'findNavaidsByID', 'findNavaidsWithinRange', 'finddata', 'flightplan', 'geodinfo', 'geodtocart', 'getprop', 'greatCircleMove', 'interpolate', 'isa', 'logprint', 'magvar', 'maketimer', 'md5', 'navinfo', 'parse_markdown', 'parsexml', 'print', 'printf', 'printlog', 'rand', 'registerFlightPlanDelegate', 'removecommand', 'removelistener', 'resolvepath', 'setlistener', 'setprop', 'settimer', 'srand', 'systime', 'thisfunc', 'tileIndex', 'tilePath', 'values'), suffix=r'\b'), Name.Builtin),&lt;br /&gt;
			(words(('append', 'bind', 'call', 'caller', 'chr', 'closure', 'cmp', 'compile', 'contains', 'delete', 'die', 'find', 'ghosttype', 'id', 'int', 'keys', 'left', 'num', 'pop', 'right', 'setsize', 'size', 'sort', 'split', 'sprintf', 'streq', 'substr', 'subvec', 'typeof'), suffix=r'\b'), Name.Builtin),&lt;br /&gt;
			(words(('_createCondition', '_fgcommand', '_interpolate', '_setlistener'), suffix=r'\b'), Keyword.Reserved),&lt;br /&gt;
			(r'`', String.Backtick, 'backtick'),&lt;br /&gt;
			(r&amp;quot;'&amp;quot;, String.Single, 'sqstring'),&lt;br /&gt;
			(r'&amp;quot;', String.Double 'dqstring'),&lt;br /&gt;
			(r'\b_\w*?\b', Keyword.Reserved),&lt;br /&gt;
			#(r'\b\w*?\b', Name),&lt;br /&gt;
		]&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
class XMLNasalLexer(XmlLexer):&lt;br /&gt;
	&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
	For Nasal code embedded in XML files.&lt;br /&gt;
	&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	name = 'XML-Nasal'&lt;br /&gt;
	aliases = ['xml-nasal', 'xml-ns']&lt;br /&gt;
&lt;br /&gt;
	tokens = {&lt;br /&gt;
		'root': [&lt;br /&gt;
			(r'(&amp;lt;(?:load|unload|script)&amp;gt;)(&amp;lt;!\[CDATA\[)?(.*?)(]]&amp;gt;)?(&amp;lt;/(?:load|unload|script)&amp;gt;)', bygroups(Name.Tag, Comment.Preproc, using(NasalLexer), Comment.Preproc, Name.Tag),&lt;br /&gt;
			inherit,&lt;br /&gt;
		],&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:: We can use the ECMAScript/JavaScript lexer[http://pygments.org/docs/lexers/#lexers-for-javascript-and-related-languages] for now, my suggestion would be to copy that over to a file so that we can work on a custom Nasal lexer (Syntax  is almost identical, with a few different keywords, and many others being irrelevant). What is missing/different can be obtained from other lexers that are similar, e.g. [http://pygments.org/docs/lexers/#lexers-for-other-c-like-languages] [[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 15:45, 19 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: Okay, here's the better/quick&amp;amp;easy way: We have Nasal support for some fairly popular editors, like [http://wiki.flightgear.org/Howto:Syntax_highlighting_for_Nasal#Vim|vim](originally created by Melchior&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/flightgear/ci/next/tree/scripts/syntax/nasal.vim&amp;lt;/ref&amp;gt;), listed at [[Howto:Syntax_highlighting_for_Nasal]] - there are various free converters available that will read such a syntaxhighlighting file and convert it to a pygments class, e.g. see: https://github.com/honza/vim2pygments [[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 16:00, 19 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
==== References ====&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== The repository link templates ==&lt;br /&gt;
=== Complete overhaul of the repository link templates ===&lt;br /&gt;
&lt;br /&gt;
I have now performed a complete overhaul of the repository link templates (see {{tl|repo link/doc related}}).  This was motivated by the incomplete state of these templates, the lack of standardisation, the lack of SourceForge git repository support for {{tl|repo link}}, web-interface only support, etc.  I have used a lot of recursive transclusion for standardisation, so that there is a single point for updating for any FlightGear infrastructure changes.  This is the master {{tl|repo link}} template.  All the other templates are subtemplates which recursively transclude from this master template.  I have also created a number of documentation templates for simplifying template maintenance (see {{tl|repo link/doc related‎}}, {{tl|repo link/doc specific file git‎‎}}, {{tl|repo link/doc git clone‎‎}}, and {{tl|repo link/doc commit}}).  The changes were constrained to maintain backwards compatibility as much as possible.  However I would like to break this to allow the following templates to be updated to transclude from the master {{tl|repo link}} template:&lt;br /&gt;
&lt;br /&gt;
* {{tl|flightgear file}},&lt;br /&gt;
* {{tl|simgear file}},&lt;br /&gt;
* {{tl|fgdata file}},&lt;br /&gt;
* {{tl|fgaddon file}}.&lt;br /&gt;
&lt;br /&gt;
If no one objects, I would like to completely break these and expand and rename the parameter set to match the other &amp;lt;nowiki&amp;gt;{{* file}}&amp;lt;/nowiki&amp;gt; repository templates (e.g. {{tl|terragear file}}).  My overhaul currently does not include Hooray's ideas for non command line usages, i.e. different GUIs, but it enables it to be easily added via the master template and the addition of a single parameter to any subtemplates.&lt;br /&gt;
&lt;br /&gt;
[[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 15:05, 25 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
: I don't have any objections myself, I appreciate all the work you are putting into this, and would like to thank you for helping us clean up all that mess by doing such unglamorous work ;-) I also appreciate that your changes would facilitate adding a non-CLI mode to the corresponding templates. However, I would suggest to wait for Gijs' feedback, because he's ultimately the most likely person to veto something around here ;-) [[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 17:31, 25 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: Johan seems to be the one who did a lot of the initial work on these &amp;lt;nowiki&amp;gt;{{* file}}&amp;lt;/nowiki&amp;gt; templates, and Red Leader with the {{tl|repo link}} template.  And they were involved in the general discussions ([[http://wiki.flightgear.org/index.php?title=FlightGear_wiki:Village_pump&amp;amp;oldid=87148#Repository_link_templates perm]).  But I know Gijs was also involved in the design.&lt;br /&gt;
&lt;br /&gt;
:: For the non-CLI mode, that will need -a lot- more planning.  For example a definitive list of all these modes would be useful.  Should this use an optional Mediawiki pop up extension showing a link to a general page that describes the action for all different GUIs, CLI, etc.?  Should we have a switch box so that the reader can switch in-text between CLI, and the numerous GUIs?  Are we going to have a large set of screenshots for each GUI?  If so, I would strongly recommend the [https://www.mediawiki.org/wiki/Extension:Labeled_Section_Transclusion labelled section transclusion extension] for creating a single page for one GUI with everything for that GUI, as a tutorial.  Here is [http://wiki.nmr-relax.com/Relax_4.0.1 an external example where I have used this], to fragment the base release page to create [http://wiki.nmr-relax.com/Relax_release_descriptions this meta page], as well as many other meta pages.&lt;br /&gt;
&lt;br /&gt;
:: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 03:14, 26 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
I am also thinking of changing the name of the &amp;lt;nowiki&amp;gt;{{* file}}&amp;lt;/nowiki&amp;gt; templates, as I hope to make the scope of the templates far more general.  The name &amp;lt;nowiki&amp;gt;{{* source}}&amp;lt;/nowiki&amp;gt; or &amp;lt;nowiki&amp;gt;{{* repo}}&amp;lt;/nowiki&amp;gt; might be better.  For example these will allow the repository commit, tree view, log view (and maybe rss feed), with or without a file/directory path.  And I would like to generalise this to handle both the SF web-interface and non-web net protocols (git://, ssh://, svn://, etc.).  It will allow for CLI instructions to be built up and embedded in &amp;lt;nowiki&amp;gt;{{#tag:source|&amp;lt;content&amp;gt;|lang=sh}}&amp;lt;/nowiki&amp;gt; tags.  And I will defer all infrastructure decisions in the subtemplates to the single point of {{tl|project infrastructure}}, so that if there are changes in the future, then only this single template needs to be updated to update the entire wiki.&lt;br /&gt;
&lt;br /&gt;
[[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 03:22, 26 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
: The {{tl|project infrastructure}} template as a single point provider of various project infrastructure names and URL pairs seem like a great idea.  If it work out well it will really lessen the maintenance by having less places needing updates, while allowing the various repository templates to be simple to use, in essence by having comprehensible names and no boiler plate parameters for their users.&lt;br /&gt;
: —[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 15:15, 27 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
==== Repository link update ====&lt;br /&gt;
For those following, I have massively expanded the capabilities of the {{tl|repo link}} template:&lt;br /&gt;
* The SourceForge URLs are now comprehensive.&lt;br /&gt;
* Full support for the new query-based URLs for the Gitorious archives.&lt;br /&gt;
* Functional GitLab URLs.&lt;br /&gt;
* Generic repository support (used to create the {{tl|openscenegraph co}} template).&lt;br /&gt;
* Detailed documentation and extensive examples for checking the implementation (if you find any non-supported links, please add these as examples).&lt;br /&gt;
* Isolation of the '''cmd''' parameter from the CLI options &amp;amp;mdash; this is to enable future support for non-CLI instructions based on the value of '''cmd'''.&lt;br /&gt;
&lt;br /&gt;
I have also completed a large set of subtemplates of {{tl|repo link}}, see the list at {{tl|repo link/doc related}}.  This includes a full set of &amp;lt;nowiki&amp;gt;{{* source}}&amp;lt;/nowiki&amp;gt; templates.  I have left the original &amp;lt;nowiki&amp;gt;{{* file}}&amp;lt;/nowiki&amp;gt; templates, rather than renaming and modifying them, so these are now redundant.  All of the &amp;lt;nowiki&amp;gt;{{* source}}&amp;lt;/nowiki&amp;gt;, &amp;lt;nowiki&amp;gt;{{* commit}}&amp;lt;/nowiki&amp;gt;, &amp;lt;nowiki&amp;gt;{{* clone}}&amp;lt;/nowiki&amp;gt;, and &amp;lt;nowiki&amp;gt;{{* co}}&amp;lt;/nowiki&amp;gt; templates transclude from the master {{tl|repo link}} template to do all of the work.&lt;br /&gt;
&lt;br /&gt;
One important template is {{tl|gitorious source}}.  The support for the new query-based URLs for the Gitorious archives is now quite comprehensive in {{tl|repo link}}.  Therefore I have converted almost every single FlightGear wiki link to https://gitorious.org to use {{tl|gitorious source}} instead.  This fixes a lot of broken links and broken git instructions.  I have reduced the number of hits for gitorious.org on the wiki (searching just for &amp;quot;gitorious&amp;quot;) to 22 hits.  This includes 2 very outdated articles ([[FlightGear Git: aircraft authors]], [[Fr/FlightGear et Git]]), 15 locked newsletters, 1 with no longer existent Gitorious merge request links, and 4 base URL links for Hangars.  This way we can maintain the Gitorious web interface links and git command instructions in a functional state by simply updating the single source of {{tl|repo link}}.&lt;br /&gt;
&lt;br /&gt;
[[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 11:38, 29 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
: I just remembered [[Special:LinkSearch]], so make that 184 broken gitorious.org links remaining.  Lots more work to do :)&lt;br /&gt;
&lt;br /&gt;
: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 14:46, 29 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
For some of these templates, e.g. {{tl|repo link/doc usage}}, I'm trying to implement some logic for automatic whitespace padding for documentation formatting, but the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;{{#len:string}}&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; function is not enabled.  According to {{mediawiki|Wikitext_parser/Core_parser_functions#.23len}} and {{mediawiki|Extension:StringFunctions}}, the option &amp;lt;code&amp;gt;$wgPFEnableStringFunctions = true;&amp;lt;/code&amp;gt; should be set (in &amp;lt;code&amp;gt;LocalSettings.php&amp;lt;/code&amp;gt;).  Unless there is a reason for not using this, I was wondering if someone could enable this?  Cheers!&lt;br /&gt;
&lt;br /&gt;
[[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 09:53, 8 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
=== Archived newsletters and dead links? ===&lt;br /&gt;
&lt;br /&gt;
Do we have a policy for the dead links in the FlightGear newsletters?  It is obviously good to preserve the historic state.  But there are many Gitorious links that could be made functional again using the {{tl|gitorious source}} template to point to the historic Gitorious archives (including the official FlightGear repositories, rather than using {{tl|fgdata source}}, for example).  The https://gitorious.org links have been converted from URL/path based to query based, so absolutely all of the old links are broken.  I am steadily converting all Gitorious links to use the [[Template:repo link/doc related|{{obr}}repo link{{cbr}} family of templates]], with the exception of the newsletters.&lt;br /&gt;
&lt;br /&gt;
[[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 04:52, 8 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
: I think it could be a good idea to try update old links in those newsletters.  I sometimes look back at things and tend to think that I probably are not the only one doing that.&lt;br /&gt;
: I wonder if the rotten links should be replaced or stricken, but I think they could just as well be replaced.  The key thing is that they go to the same resource or content, not weather they have been updated or not (also, the change will be visible in the revision history after all).&lt;br /&gt;
: —[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 07:11, 8 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: I should add that I'm using [http://wiki.flightgear.org/index.php?title=Special:LinkSearch&amp;amp;limit=500&amp;amp;offset=0&amp;amp;target=http%3A%2F%2Fgitorious.org &amp;lt;nowiki&amp;gt;Special:LinkSearch for http://gitorious.org&amp;lt;/nowiki&amp;gt;] and [http://wiki.flightgear.org/index.php?title=Special:LinkSearch&amp;amp;limit=500&amp;amp;offset=0&amp;amp;target=https%3A%2F%2Fgitorious.org &amp;lt;nowiki&amp;gt;Special:LinkSearch for https://gitorious.org&amp;lt;/nowiki&amp;gt;].  And I am also not touching the &amp;lt;code&amp;gt;User*&amp;lt;/code&amp;gt; pages, &amp;lt;code&amp;gt;*talk*&amp;lt;/code&amp;gt; pages, or pages tagged as out of date or up for deletion.  For the newsletters I might look at these later when the broken Gitorious links are fixed in the rest of the wiki but, as these are locked, someone else might have make the switch to {{tl|gitorious source}}, {{tl|gitorious url}}, {{tl|gitorious clone}}, and {{tl|gitorious merge request}}.&lt;br /&gt;
&lt;br /&gt;
:: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 02:53, 9 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
::: I will temporarily add a table here for the templates in the newsletters and will slowly fix them one by one together with any other admin.&lt;br /&gt;
{{navbox&lt;br /&gt;
| title = Click &amp;quot;show&amp;quot; to show --&amp;gt;&lt;br /&gt;
| state = collapsed&lt;br /&gt;
| navbar = plain&lt;br /&gt;
| list1 =&lt;br /&gt;
http:...&lt;br /&gt;
{{{!}} class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Fixed !! Newsletter !! Gitorious URL !! Notes&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter May 2010]]&lt;br /&gt;
{{!}} http://gitorious.org/fg&lt;br /&gt;
{{!}} No equivalent link for the Gitorious archive - project pages are dead.  Maybe just use http://gitorious.org/?&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter May 2010]]&lt;br /&gt;
{{!}} http://gitorious.org/fg&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter September 2010]]&lt;br /&gt;
{{!}} http://gitorious.org/fg/flightgear/commit/5c6fe952598053fa63631fc0161d666f22a50f51&lt;br /&gt;
{{!}} Functional link, equivalent to {{gitorious url|fg|flightgear|commit=5c6fe952598053fa63631fc0161d666f22a50f51}}.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter September 2010]]&lt;br /&gt;
{{!}} http://gitorious.org/fg/flightgear/commit/5c6fe952598053fa63631fc0161d666f22a50f51&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter January 2011]]&lt;br /&gt;
{{!}} http://gitorious.org/jsbsim/jsbsim&lt;br /&gt;
{{!}} Functional link.  Switched to {{gitorious url|jsbsim|jsbsim}} to future-protect the link.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter January 2011]]&lt;br /&gt;
{{!}} http://gitorious.org/jsbsim/jsbsim&lt;br /&gt;
{{!}} Functional link.  Switched to {{gitorious url|jsbsim|jsbsim}} to future-protect the link.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter February 2011]]&lt;br /&gt;
{{!}} http://gitorious.org/headtrack&lt;br /&gt;
&lt;br /&gt;
http://gitorious.org/arduinocockpit&lt;br /&gt;
{{!}} Project pages are dead, switched to {{gitorious url|headtrack|headtrack}}&lt;br /&gt;
&lt;br /&gt;
{{gitorious url|arduinocockpit|arduinocockpit}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter February 2011]]&lt;br /&gt;
{{!}} http://gitorious.org/arduinocockpi&lt;br /&gt;
&lt;br /&gt;
http://gitorious.org/headtrack&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter March 2011]]&lt;br /&gt;
{{!}} http://gitorious.org/lockheed-l10-electra&lt;br /&gt;
{{!}} Missing project - i.e. {{gitlab source|user=emilianh|repo=Lockheed-L10-Electra|text=migrated to GitLab}}.  Switched to {{gitlab source|user=emilianh|repo=Lockheed-L10-Electra}}.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter March 2011]]&lt;br /&gt;
{{!}} http://gitorious.org/lockheed-l10-electra&lt;br /&gt;
{{!}} Switched to {{gitlab source|user=emilianh|repo=Lockheed-L10-Electra}}.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter November 2011]]&lt;br /&gt;
{{!}} http://gitorious.org/flightgear-aircraft&lt;br /&gt;
{{!}} Switched to {{gitorious source}} and rephrased text slightly to help readers find the repositories.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter October 2012]]&lt;br /&gt;
{{!}} http://gitorious.org/anders-hangar/mtb_20m/trees/master&lt;br /&gt;
{{!}} Switch to {{gitorious url|proj=anders-hangar|repo=mtb_20m}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter March 2013]]&lt;br /&gt;
{{!}} http://gitorious.org/fg/flightgear/blobs/next/scripts/java/FGClient/src/FGFSDemo.java&lt;br /&gt;
{{!}} Switched to {{gitorious url|proj=fg|repo=flightgear|path=scripts/java/FGClient/src/FGFSDemo.java}}.  This points to the old Gitorious repository to protect against path changes in the future.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter September 2013]]&lt;br /&gt;
{{!}} http://gitorious.org/boeing/707&lt;br /&gt;
{{!}} Switched to {{gitorious source|proj=boeing|repo=707}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter September 2013]]&lt;br /&gt;
{{!}} http://gitorious.org/boeing/707&lt;br /&gt;
{{!}} Switched to {{gitorious source|proj=boeing|repo=707}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter November 2013]]&lt;br /&gt;
{{!}} http://gitorious.org/fg/fgrun&lt;br /&gt;
{{!}} Switch to {{gitorious url|proj=fg|repo=fgrun}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter November 2013]]&lt;br /&gt;
{{!}} http://gitorious.org/fg/fgrun&lt;br /&gt;
{{!}} Switch to {{gitorious url|proj=fg|repo=fgrun}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter July 2014]]&lt;br /&gt;
{{!}} http://gitorious.org/nasal-support/nasal-npp&lt;br /&gt;
{{!}} Switched to {{gitorious url|nasal-support|nasal-npp}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter April 2015]]&lt;br /&gt;
{{!}} http://gitorious.org&lt;br /&gt;
{{!}} Switched to {{tl|gitorious source}} without parameters for the Gitorious base URL, to future-protect it.&lt;br /&gt;
{{!}}}&lt;br /&gt;
&lt;br /&gt;
https:...&lt;br /&gt;
{{{!}} class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Fixed !! Newsletter !! Gitorious URL !! Notes&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter April 2011]]&lt;br /&gt;
{{!}} https://gitorious.org/papillon81/flightgear-custom-scenery/&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/dvanmosselbeen/flightgear-custom-scenery&lt;br /&gt;
{{!}} Switched to {{gitorious source|dvanmosselbeen|flightgear-custom-scenery}} and {{gitorious source|papillon81|flightgear-custom-scenery}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter April 2011]]&lt;br /&gt;
{{!}} https://gitorious.org/dvanmosselbeen/flightgear-custom-scenery&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/papillon81/flightgear-custom-scenery/&lt;br /&gt;
{{!}} Switched to {{gitorious source|dvanmosselbeen|flightgear-custom-scenery}} and {{gitorious source|papillon81|flightgear-custom-scenery}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter July 2011]]&lt;br /&gt;
{{!}} https://gitorious.org/dvanmosselbeen/flightgear-custom-scenery&lt;br /&gt;
{{!}} Switched to {{gitorious source|dvanmosselbeen|flightgear-custom-scenery}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter July 2011]]&lt;br /&gt;
{{!}} https://gitorious.org/dvanmosselbeen/flightgear-custom-scenery&lt;br /&gt;
{{!}} Switched to {{gitorious source|dvanmosselbeen|flightgear-custom-scenery}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter December 2011]]&lt;br /&gt;
{{!}} https://gitorious.org/dvanmosselbeen/flightgear-custom-scenery&lt;br /&gt;
{{!}} Switched to {{gitorious source|dvanmosselbeen|flightgear-custom-scenery}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Fr/Nouvelles du projet FlightGear - décembre 2011]]&lt;br /&gt;
{{!}} https://gitorious.org/dvanmosselbeen/flightgear-custom-scenery&lt;br /&gt;
{{!}} Switched to {{gitorious source|dvanmosselbeen|flightgear-custom-scenery}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter April 2012]]&lt;br /&gt;
{{!}} https://gitorious.org/fg/fgdata/blobs/master/Aircraft/Instruments-3d/garmin196/README&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/fgdata/blobs/master/Aircraft/Instruments-3d/garmin196/doc/doc-en.htm&lt;br /&gt;
{{!}} Switched to {{fgdata source|path=Aircraft/Instruments-3d/garmin196/README|full=1}} and {{fgdata source|path=Aircraft/Instruments-3d/garmin196/doc/doc-en.htm|full=1}} to point to the current FGData locations and removed the name &amp;quot;Gitorious&amp;quot; to make the text of the Garmin 196 GPS section still relevant&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter August 2012]]&lt;br /&gt;
{{!}} https://gitorious.org/mil-mi-6&lt;br /&gt;
{{!}} Switched to {{gitorious url|proj=mil-mi-6|repo=mi6dev}}, and changed from the non-existent project page to the main repository.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter October 2012]]&lt;br /&gt;
{{!}} https://gitorious.org/fgradar&lt;br /&gt;
{{!}} Switched from the project page to the direct repository {{gitorious url|fgradar|fgradar}}.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter March 2013]]&lt;br /&gt;
{{!}} https://gitorious.org/fg/flightgear/commit/913727239d6776c0508d206f395e16c265413ec3&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/flightgear/commit/eba03b5e469824ee8f1494723fcddbbc56155a08&lt;br /&gt;
{{!}} Switched to {{flightgear url|commit=913727239d6776c0508d206f395e16c265413ec3}} and {{flightgear url|commit=eba03b5e469824ee8f1494723fcddbbc56155a08}}.  This deliberately points to the current repository.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter April 2013]]&lt;br /&gt;
{{!}} https://gitorious.org/fg-radi/osm2city&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/scenery-france-850&lt;br /&gt;
{{!}} Switched to the new GitLab repository {{gitlab source|proj=fg-radi|repo=osm2city|full=1}}&lt;br /&gt;
&lt;br /&gt;
and removed the no longer existent scenery-france-850 repository, replacing it with &amp;quot;&amp;lt;s&amp;gt;Scenery repository (Gitorious)&amp;lt;/s&amp;gt;&amp;quot;.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter October 2013]]&lt;br /&gt;
{{!}} https://gitorious.org/fg/galvedros-fgdata&lt;br /&gt;
{{!}} Switch to {{gitorious url|proj=fg|repo=galvedros-fgdata}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter October 2013]]&lt;br /&gt;
{{!}} https://gitorious.org/fg/galvedros-fgdata&lt;br /&gt;
{{!}} Switch to {{gitorious url|proj=fg|repo=galvedros-fgdata}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter November 2013]]&lt;br /&gt;
{{!}} https://gitorious.org/ec130/&lt;br /&gt;
{{!}} Switched from the project page to the direct repository {{gitorious source|ec130|ec130}}.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter November 2013]]&lt;br /&gt;
{{!}} https://gitorious.org/ec130/&lt;br /&gt;
{{!}} Switched from the project page to the direct repository {{gitorious source|ec130|ec130}}.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter February 2014]]&lt;br /&gt;
{{!}} https://gitorious.org/fg/philosophers-fgdata/source/022bef27f05d4837d720f63c6507b47466ff2a59:Nasal/console/repl.nas#L436&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/philosophers-fgdata/source/nasal-console:Nasal/console&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/fgdata/commit/eaaf816b772649d5b0826a1d0bdd166dbc5b968f&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/flightgear/commit/34ed79e5f88ffdfc5e651a1fe3e639cb8f4d3353&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/flightgear/commit/5eee5e42ae4f5cf56283b3bf5a3be46efc2b51c4&lt;br /&gt;
&lt;br /&gt;
https://www.gitorious.org/fg/flightgear/merge_requests/26&lt;br /&gt;
{{!}} Switched to {{gitorious source|proj=fg|repo=philosophers-fgdata|branch=nasal-console|path=Nasal/console/repl.nas|line=708}}&lt;br /&gt;
&lt;br /&gt;
{{gitorious url|proj=fg|repo=philosophers-fgdata|branch=nasal-console|path=Nasal/console|view=tree}}&lt;br /&gt;
&lt;br /&gt;
{{fgdata-old url|commit=eaaf816b772649d5b0826a1d0bdd166dbc5b968f}}&lt;br /&gt;
&lt;br /&gt;
{{flightgear commit|34ed79e5f88ffdfc5e651a1fe3e639cb8f4d3353}}&lt;br /&gt;
&lt;br /&gt;
{{gitorious merge request|mr=54}}&lt;br /&gt;
&lt;br /&gt;
{{gitorious merge request|mr=26}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter February 2014]]&lt;br /&gt;
{{!}} https://gitorious.org/fg/philosophers-fgdata/source/022bef27f05d4837d720f63c6507b47466ff2a59:Nasal/console/repl.nas#L436&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/philosophers-fgdata/source/nasal-console:Nasal/console&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/fgdata/commit/eaaf816b772649d5b0826a1d0bdd166dbc5b968f&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/flightgear/commit/34ed79e5f88ffdfc5e651a1fe3e639cb8f4d3353&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/flightgear/commit/5eee5e42ae4f5cf56283b3bf5a3be46efc2b51c4&lt;br /&gt;
&lt;br /&gt;
https://www.gitorious.org/fg/flightgear/merge_requests/26&lt;br /&gt;
{{!}} Changes match the English article.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter April 2014]]&lt;br /&gt;
{{!}} https://gitorious.org/fg/fgdata/flightgear?p=fg/fgdata:flightgear.git;a=blob;f=keyboard.xml&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/fgdata?p=fg:fgdata.git;a=commit;h=f8c56dcc52ffd3d6dfca1d39dc4a72b6b3478368&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/hoorays-flightgear?p=fg:hoorays-flightgear.git;a=shortlog;h=refs/heads/topics/cppbind-fgprotocol&lt;br /&gt;
{{!}} This first link was the broken {{tl|git link}} template (see the table below).  The other two links are not in the article?!&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter June 2014]]&lt;br /&gt;
{{!}} https://gitorious.org/eddp-custom-scenery/eddp-custom-scenery/&lt;br /&gt;
{{!}} Switched to {{tl|gitorious clone}} to provide functional '''git clone''' instructions.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter November 2014]]&lt;br /&gt;
{{!}} https://gitorious.org/fg/hoorays-fgdata/source/2857d8fc9fcfe2bb162a9eb9d3dcca4d41b3a876:Nasal/ai/aim9/aim9.fdm#L9&lt;br /&gt;
{{!}} Switch to {{gitorious url|proj=fg|repo=hoorays-fgdata|commit=2857d8fc9fcfe2bb162a9eb9d3dcca4d41b3a876|path=Nasal/ai/aim9/aim9.fdm|line=9}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter January 2015]]&lt;br /&gt;
{{!}} https://gitorious.org/fg/canvas-hackers-fgdata/source/f59c42134a5a77e343981dcff8278c3e2f094e87&lt;br /&gt;
{{!}} Switch to {{gitorious url|proj=fg|repo=canvas-hackers-fgdata|commit=f59c42134a5a77e343981dcff8278c3e2f094e87|view=summary}}&lt;br /&gt;
{{!}}}&lt;br /&gt;
&lt;br /&gt;
Broken templates:...&lt;br /&gt;
{{{!}} class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Fixed !! Newsletter !! Template !! Notes&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter April 2014]]&lt;br /&gt;
{{!}} {{tlx|Git link|gitorious|fg/fgdata|master|keyboard.xml|pre=$FG_ROOT/}}&lt;br /&gt;
{{!}} Switched to {{fgdata source|path=keyboard.xml|pre=$FG_ROOT}} to fix the Gitorious link created by the broken and depreciated {{tl|git link}} template.&lt;br /&gt;
{{!}}}&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
::: —[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 12:06, 9 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:::: I've added a '''notes''' column to help a little.&lt;br /&gt;
&lt;br /&gt;
:::: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 12:30, 9 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
=== Elimination of the dead Gitorious links ===&lt;br /&gt;
Thanks largely to the diversity and flexibility of the [[:Category:Repository link templates|{{obr}}repo link{{cbr}} family of templates]], I have now managed to eliminate almost every last dead Gitorious link in the FlightGear wiki!  The locked Newsletter articles, user pages, and talk pages are the only exceptions.  The page counts from the (Main) namespace are:&lt;br /&gt;
* [http://wiki.flightgear.org/index.php?target=http%3A%2F%2Fgitorious.org&amp;amp;namespace=0&amp;amp;title=Special%3ALinkSearch &amp;lt;nowiki&amp;gt;Special:LinkSearch for http://gitorious.org&amp;lt;/nowiki&amp;gt;] &amp;amp;mdash; 37.  Of these, 17 are for the front page with the news of the Gitorious to SourceForge migration, and the rest are Newsletters.&lt;br /&gt;
* [http://wiki.flightgear.org/index.php?title=Special:LinkSearch&amp;amp;limit=500&amp;amp;offset=0&amp;amp;target=https%3A%2F%2Fgitorious.org&amp;amp;namespace=0 &amp;lt;nowiki&amp;gt;Special:LinkSearch for https://gitorious.org&amp;lt;/nowiki&amp;gt;] &amp;amp;mdash; 166.  Most of these links are valid and created by the {{obr}}gitorious *{{cbr}} subtemplates of {{tl|repo link}}.  The remaining broken links are all in the locked Newsletters.&lt;br /&gt;
The Howto:* pages are not in the (Main) wiki namespace, but I've knocked those out too.&lt;br /&gt;
&lt;br /&gt;
[[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 13:54, 10 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
: thanks for doing all this unglamorous work - I am sorry that Gijs was apparently too busy to follow up on my suggestion to either provide you with admin access around here, or at least to help you run a Python script to do all this work in an automated, rather than manual, fashion. Hopefully, things will work out better next time. Again, thank you. Like I said, I think you should definitely be given admin access on the wiki, especially given your recent contributions - and I would gladly have my wiki status downgraded accordingly. In fact, if I was able to directly promote accounts accordingly, I would have done so months ago - however, it seems that Gijs is the only one to have those privileges, and he mentioned off-list that he's kinda busy with RL/exams etc, so it is to be expected that he's going to become a bottleneck more often - hopefully, this will be recongized as an actual issue, so that there will be more people able to promote new wiki admins. Sorry that things didn't work out better this time, and thanks so much for doing all this stuff manually. -[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 14:49, 10 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: No problems!  As for automating this, that would not have been possible.  If you look at the changes, you'll see that each one is different &amp;lt;sup&amp;gt;[http://wiki.flightgear.org/index.php?title=Special:RecentChanges&amp;amp;to=20160310210655&amp;amp;limit=500]&amp;lt;/sup&amp;gt;.  I had to check each one, and update the link as required.&lt;br /&gt;
&lt;br /&gt;
:: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 16:08, 10 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
::: There's three of us actually (Curt, Simon and myself), no need to wait on me. See http://wiki.flightgear.org/index.php?title=Special%3AListUsers&amp;amp;username=&amp;amp;group=bureaucrat&amp;amp;limit=100 (Sek is inactive nowadays) ;-)&lt;br /&gt;
::: Please note that forum pms are really not the best way to contact me. I very much prefer email over forum pms as it's a lot easier to filter out the huge amounts of nonsense I'm receiving from stuff requiring actual attention.&lt;br /&gt;
::: Anyhow I've just  promoted Bugman so he can edit locked articles.&lt;br /&gt;
::: [[User:Gijs|Gijs]] ([[User talk:Gijs|talk]]) 05:06, 11 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:::: Thank you.  I'll try to preserve the original intent of the Newsletters while fixing the broken links (maybe even preserving any original URLs as Mediawiki link text, while pointing to the new URL).  I will use the {{obr}}gitorious *{{cbr}} templates to point to the historical sources, and will probably use this for all of the Gitorious URLs so that we have full control over any future URL breakages via the single location of {{tl|repo link}}.  For example, if they change the gitorious.org domain name to a https://archive.org subdomain (i.e. gitorious.archive.org).&lt;br /&gt;
&lt;br /&gt;
:::: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 06:40, 11 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
=== Regex parsing of template parameters? ===&lt;br /&gt;
&lt;br /&gt;
For the {{tl|repo link}} template, I am currently trying to work out what to do for git branches and tags on the SourceForge infrastructure.  The problem is that the presence of the character &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt; within a branch or tag name requires the text &amp;lt;code&amp;gt;/~&amp;lt;/code&amp;gt; to be appended to that name in the URL, for example:&lt;br /&gt;
&lt;br /&gt;
* Tag &amp;lt;code&amp;gt;version/2016.1.1&amp;lt;/code&amp;gt;:  https://sourceforge.net/p/flightgear/simgear/ci/version/2016.1.1/~/tree/simgear/ephemeris/ephemeris.cxx&lt;br /&gt;
* Branch &amp;lt;code&amp;gt;release/2016.1&amp;lt;/code&amp;gt;:  https://sourceforge.net/p/flightgear/simgear/ci/release/2016.1/~/tree/simgear/ephemeris/ephemeris.cxx&lt;br /&gt;
&lt;br /&gt;
I haven't found out a way to use regex to parse the &amp;lt;code&amp;gt;tag&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;branch&amp;lt;/code&amp;gt; template parameters to automate this, hence I am thinking of just giving the instruction for the template user to append this text to the &amp;lt;code&amp;gt;tag&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;branch&amp;lt;/code&amp;gt; parameter text themselves.  However this is not ideal - a change of this behaviour on the SourceForge side requires end pages with SourceForge URLs to be updated, rather than just updating {{tl|repo link}}.  I was wondering about possibility of installing the extension:&lt;br /&gt;
&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Extension:RegexParserFunctions Extension:RegexParserFunctions]&lt;br /&gt;
&lt;br /&gt;
Though I'm not 100% sure if that will work.  Or does someone else know an alternative?  Cheers!&lt;br /&gt;
&lt;br /&gt;
[[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 12:09, 22 April 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
: not a solution, just a potential workaround would be checking for the most common prefix strings used in tags/branches (e.g. version, release, topic, topics) and explicitly rewrite the URL accordingly to append the /~ suffix -[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 12:59, 22 April 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:: That might be a solution.  But I don't know how to do that without regex ;)  We really only have #ifeq statements, but that has to match the whole string.&lt;br /&gt;
&lt;br /&gt;
:: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 13:44, 22 April 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
As a temporary workaround, I'll update the SourceForge {{tl|repo link}} template instructions to tell the user to append &amp;lt;code&amp;gt;/~&amp;lt;/code&amp;gt; to the branch or tag name, if the &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt; character is present.&lt;br /&gt;
&lt;br /&gt;
[[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 10:31, 20 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Discussion about quotes on the wiki ==&lt;br /&gt;
{{usr|Hooray}} have started a page now at [[FlightGear wiki:Quoting Guidelines]] ([http://wiki.flightgear.org/index.php?title=FlightGear_wiki:Quoting_Guidelines&amp;amp;oldid=96104 perm]) for a discussion regarding guidelines for the use of quotes on the wiki.  Join the discussion.&lt;br /&gt;
&lt;br /&gt;
—[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 18:17, 21 March 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In slight relation to this I have tried to make the wiki more consistently use the most common spelling and case, &amp;quot;Instant-Cquotes&amp;quot; and have changed the automatic categorization accordingly.  All articles using the {{tl|FGCquote}} template can now be found in [[:Category:Articles containing Instant-Cquotes]] (currently some ~250 articles).&lt;br /&gt;
&lt;br /&gt;
—[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 08:21, 23 March 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Reorganizing the Git articles ==&lt;br /&gt;
I've noticed that the [[:Category:Git|Git articles]] suffer from duplication and are in part obsolete (especially with regard to the instructions for running Git on Windows). Thus, I propose the following reorganization:&lt;br /&gt;
* [[Development workflow]]: reorganization to explain how the patch submission process is organized from a high-level point of view (forking the repository from SourceForge, developing, pushing the commits to the personal fork, submitting a merge request/sending a patch to the mailing list);&lt;br /&gt;
* [[FlightGear Git]]: leave as is;&lt;br /&gt;
* '''Installing and configuring Git''' - new article about installing Git and configuring it (setting the username/e-mail address); merge the contents of [[FlightGear Git on Windows]] and [[Resources WRT running git on Win32]] here;&lt;br /&gt;
* [[FlightGear Git for laymen]] - make it follow [[FGW:MOS]], merge the contents of [[Howto:Start using git]] here;&lt;br /&gt;
* [[FlightGear Git: core developers]] and [[FlightGear Git: data developers]] - I'm uncertain about what I should do with them: the only piece information that would not be written in other articles is the list of alternative methods for cloning FGData;&lt;br /&gt;
* [[FlightGear Git: gitiquette]] and [[FlightGear Git: tips]] - make them follow [[FGW:MOS]].&lt;br /&gt;
Any comments? -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 06:11, 13 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
: This is sorely needed!  For [[FlightGear Git: core developers]] and [[FlightGear Git: data developers]], maybe these can be merged into something like [[FlightGear Git: working with the repositories]]?  The only real difference is the URL, but that is a minor difference with the [[:Category:Repository link templates]].  This could be generalised into a set of instructions for working with all git repositories for the core infrastructure, including forking and merge requests, with a current focus on the SourceForge web and non-web interfaces.&lt;br /&gt;
&lt;br /&gt;
: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 08:17, 13 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:: Yes, I was thinking about a similar solution as well. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 10:16, 13 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
: For the reorganisation of the articles, it would be good to make a lot of use of the {{tl|Project infrastructure}} template.  This will abstract away the SourceForge infrastructure (well some instructions will be 100% SourceForge specific, so it won't be perfect).  I would like to however have [[Template talk:Project infrastructure#Slight variation of the current architecture|Johan's design]] implemented first, as it would be quite beneficial.&lt;br /&gt;
&lt;br /&gt;
: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 18:43, 14 May 2016 (EDT)&lt;br /&gt;
:: Thanks, didn't know it existed. Right now I'm fixing some last-minute bugs before the release, but I'll have a look at this. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 09:05, 15 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
::: And while we're at it, we also have a handful of git related templates to abstract away UI-specifics, which would allow us/me to upload screenshots for different interfaces (CLI, tortoisegit etc), so that we only need to update the templates, and not touch any  of those articles. OTOH, I cannot seem to find a recent discussion of the idea, only http://wiki.flightgear.org/Talk:Development_workflow and that has not been updated in 3 years. Any opinions ? -[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 20:52, 15 May 2016 (EDT)&lt;br /&gt;
:::: I'm not fully sold on this one. I see the point of creating templates (for example, the Git commands mentioned in [[Talk:Development workflow]] can be used in aircraft pages to explain how to checkout a development version from a private repository), but, in my opinion, screenshots are a bit &amp;quot;heavy&amp;quot; to be reused in other articles (beside the Git ones). Did you plan to use them in other pages and, if yes, how? -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 14:11, 23 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:: It was originally intended to document different UIs and workflows - i.e. by parameterizing the templates, so that a matching set of commands, and screenshots, could be shown. The basic idea was that we have a growing number of articles detailing git workflows (clone, checkout, push, branch etc) - and it seemed to make sense to have a single article/template documenting the specifics, so that other articles could merely use that template, while specifiying the &amp;quot;action&amp;quot; and any other variable items (repository, branch etc) - and then use a template to provide the matching command line. However, don't worry - we don't need to do it that way. Originally, it was all inspired by [[Howto:Build FlightGear with NetBeans using CMake]]. -[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 14:23, 23 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== UTF-8 language pages cannot be edited ==&lt;br /&gt;
&lt;br /&gt;
This is a continuation of [[FlightGear wiki:Village pump/Archive 2015#UTF-8 language pages cannot be edited]].  I can see that wiki editors are [[Zh/FlightGear Wiki|forced to create workarounds]], as the [[Main page]] in Chinese [http://wiki.flightgear.org/index.php?title=Zh/%E9%A6%96%E9%A1%B5&amp;amp;action=edit cannot be edited].  I think it is quite important to solve this ''&amp;quot;A database query error has occurred. This may indicate a bug in the software&amp;quot;'' issue.  As the fix is quite dangerous (see {{mediawiki|Topic:S1q54kosfdkhz6w1}}), do we have a backup system?  Do we have regular mysql and ftp dumps that can be backed up locally using rsync?&lt;br /&gt;
&lt;br /&gt;
[[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 05:16, 15 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Making wiki specific templates available via editor ? == &lt;br /&gt;
We now have an increasing number of wiki specific templates that should be more widely used, so that it would make sense to integrate those with the default mediawiki editor - e.g. the URL encapsulating templates. -[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 10:12, 16 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Categorizing aircraft infoboxes by hangar ==&lt;br /&gt;
I would like to bring the discussions from [[Template talk:Infobox aircraft#fgaddon aircraft]] into here for greater exposure.  The idea discussed there was to add &amp;lt;code&amp;gt;hangar&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;aircraft&amp;lt;/code&amp;gt; parameters to automate and categorise the aircraft infoboxes.  This is to help readers instantly identify the source of the aircraft and to give greater exposure to 3rd party hangars or independent aircraft.  To show off the potential of this automated approach, I have created an example template at [[User:Bugman/Infobox Aircraft]] (see the bottom for an example based on the [[Space Shuttle]] infobox).  Each [[FlightGear hangars#Third party sites|3rd party hangar]] can add one of the following options:&lt;br /&gt;
&lt;br /&gt;
* The hangar logo, with a link to the hangar.  For example I have created an initial test logo for FGAddon:  [[File:FGAddon logo.png|80px]]&lt;br /&gt;
* Development repository link.  An automatically created link, if the {{param|development}} parameter is not supplied.&lt;br /&gt;
* Download link.  An automatically created link, if the {{param|download}} parameter is not supplied.&lt;br /&gt;
* A hangar category.  For example [[:Category:FGAddon hangar]].&lt;br /&gt;
&lt;br /&gt;
Feedback would be appreciated.  Cheers!&lt;br /&gt;
&lt;br /&gt;
[[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 04:53, 25 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
: Following from these ideas, I have made a proposal for a new template:  [[Template talk:Infobox aircraft#Proposal for a new aircraft infobox template design (2016/06)]].  The more feedback on this, the better ;)  Cheers!&lt;br /&gt;
&lt;br /&gt;
: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 10:17, 1 June 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:: Thanks for your work - looks good, the only change I would make is (as you noted in the template talk page) replacing the repository/download/livery database/forum thread icons with something more suitable and less &amp;quot;brilliant&amp;quot; icons (though I admit I don't have an alternative proposal for this right now). -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 04:40, 2 June 2016 (EDT)&lt;/div&gt;</summary>
		<author><name>Elgaton</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=FlightGear_wiki_talk:Instant-Refs&amp;diff=98770</id>
		<title>FlightGear wiki talk:Instant-Refs</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=FlightGear_wiki_talk:Instant-Refs&amp;diff=98770"/>
		<updated>2016-05-27T12:10:36Z</updated>

		<summary type="html">&lt;p&gt;Elgaton: /* Upcoming dependencies */ Library now on the CDN&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== more sources ==&lt;br /&gt;
&lt;br /&gt;
at some point, we may also want to add support for other sources, such as:&lt;br /&gt;
* old forum URLs, i.e. not yet using the subdomain format (should be easy, it's just a different/additional URL after all)&lt;br /&gt;
* thread.gmane.org/gmane.games.flightgear.devel/&lt;br /&gt;
* jsbsim devel list&lt;br /&gt;
* github tickets&lt;br /&gt;
* the new SF.net issue tracker &lt;br /&gt;
* SF.net commit logs http://gitorious.org/fg/&lt;br /&gt;
* http://www.mail-archive.com/flightgear-devel@flightgear.org/ (until 2005)&lt;br /&gt;
* http://www.mail-archive.com/flightgear-devel@lists.sourceforge.net/maillist.html (until 10/2013)&lt;br /&gt;
&lt;br /&gt;
that should cover all important sources. And it would allow us to also use the same script to help populate [[FlightGear Newsletter]] &amp;amp; [[Changelog 3.2|changelogs]], but also [[Release plan/Lessons learned]]. So this could be a real time-saver. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 14:40, 1 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Automatic update of script and old quotes ==&lt;br /&gt;
Thanks for the heads-up. Now, that makes me wonder if I can adapt the script to automatically parse existing wiki articles and update cquotes there automatically by re-opening the URL and re-running the extraction logic :) BTW: That reminds me: I was going to investigate adopting the '''downloadURL''' attribute[http://stackoverflow.com/questions/15095055/why-isnt-my-greasemonkey-script-updating] so that scripts can auto-update --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 22:51, 11 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
:: if we should continue to see this widely used, having a good way to re-download and re-run the script on pages with existing cquotes would be a good way to automatically update quotes. For that, we would want to encode certain meta info in each template, e.g.:&lt;br /&gt;
* script version&lt;br /&gt;
* quoting date/time&lt;br /&gt;
* quote URL&lt;br /&gt;
* selection offsets &lt;br /&gt;
* quoting settings (format)&lt;br /&gt;
&lt;br /&gt;
We can hook into form submission to update arbitrary quotes/contents using this: http://commons.oreilly.com/wiki/index.php/Greasemonkey_Hacks/Developer_Tools#Intercept_and_Modify_Form_Submissions&lt;br /&gt;
&lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 07:19, 15 November 2015 (EST)&lt;br /&gt;
&lt;br /&gt;
=== Hosting ===&lt;br /&gt;
The script seems to be about to become sufficiently complex to deserve actual hosting:&lt;br /&gt;
* http://wiki.greasespot.net/User_Script_Hosting&lt;br /&gt;
* https://openuserjs.org/&lt;br /&gt;
&lt;br /&gt;
(that would allow updating the script automatically)&lt;br /&gt;
&lt;br /&gt;
: Hi, is there any progress being made on this? I think the best way to host it would be to put in in a SourceForge repository under the FlightGear project (I don't know if it allows direct downloads, though, and we would need to relicense the script because [https://opensource.org/faq#public-domain public domain licenses are not OSI-approved]); otherwise, I can submit it to [https://greasyfork.org/ GreasyFork] (OpenUserJS is unsuitable as [https://openuserjs.org/about/Terms-of-Service public domain licenses are not allowed]). -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 03:58, 1 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:: I don't think anybody has looked into this recently - however, relicensing should be a no-brainer, given that all the code is in the public domain anyway. I am not sure if it's worth the hassle to put up under sourceforge/FlightGear; we also need to keep in mind that this is not exactly the most popular &amp;quot;tool&amp;quot; around here. So, before this becomes even better accessible, it might be a good idea to comply with some of the requests made, e.g. by adding support for a different output mode (without using the FGCquote template, just the copied text, plus the ref part), so that quote-heavy pages don't look that obnoxious.&lt;br /&gt;
:: Regarding hosting in general, I still think it may be a good idea, but we would probably need to make sure that some requirements are met, e.g. having a revision history, and to provide other contributors with access-alternatively, we should maintain a copy of the script in the wiki, and add a note saying that changes to it will be reviewed/integrated with the hosted script by one of us (if you'd volunteer to help with that, I'd suggest to just go ahead and set up a public repository).&lt;br /&gt;
:: Admittedly, this is going to remain a fairly FG specific script, it would need quite a bit of work to become useful for other purposes (even though other OSS projects may be easy to support). --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 06:33, 1 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
::: OK, I think we can leave the script here and host it on GreasyFork (it allows public domain scripts) - I'll put the page on my watchlist to make sure I update the script there every time there's a version bump. Does that look good to you and the other contributors? -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 09:26, 1 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:::: Sounds good to me, given how the script has evolved over time, we've probably hit a natural limit already, i.e. being able to use multiple files easily, and update scripts automatically sounds like a useful thing to me. I don't know if greasyfork supports &amp;quot;teams&amp;quot; of contributors for better collaboration ? It might also be a good idea to generalize the script so that it supports arbitrary phpBB installations and mailing list archives other than just sourceforge (think gmane) - and maybe output formats other than just wikimedia markup, that way, the script may become more useful over time.--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 13:46, 1 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
::::: It doesn't as it only offers a user script downloading facility (source code repositories like GitHub and SourceForge are better suited for the kind of work you mention). I'll wait a bit in case Red Leader, Philosopher or bigstones have any objections/remarks, then I'll upload the script there. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 17:14, 1 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:: do they support extensions spread across multiple files ? That is something that would help us quite a bit cleaning up the current code, which has become a bit convoluted over time. Apart from that, nothing wrong with github et al - I am just not sure if they're suitable for automatically propagating updated changes.--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 10:12, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
::: No, not that I know of (generally speaking, all user scripts are made of a single .user.js file). We could &amp;quot;hack&amp;quot; it by splitting the current script in multiple files and requiring them from a main one as libraries via the &amp;lt;tt&amp;gt;@include&amp;lt;/tt&amp;gt; directive, but that would rule out most hosting solutions (many providers only allow GreaseMonkey scripts which include additional files only from a handful of trusted domains/CDNs, for safety reasons).&lt;br /&gt;
::: As for propagating changes on GitHub and other code repository, the update URL must remain constant throughout the lifetime of the script. I'm sure this can be done on GitHub by publishing updates not as releases (where the addresses change), but on GitHub Pages (a user script I use does exactly this); on SourceForge, the usual download hosting could do the trick, but I'd need to perform a test first. (I'd prefer SF to keep the script &amp;quot;inside&amp;quot; the FG project hierarchy, if possible). -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 10:50, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
: actually, user scripts can be compromised of multiple files, e.g. via the require directive [http://stackoverflow.com/questions/8695459/is-it-possible-to-split-greasemonkey-user-scripts-into-multiple-files]. Personally, I would like to make use of that - we are already using that to include jQuery stuff, and it would help us organize the script a little better. I am not oposed to seeing the script hosted as some part of FG/SF, but I just don't think it's going to be a very popular idea - so far, everything worked out without major hinderance, so I would rather use an independent hosting solution, or continue to use the wiki to ensure that the barrier to entry/contributing isn't raised, e.g. by going through merge requests etc. Major contributions to the script like those from bigstones or Red Leader were simply &amp;quot;dropped&amp;quot; here directly, so this seems to have worked out really well.--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 11:26, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:: I've checked the [https://greasyfork.org/it/help/external-scripts GreasyFork external script policy]: as long as all the files are hosted on/uploaded to GreasyFork, it's not a problem. (Also, sorry about the typo, I wrote &amp;lt;tt&amp;gt;@include&amp;lt;/tt&amp;gt; instead of &amp;lt;tt&amp;gt;@require&amp;lt;/tt&amp;gt; by mistake). I guess I can proceed with the upload now? -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 12:22, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
: sure, why not - it's in the public domain after all - feel free to make any changes to the script to have it auto-update. We can review everything once we have gathered a little more experience with this kind of scheme. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 12:27, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:: {{done}} - I'm updating the installation instructions in the main page. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 13:52, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
::: Script at: https://greasyfork.org/en/scripts/19331-instant-cquotes &lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 14:18, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:::: Regarding updates, bumping the version number is fine - I'll take the script at the wiki revision where the version is bumped and upload it. (Note that I will not perform any prior testing, so be extra careful - maybe I should add this in the note above the script?). -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 18:08, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:: sounds good, I will be sure to stop updating the version number without prior testing, we could also add some tests to the code to spot the more obvious mistakes - in fact, there is already an OpenLink helper that could be used to download a few postings and try to extract the corresponding fields, so that we would only bump the version number if that succeeds. BTW: Thanks for handling the hosting part, much appreciated ! --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 18:25, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Issues ==&lt;br /&gt;
=== too greedy non-greedy regexes ===&lt;br /&gt;
The problem described in the previous section regarding regexes that eat up half messages seems to be related to my  [http://blog.liip.ch/archive/2009/07/24/the-greedyness-of-non-greedy-regular-expressions.html misunderstanding of the non-greediness]. So, I managed to fix it for this one case, but this means that using .*? to match everything until you meet the following character (as I currently do pretty much everywhere) is dangerous and prone to failure. Any occurrence of that should be changed as I did in [http://wiki.flightgear.org/index.php?title=FlightGear_wiki:Instant-Cquotes&amp;amp;oldid=72839 this edit] and that's clearly cumbersome, not to say that it can still be incorrect: say I have&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;a someprop=&amp;quot;href&amp;quot; href=&amp;quot;http://www.link.org&amp;quot; ... &amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
If I want to mach anything between a and href, I use &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;[^(?:href)]*&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;, but that would match only up to the text inside someprop, so I'd have to check that it's not inside doublequotes... Well, I guess this is getting too complicated for handling it [http://blog.codinghorror.com/parsing-html-the-cthulhu-way/ the Chtulu way].&lt;br /&gt;
&lt;br /&gt;
So my approach would be: fix this whenever the problem comes up, but don't overdo because we're already moving in dangerous ground. Or, rewrite it all using ''only'' xpaths *sobs*.&lt;br /&gt;
--[[User:Bigstones|Bigstones]] ([[User talk:Bigstones|talk]]) 16:49, 17 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
=== regex vectors ===&lt;br /&gt;
&lt;br /&gt;
When testing things I realized that you are right: there are some scenarios where the regex may fail depending on how &amp;quot;complete&amp;quot; the selection is, because we obviously have hard-coded assumptions here. I'll see if it's feasible to also support vectors for regexes to extract the corresponding fields and try each regex in order to get a certain field, or if that doesn't make any sense... But quoting with/without author (anonymous quote) would be a valid test case here.--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 16:46, 16 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
: Probably going to look into this sooner or later because this could be a simple solution to also support PM quoting - without having to parse the actual URL, we'd just try different regexes in order and use the one that succeeds. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 16:46, 16 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
=== Syntaxhighlighting ===&lt;br /&gt;
Need to investigate what needs to be updated to support quoting code sections, as per [http://forum.flightgear.org/viewtopic.php?f=66&amp;amp;t=21855&amp;amp;p=212585#p212581] --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 22:33, 14 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
=== Postings that break our script for some reason ===&lt;br /&gt;
* http://forum.flightgear.org/viewtopic.php?f=19&amp;amp;t=23365&lt;br /&gt;
&lt;br /&gt;
== Misc notes ==&lt;br /&gt;
&lt;br /&gt;
=== Detecting failed XPaths === &lt;br /&gt;
you've got a point, we should probably check if xpath/regexes succeed or fail, and show a warning so that we know that the scripts needs to be updated because some xpath/regex may have changed. &lt;br /&gt;
&lt;br /&gt;
=== Paragraphs / br (trailing slash) ===&lt;br /&gt;
There are some minor issues now, i.e. newline2br will no longer contain the trailing forward slash, so there's probably some JavaScript/regex oddity involved here, maybe slashes just need to be escaped. Will be testing the code with a few different forum postings and check the resulting cquote&lt;br /&gt;
: {{done}}. That's because newline2br wasn't used at all in html mode. I added addNewlines which puts newlines after br's and list related tags, if there are more newlines to be added that should be the place.&lt;br /&gt;
: --[[User:Bigstones|Bigstones]] ([[User talk:Bigstones|talk]]) 14:03, 17 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
=== support/ignore highlighted keywords/smilies ===&lt;br /&gt;
see [[Understanding Forward Compatibility]] for examples&lt;br /&gt;
: {{done}} --[[User:Bigstones|Bigstones]] ([[User talk:Bigstones|talk]]) 15:13, 17 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Beyond just cquotes (newsletter/changelog) ==&lt;br /&gt;
&lt;br /&gt;
Gijs has recently revamped the newsletter template rather significantly, see: [[FlightGear_Newsletter_June_2014]], and [[User_talk:Gijs#06.2F2014_newsletter:_too_much_of_a_]] - basically, we could extend the script to support another output FORMAT to directly create markup for the newsletter/changelog. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 20:40, 30 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
== more styles/output formats ==&lt;br /&gt;
&lt;br /&gt;
looking at some of the cleanup done by Red Leader recently, we could also directly support other styles/output formats to directly provide a format that looks well enough without requiring tons of manual editing. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 11:11, 13 February 2015 (EST)&lt;br /&gt;
&lt;br /&gt;
== token matching for keywords/variables ==&lt;br /&gt;
&lt;br /&gt;
seems like it might make sense to match common keywords/acronyms and variables, such as e.g.:&lt;br /&gt;
* FG_ROOT =&amp;gt; [[$FG_ROOT]]&lt;br /&gt;
* FG_HOME =&amp;gt;  [[$FG_HOME]]&lt;br /&gt;
* FG_SRC =&amp;gt; [[$FG_SRC]]&lt;br /&gt;
&lt;br /&gt;
file names with a known prefix like $FG_ROOT could even be pattern-matched using git link: $FG_ROOT/Nasal/canvas/MapStructure.nas would become [[$FG_ROOT]]{{Git link|gitorious|fg/fgdata|master|Nasal/canvas/MapStructure.nass|text=/Nasal/canvas/MapStructure.nas}}&lt;br /&gt;
&lt;br /&gt;
Equally, we could match common property paths to use code tags, e.g.: /sim/rendering would become &amp;lt;code&amp;gt;/sim/rendering&amp;lt;/code&amp;gt;&lt;br /&gt;
Ultimately, it might be a good idea to get in touch with Johan_G, Gijs and Red Leader to see what kind of format they'd prefer, especially because this could then be directly used for creating newsletter contents. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 11:19, 13 February 2015 (EST)&lt;br /&gt;
&lt;br /&gt;
== matching repository references using git link template ==&lt;br /&gt;
&lt;br /&gt;
Most of us commonly refer to repository files using either the $FG_* references, or relative paths in the form of &amp;lt;code&amp;gt;src/Main/fg_init.cxx:line number&amp;lt;/code&amp;gt;, we could automatically convert such references using the git/repo link template, e.g.: &lt;br /&gt;
&lt;br /&gt;
{{FGCquote&lt;br /&gt;
  |Further investigation found that the launcher *is* trying to add this directory to fg-aircraft (src/GUI/QtLauncher.cxx:772), but that this doesn't work because this option is processed before the launcher is run (intentionally, to allow the launcher to find aircraft in fg-aircraft: '''src/Main/main.cxx:448''').&lt;br /&gt;
  |{{cite web |url=http://sourceforge.net/p/flightgear/mailman/message/33686356/&lt;br /&gt;
     |title=&amp;lt;nowiki&amp;gt;Re: [Flightgear-devel] Launcher issues on Linux&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
     |author=&amp;lt;nowiki&amp;gt;Rebecca N. Palmer&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
     |date=&amp;lt;nowiki&amp;gt;2015-04-01&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
   }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 12:48, 1 April 2015 (EDT)&lt;br /&gt;
&lt;br /&gt;
== chrome specific port ==&lt;br /&gt;
&lt;br /&gt;
Hi Red Leader, when/if you do come up with a chrome specific version of the script, I would suggest to refactor existing APIs accordingly, so that we can come up with a common library of general purpose/utility helpers, so that both scripts can co-exist and use a common/shared file (think all the extraction/transformation logic), by referencing an external .js/JavaScript file that will be maintained/updated and hosted separately. I think this could be accomplished easily using jsfiddle. So basically, I am suggesting to come up with a shared back-end for both versions of the script. Given the complexity we're reaching meanwhile, as well as the number of edits and contributors, it may also make sense to consider using github for this at some point. One of the main advantages being that we could easily distribute updates automatically to all people who've installed the script, without them having to do anything manually.--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 08:38, 23 June 2015 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Development resources ==&lt;br /&gt;
&lt;br /&gt;
* https://www.youtube.com/watch?v=xpXNDT0SxM0&lt;br /&gt;
* http://wiki.greasespot.net/GM_getResourceText&lt;br /&gt;
* http://stackoverflow.com/questions/14594346/create-a-config-or-options-page-for-a-greasemonkey-script&lt;br /&gt;
&lt;br /&gt;
== Future focus/development and priorities (De-quoting) ==&lt;br /&gt;
&lt;br /&gt;
Given that most people involved in maintaining the wiki don't seem to particularly appreciate the nature of articles consisting mainly of quotes, and that we don't seem to have any other good way to populate new articles quickly, I was thinking of changing the focus of the script to dynamically create articles using quotes (with proper refs), that would be merely copy-edited, i.e. using the process we are currently using to &amp;quot;de-quote&amp;quot; such articles by 1) categorizing related quotes, 2) coming up with headers/sub-headers, 3) re-writing/merging certain quotes, 4) attributing them - linking back to the quotes archives.&lt;br /&gt;
Should we decide to pursue this, the script would be turned into a &amp;quot;wizard&amp;quot; where we can topics and sub-topics (wiki headings) and then add arbitrary text using the existing approach, but without using cquotes - i.e. the focus would be on extracting relevant contents, distilling them down and adding plenty of refs, including a references section at the bottom. Some tokens/words could be changed dynamically, but some kind of proof-reading/copy-editing would still need to be done afterwards, because people tend to use first person speech in their announcements/postings, which we would need to convert to 3rd person semi-automagically. Thoughts/ideas ?--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 07:11, 15 November 2015 (EST)&lt;br /&gt;
&lt;br /&gt;
== changing and automating regex/xpath handling ==&lt;br /&gt;
{{See also|#Genetic_Expression_solver}}&lt;br /&gt;
&lt;br /&gt;
We have currently hard-coded handling of different websites, regexes and xpath expressions so that things are a  bit fragile at the moment, and once a website changes its style/template, our script would break immediately. However, we could change the way the script works by using a very simple NN (neural network) to come up with matching regex/xpath expressions automatically. The way this could work would be &amp;quot;supervised&amp;quot; training, where we would replace/adapt our existing CONFIG hash with a vector of URLs and contents to be extracted (date, time, title, posting). This kind of data would suffice entirely for a neural network to self-train itself and &amp;quot;learn&amp;quot; how to come up with regex/xpath expressions to extract the relevant contents, including not only hard-coded websites like sourceforge, but even completely different websites (think gmane) - because the &amp;quot;learning&amp;quot; routine would self-adapt by looking at how to get its contents, and never contain any hard-coded regex/xpath expressions anymore. The CONFIG hash would end up being a vector with &amp;quot;training data&amp;quot; for different websites to be supported. And whenever an expression fails, it could re-train itself accordingly.--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 13:33, 15 November 2015 (EST)&lt;br /&gt;
&lt;br /&gt;
== nested quotes and AJAX for thread titles ==&lt;br /&gt;
&lt;br /&gt;
{{FGCquote&lt;br /&gt;
|1= http://sourceforge.net/p/flightgear/mailman/message/33451055/&lt;br /&gt;
{{cquote|As we move forward with FlightGear development and future versions, we will be expanding the &amp;quot;in app&amp;quot; aircraft center. This dialog inside flightgear lets you select, download, and switch to any of the aircraft in the library.|Curt}}&lt;br /&gt;
|2= {{cite web&lt;br /&gt;
  | url    = http://forum.flightgear.org/viewtopic.php?p=259879#p259879&lt;br /&gt;
  | title  = &amp;lt;nowiki&amp;gt;Re: New Canvas GUI&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  | author = &amp;lt;nowiki&amp;gt;Hooray&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  | date   = Oct 7th, 2015&lt;br /&gt;
  }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== AJAX mode/testing ==&lt;br /&gt;
&lt;br /&gt;
We should probably add a dialog to store credentials that we can use for accessing the wiki, which would need to be shown after installing the script, i.e. first-time use&lt;br /&gt;
&lt;br /&gt;
* http://stackoverflow.com/questions/14594346/create-a-config-or-options-page-for-a-greasemonkey-script&lt;br /&gt;
* http://commons.oreilly.com/wiki/index.php/Greasemonkey_Hacks/Getting_Started#During_Installation&lt;br /&gt;
* https://www.safaribooksonline.com/library/view/greasemonkey-hacks/0596101651/ch01s06.html&lt;br /&gt;
&lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 12:59, 20 November 2015 (EST)&lt;br /&gt;
&lt;br /&gt;
== libraries ==&lt;br /&gt;
&lt;br /&gt;
Referring to the [[#Hosting]] section, and my comment on wanting to use additional libs (like jQuery), I am primarily thinking about using a wizard-framework (e.g. jQuery steps) and a framework for creating wikimedia editor plugins (actions):&lt;br /&gt;
&lt;br /&gt;
* http://mstratman.github.io/jQuery-Smart-Wizard/&lt;br /&gt;
* http://www.jquery-steps.com/&lt;br /&gt;
* http://www.jqueryrain.com/demo/jquery-step-form-wizard/&lt;br /&gt;
* https://www.mediawiki.org/wiki/Extension:WikiEditor&lt;br /&gt;
&lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 12:07, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== About dequoting the script's article ==&lt;br /&gt;
&lt;br /&gt;
Thanks for doing this, but I am frankly not sure if it's worth the effort - there are much more popular/important articles using tons of quotes than this one, and given the reputation of the script, having quotes in this article may actually be a useful thing to make the case for having quotes in the first place - thus, I would frankly not spend much time going through this particular article - in fact, I'd be very surprised if the greasyfork download stats showed more than 3-5 people actually downloading, and using, the script - so this is really just a niche tool, and we probably better spend our time doing other things, and reviewing other wiki articles, than the script's article - at the very least, I would suggest to retain the references to the original discussions revolving these quotes (just my 2c). --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 19:00, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
: {{done}} I've added back the quotes as references. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 02:53, 3 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Script configuration (persistence) ==&lt;br /&gt;
&lt;br /&gt;
* https://wiki.greasespot.net/GM_config&lt;br /&gt;
* https://github.com/sizzlemctwizzle/GM_config/wiki&lt;br /&gt;
* https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API&lt;br /&gt;
&lt;br /&gt;
== Work in progress ==&lt;br /&gt;
&lt;br /&gt;
We have now several more or less related development efforts going on, and the code is also growing because of that - so it seems to make sense to summarize what's been going on recently. In general, all changes were made in response to the collection of feature requests and ideas we have accumulated over time  - specifically, that means that the following roadmap is in the process of being implemented:&lt;br /&gt;
&lt;br /&gt;
* establish unit testing, and add a few self-tests, so that the script can be more easily tested, updated/reviewed in the future&lt;br /&gt;
* rework the script to more easily support other sources (think gmane)&lt;br /&gt;
* make it much easier to update modified xpath/regex expressions (i.e. provide a UI for that)&lt;br /&gt;
* support persistence for script-specific settings&lt;br /&gt;
* make it easier for people to port/maintain the script by encapsulating platform specifics&lt;br /&gt;
* support asynchronous fetching of postings (AJAX), e.g. to fetch posting titles, attachments etc&lt;br /&gt;
* prepare the groundwork for supporting template-based output formats (think newsletter, changelog, articles)&lt;br /&gt;
* review what's necessary to allow the script to update fgcquote-based quotes automagically&lt;br /&gt;
&lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 16:47, 4 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== External genetic/neural network libraries ==&lt;br /&gt;
While uploading the latest version of the script, I noticed that the Genetic and Synaptic libraries are hosted on sites not on [https://greasyfork.org/en/help/external-scripts the approved GreasyFork list]. Shall I ask them to host them? -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 13:28, 11 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
: Thanks for pointing that out, I missed that completely, because everything is working correctly here - but obviously, I rarely get to actually download/install the latest version via greasyfork. Those libs should be safe to be added to the list, i.e. they're fairly established/popular, lest I'd not be using them. For now, this is just an experiment anyway. The idea is to update the xpath/regex code to evolve if/when the underlying website (theme) changes. But if there is a problem, we could use other libs - the code is just used for testing ATM. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 13:41, 11 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
* https://github.com/subprotocol/genetic-js&lt;br /&gt;
* https://github.com/cazala/synaptic&lt;br /&gt;
&lt;br /&gt;
:: {{ongoing}} I have submitted the libraries to the JSDelivr CDN; once they are up, I'll change the source URLs in the script and update it on GreasyFork as well. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 18:32, 17 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
::: Hi Elgaton, thank you for taking care of this, it's very much appreciated ! --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 18:55, 17 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:::: You're welcome! My merge requests for the CDN were approved (this took a bit longer than expected because I had made a small mistake - I forgot to include a file required by the Genetic.js library). The libraries should be up in a day or two, at which point I'll update the URLs in the script and submit the new version to GreasyFork. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 02:59, 20 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
::::: {{done}} Everything should be fine now. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 09:16, 20 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:: Thank you for all the help with this, and also for updating the greasyfork info/screenshots ! --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 07:16, 21 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Genetic Expression solver ==&lt;br /&gt;
[[File:Instant-cquotes-genetic-regex-solving.png|thumb|Screenshot showing the instant cquotes script with integrated regex solving support using genetic algorithms.]]&lt;br /&gt;
&lt;br /&gt;
The genetic-js framework has been integrated, it is intended to help solve xpath/regex expressions procedurally using genetic algorithms/programming. &lt;br /&gt;
&lt;br /&gt;
The idea is to provide a set of desired outputs (needles), available input data (haystack), and use existing (possibly outdated) regex/xpath expressions to seed a pool with potential solutions for retrieving the desired output. For now, this is just proof-of-concept, i.e. just an experiment.&lt;br /&gt;
&lt;br /&gt;
For example, let's consider the typical format of a from header for any sourceforge posting:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var regexTests = [&lt;br /&gt;
  {haystack: &amp;quot;From: John Doe &amp;lt;John@do...&amp;gt; - 2020-07-02 17:36:03&amp;quot;, needle: &amp;quot;John Doe&amp;quot;}, &lt;br /&gt;
  {haystack: &amp;quot;From: Marc Twain &amp;lt;Marc@ta...&amp;gt; - 2010-01-03 07:36:03&amp;quot;, needle: &amp;quot;Marc Twain&amp;quot;},&lt;br /&gt;
  {haystack: &amp;quot;From: George W. Bush &amp;lt;GWB@wh...&amp;gt; - 2055-11-11 17:33:13&amp;quot;, needle: &amp;quot;George W. Bush&amp;quot;}&lt;br /&gt;
];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The basic idea is to run a fitness function and score regex expressions based on not throwing an exception (which makes them valid), and by checking if the desired tokens are part of the output string, and evolve (mutate/cross-over) the &amp;quot;fittest&amp;quot; expressions - i.e. those that satisfy at least /some/ of the heuristics.&lt;br /&gt;
&lt;br /&gt;
Some of the metrics that can be used by the fitness function to determine if an expression is &amp;quot;fit&amp;quot;, are:&lt;br /&gt;
* valid expression&lt;br /&gt;
* relative offset/excess bytes in matches string&lt;br /&gt;
* number of examples it can successfully extract&lt;br /&gt;
* length of the expression&lt;br /&gt;
* runtime of the expression&lt;br /&gt;
&lt;br /&gt;
The search space, and runtime, can be significantly reduced by looking at similarities between all examples and coming up with a subset string that contains all identical components (e.g. the &amp;lt;code&amp;gt;From:&amp;lt;/code&amp;gt; part in the author regex) and use that for seeding the initial generations.&lt;br /&gt;
&lt;br /&gt;
Ultimately, this would allow the script to self-update its regex/xpath expressions if/when the underlying website (themes) change, but it would also allow to add support for new websites, without ever manually adding the required xpath/regex expressions, i.e. all that is needed is a sufficiently large number of example datasets to obtain the author, date and title information, and a URL for the script to download the HTML markup of the posting in question:&lt;br /&gt;
&lt;br /&gt;
{{Note|The date field won't work as is, because it's actually post-processed using a transformation function, so we'd need to undo the transformation or use the actual date string instead}}&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt; // vector with tests to be executed for sanity checks (unit testing)&lt;br /&gt;
    tests: [&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://sourceforge.net/p/flightgear/mailman/message/35059454/',&lt;br /&gt;
        author: 'Erik Hofman',&lt;br /&gt;
        date: 'May 3rd, 2016', // NOTE: using the transformed date here &lt;br /&gt;
        title: 'Re: [Flightgear-devel] Auto altimeter setting at startup (?)'&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://sourceforge.net/p/flightgear/mailman/message/35059961/',&lt;br /&gt;
        author: 'Ludovic Brenta',&lt;br /&gt;
        date: 'May 3rd, 2016',&lt;br /&gt;
        title: 'Re: [Flightgear-devel] dual-control-tools and the limit on packet size'&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://sourceforge.net/p/flightgear/mailman/message/20014126/',&lt;br /&gt;
        author: 'Tim Moore',&lt;br /&gt;
        date: 'Aug 4th, 2008',&lt;br /&gt;
        title: 'Re: [Flightgear-devel] Cockpit displays (rendering, modelling)'&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://sourceforge.net/p/flightgear/mailman/message/23518343/',&lt;br /&gt;
        author: 'Tim Moore',&lt;br /&gt;
        date: 'Sep 10th, 2009',&lt;br /&gt;
        title: '[Flightgear-devel] Atmosphere patch from John Denker'&lt;br /&gt;
      } // add other tests below&lt;br /&gt;
&lt;br /&gt;
    ], // end of vector with self-tests&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note how this no longer contains any hard-coded xpath/regex expressions - instead, the script can refer to the website specific defaults, and try those first, and if they fail, use those to seed new generations and evolve them procedurally until all tests succeed.&lt;br /&gt;
&lt;br /&gt;
For a regex to be valid, it must work for all tests/examples.&lt;br /&gt;
&lt;br /&gt;
Once the regex solver is working correctly, the code can be further generalized to also evolve xpath expressions (NOTE: the DOMParser API is /not/ available to webworkers ...) and chain those two components together.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* http://regex.inginf.units.it/how.html&lt;br /&gt;
* http://www.i-programmer.info/programming/perl/9503-automatically-generating-regular-expressions-with-genetic-programming.html&lt;br /&gt;
* http://jkff.info/articles/ire/&lt;br /&gt;
* http://www.networkworld.com/article/2955126/software/genetic-programming-meets-regular-expressions.html&lt;br /&gt;
* https://handcraftsman.wordpress.com/2012/04/11/evolving-a-regular-expression-with-go/&lt;br /&gt;
* http://stackoverflow.com/questions/4880402/how-to-auto-generate-regex-from-given-list-of-strings&lt;br /&gt;
* http://regex.inginf.units.it/&lt;br /&gt;
* http://www.genetic-programming.org/hc2014/Bartoli-Paper.pdf&lt;br /&gt;
&lt;br /&gt;
== Hierarchical Clustering  ==&lt;br /&gt;
&lt;br /&gt;
Been tinkering with a JavaScript module to automatically cluster postings based on certain keywords in the topic/title or posting (e.g. Nasal, Canvas, 2D API, rendering): https://harthur.github.io/clusterfck/&lt;br /&gt;
&lt;br /&gt;
Note that in conjunction with processing article sections and/or whole articles, this could help automatically come up with matching postings for articles and vice versa.&lt;br /&gt;
&lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 18:11, 19 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Upcoming dependencies ==&lt;br /&gt;
&lt;br /&gt;
The script is now using [http://markitup.jaysalvat.com/home/ markitup] to create the template editor. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 10:18, 21 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
: I've [https://github.com/jsdelivr/jsdelivr/pull/11757 submitted a pull request] for the library to be distributed by jsDelivr. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 16:08, 21 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:: Thank you, but please don't make this a priority: I only just realized that it is introducing a bunch of jQuery issues, and that the project hasn't been updated in years, so it probably makes more sense to use something else - i.e. the &amp;quot;integration&amp;quot; itself only takes 10 lines of code, but fixing all the jQuery compatibility issues, would be non-trivial. Thanks anyway. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 15:19, 22 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
::: {{Done}} -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 08:10, 27 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Code beautifier ? ==&lt;br /&gt;
&lt;br /&gt;
I still had, and have, pending changes that would need to go through the same beautifier you're using, or they'd be lost -  so for now, I have just overwritten your  beautified code, hope that you didn't do this manually (there really are tons of automated and configurable beautifiers out there). --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 15:59, 21 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
: Of course not - let me know when you've incorporated all changes so that I can beautify the script again. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 16:31, 21 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:: I have been using some web-based JavaScript syntax checking tools, too (e.g. www.jshint.com), so if it's a website, too - let's just share/document these tools here.--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 16:34, 21 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
::: I use [http://www.jslint.com JSLint] plus a bit of manual editing (if needed). -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 17:34, 21 May 2016 (EDT)&lt;/div&gt;</summary>
		<author><name>Elgaton</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=FlightGear_Git&amp;diff=98564</id>
		<title>FlightGear Git</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=FlightGear_Git&amp;diff=98564"/>
		<updated>2016-05-23T20:58:09Z</updated>

		<summary type="html">&lt;p&gt;Elgaton: /* Repositories and branches */ Add branch details for all repositories in fgmeta&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Git}}&lt;br /&gt;
'''Git''' is a {{wikipedia|version control system}} used by the [[FlightGear]] project to store all the files required to build and run the simulator. This includes all the programs, the data (e.g. textures, sounds), supporting tools, etc. Git tracks updates to every file as developers from around the world work together concurrently to create new versions. The sole exception is the official [[FGAddon]] aircraft repository that is Subversion rather than Git based.&lt;br /&gt;
&lt;br /&gt;
While new FlightGear features and additions are in development, they are available from Git before they are available in the standard release version. Using Git allows users to use the newest possible version of FlightGear from the latest source files, to experiment with new aircraft or other features. However, it is not a beginner's tool. Using Git can expose the user to unstable features that show ugly error messages, or crash the computer. &lt;br /&gt;
&lt;br /&gt;
As of May 2016, the repositories are located at {{Project infrastructure|name}}.&lt;br /&gt;
&lt;br /&gt;
== Motivation ==&lt;br /&gt;
In May 2010, after a hardware failure on the [[CVS]] servers, the FlightGear project changed its version control system from CVS to Git.&lt;br /&gt;
&lt;br /&gt;
Much has been written on the advantages of Git over CVS. For the FlightGear project, some advantages are:&lt;br /&gt;
* Much better support for branches and merging branches. This is especially important for creating bug fix releases for major releases while still allowing work on the next major release to continue. It is also very nice for a developer's personal workflow.&lt;br /&gt;
* Easier path for contributors to submit changes and developers to integrate them.&lt;br /&gt;
* Much better support for everyday tasks like searching the project history for changes, viewing changes, bisecting the project history to find the original source of a bug.&lt;br /&gt;
&lt;br /&gt;
== Repositories and branches ==&lt;br /&gt;
The FlightGear project is split up in the repositories listed below.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Name&lt;br /&gt;
! Contents&lt;br /&gt;
! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| {{simgear source|text=simgear}}&lt;br /&gt;
| The simulation engine that FlightGear uses.&lt;br /&gt;
| rowspan=&amp;quot;6&amp;quot; |&lt;br /&gt;
Those repositories have the following branches:&lt;br /&gt;
* ''next'': current tip of new development. This branch should always compile and run, but various things could be broken.&lt;br /&gt;
* ''release/*'': containing former and (if a specific branch was made for them) upcoming releases.&lt;br /&gt;
&lt;br /&gt;
As of May 2016, FGRun is in the process of being replaced by the [[Qt5 Launcher|Qt5 launcher]].&lt;br /&gt;
|-&lt;br /&gt;
| {{flightgear source|text=flightgear}}&lt;br /&gt;
| FlightGear itself.&lt;br /&gt;
|-&lt;br /&gt;
| {{fgdata source|text=fgdata}}&lt;br /&gt;
| All data (default aircraft, dialogs, sounds) used by FlightGear.&lt;br /&gt;
|-&lt;br /&gt;
| {{fgmeta source|text=fgmeta}}&lt;br /&gt;
| FlightGear &amp;quot;meta&amp;quot; repository containing build and setup scripts for the whole project.&lt;br /&gt;
|-&lt;br /&gt;
| {{windows-3rd-party source|text=windows-3rd-party}}&lt;br /&gt;
| Prebuilt libraries needed to make FlightGear run on Windows.&lt;br /&gt;
|-&lt;br /&gt;
| {{fgrun source|text=fgrun}}&lt;br /&gt;
| The [[FGRun]] launcher for FlightGear.&lt;br /&gt;
|-&lt;br /&gt;
| {{fgaddon source|text=fgaddon}}&lt;br /&gt;
| SVN repository that holds all official aircraft (except the [[Cessna 172P]] default plane and the [[UFO]]).&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| {{fgcom source|text=fgcom}}&lt;br /&gt;
| [[FGCom 3.0|FGCom]], a voice-over-IP application used by [[multiplayer]] controllers to provide [[Air traffic control|ATC services]].&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| {{getstart source|text=getstart}}&lt;br /&gt;
| Sources for the ''Getting Started'' manual included with the simulator.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| {{openradar source|text=openradar}}&lt;br /&gt;
| The [[OpenRadar]] application used by multiplayer controllers.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| {{sceneryweb source|text=sceneryweb}}&lt;br /&gt;
| Source code and configuration files for the [http://mapserver.flightgear.org/ Mapserver], the [https://scenery.flightgear.org/ scenery portal] and the [[TerraGear scenery build server]].&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| {{terragear source|text=terragear}}&lt;br /&gt;
| The [[TerraGear]] scenery building toolkit.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| {{terrafs source|text=terrafs}}&lt;br /&gt;
| A Linux tool to mount the TerraSync scenery as a remote file system.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| MacLauncher&lt;br /&gt;
| Old FlightGear launcher for Mac.&lt;br /&gt;
| Deprecated by the [[Qt5 Launcher|Qt5 launcher]].&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Related content ==&lt;br /&gt;
* [[FlightGear Git: splitting FGData]], an initiative to split the aircraft out of the FGData repository, in order to decrease its size and thus improve access to the average user/developer.&lt;br /&gt;
&lt;br /&gt;
{{Building}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Core developer documentation]]&lt;br /&gt;
[[Category:FlightGear]]&lt;br /&gt;
[[Category:Git]]&lt;br /&gt;
&lt;br /&gt;
[[fr:FlightGear et Git]]&lt;/div&gt;</summary>
		<author><name>Elgaton</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=FlightGear_Git&amp;diff=98563</id>
		<title>FlightGear Git</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=FlightGear_Git&amp;diff=98563"/>
		<updated>2016-05-23T20:24:08Z</updated>

		<summary type="html">&lt;p&gt;Elgaton: Use the {{Transclude|Project infrastructure}} template for the SF link; others to follow&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Git}}&lt;br /&gt;
'''Git''' is a {{wikipedia|version control system}} used by the [[FlightGear]] project to store all the files required to build and run the simulator. This includes all the programs, the data (e.g. textures, sounds), supporting tools, etc. Git tracks updates to every file as developers from around the world work together concurrently to create new versions. The sole exception is the official [[FGAddon]] aircraft repository that is Subversion rather than Git based.&lt;br /&gt;
&lt;br /&gt;
While new FlightGear features and additions are in development, they are available from Git before they are available in the standard release version. Using Git allows users to use the newest possible version of FlightGear from the latest source files, to experiment with new aircraft or other features. However, it is not a beginner's tool. Using Git can expose the user to unstable features that show ugly error messages, or crash the computer. &lt;br /&gt;
&lt;br /&gt;
As of May 2016, the repositories are located at {{Project infrastructure|name}}.&lt;br /&gt;
&lt;br /&gt;
== Motivation ==&lt;br /&gt;
In May 2010, after a hardware failure on the [[CVS]] servers, the FlightGear project changed its version control system from CVS to Git.&lt;br /&gt;
&lt;br /&gt;
Much has been written on the advantages of Git over CVS. For the FlightGear project, some advantages are:&lt;br /&gt;
* Much better support for branches and merging branches. This is especially important for creating bug fix releases for major releases while still allowing work on the next major release to continue. It is also very nice for a developer's personal workflow.&lt;br /&gt;
* Easier path for contributors to submit changes and developers to integrate them.&lt;br /&gt;
* Much better support for everyday tasks like searching the project history for changes, viewing changes, bisecting the project history to find the original source of a bug.&lt;br /&gt;
&lt;br /&gt;
== Repositories and branches ==&lt;br /&gt;
The FlightGear project is split up in the repositories listed below.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Name&lt;br /&gt;
! Contents&lt;br /&gt;
! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| {{simgear source|text=simgear}}&lt;br /&gt;
| The simulation engine that FlightGear uses.&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |&lt;br /&gt;
Those repositories have the following branches:&lt;br /&gt;
* ''next'': current tip of new development. This branch should always compile and run, but various things could be broken.&lt;br /&gt;
* ''release/*'': containing former and (if a specific branch was made for them) upcoming releases.&lt;br /&gt;
|-&lt;br /&gt;
| {{flightgear source|text=flightgear}}&lt;br /&gt;
| FlightGear itself.&lt;br /&gt;
|-&lt;br /&gt;
| {{fgdata source|text=fgdata}}&lt;br /&gt;
| All data (default aircraft, dialogs, sounds) used by FlightGear.&lt;br /&gt;
|-&lt;br /&gt;
| {{fgaddon source|text=fgaddon}}&lt;br /&gt;
| SVN repository that holds all official aircraft (except the [[Cessna 172P]] default plane and the [[UFO]]).&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| {{fgrun source|text=fgrun}}&lt;br /&gt;
| The [[FGRun]] launcher for FlightGear.&lt;br /&gt;
| As of May 2016, in the process of being replaced by the [[Qt5 Launcher|Qt5 launcher]].&lt;br /&gt;
|-&lt;br /&gt;
| {{windows-3rd-party source|text=windows-3rd-party}}&lt;br /&gt;
| Prebuilt libraries needed to make FlightGear run on Windows.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| {{fgmeta source|text=fgmeta}}&lt;br /&gt;
| FlightGear &amp;quot;meta&amp;quot; repository containing build and setup scripts for the whole project.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| {{fgcom source|text=fgcom}}&lt;br /&gt;
| [[FGCom 3.0|FGCom]], a voice-over-IP application used by [[multiplayer]] controllers to provide [[Air traffic control|ATC services]].&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| {{getstart source|text=getstart}}&lt;br /&gt;
| Sources for the ''Getting Started'' manual included with the simulator.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| {{openradar source|text=openradar}}&lt;br /&gt;
| The [[OpenRadar]] application used by multiplayer controllers.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| {{sceneryweb source|text=sceneryweb}}&lt;br /&gt;
| Source code and configuration files for the [http://mapserver.flightgear.org/ Mapserver], the [https://scenery.flightgear.org/ scenery portal] and the [[TerraGear scenery build server]].&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| {{terragear source|text=terragear}}&lt;br /&gt;
| The [[TerraGear]] scenery building toolkit.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| {{terrafs source|text=terrafs}}&lt;br /&gt;
| A Linux tool to mount the TerraSync scenery as a remote file system.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| MacLauncher&lt;br /&gt;
| Old FlightGear launcher for Mac.&lt;br /&gt;
| Deprecated by the [[Qt5 Launcher|Qt5 launcher]].&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Related content ==&lt;br /&gt;
* [[FlightGear Git: splitting FGData]], an initiative to split the aircraft out of the FGData repository, in order to decrease its size and thus improve access to the average user/developer.&lt;br /&gt;
&lt;br /&gt;
{{Building}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Core developer documentation]]&lt;br /&gt;
[[Category:FlightGear]]&lt;br /&gt;
[[Category:Git]]&lt;br /&gt;
&lt;br /&gt;
[[fr:FlightGear et Git]]&lt;/div&gt;</summary>
		<author><name>Elgaton</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Template_talk:Project_infrastructure&amp;diff=98562</id>
		<title>Template talk:Project infrastructure</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Template_talk:Project_infrastructure&amp;diff=98562"/>
		<updated>2016-05-23T20:23:38Z</updated>

		<summary type="html">&lt;p&gt;Elgaton: /* Other URLs */ Add scenery portal&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hijack ==&lt;br /&gt;
&lt;br /&gt;
@Hooray:  This idea is too useful, so I might hijack it ;)  I'll move this from {{tl|Project URL}} to {{tl|project infrastructure}}.  Then the default option can be mode=url.  I would like to have a mode=name returning SourceForge, and mode=abbrev returning sf.  I will then use this in the {{tl|repo link}} family of templates to make the subtemplates 100% independent of the current infrastructure, so that the links will be timeless :)  This single template could end up being the sole reference to SourceForge and other infrastructure on the whole wiki.&lt;br /&gt;
&lt;br /&gt;
[[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 02:08, 26 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
yes, that was the idea - I was just expecting to spend a few weeks doing this, and not to come back realizing that you finished the whole thing in a few hours. So, thank you very much for doing this. It is good for us to learn from the sourceforge transition and try to prevent certain issues in the future.--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 06:43, 26 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
== Forum  ==&lt;br /&gt;
&lt;br /&gt;
probably need to extend the template a little to support this use-case: http://wiki.flightgear.org/index.php?title=Template:Forum&amp;amp;action=history&lt;br /&gt;
&lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 06:28, 26 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
: I guess an optional 'urn' parameter for appending to the URL, as well as a 'text' parameter to change the name of the link would do.  Then {{tl|forum}} could transclude this template.&lt;br /&gt;
&lt;br /&gt;
: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 06:56, 26 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: Done.&lt;br /&gt;
&lt;br /&gt;
:: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 08:38, 26 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
: Thank you, I just used this to implement this [[Template_talk:Project_infrastructure#Unified_search_handling]] --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 11:13, 17 April 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Other URLs ==&lt;br /&gt;
&lt;br /&gt;
* mumble servers, also to help us deal with incidents like [http://wiki.flightgear.org/index.php?title=Mumble&amp;amp;oldid=97410]&lt;br /&gt;
* scenemodels.flightgear.org&lt;br /&gt;
* scenery.flightgear.org&lt;br /&gt;
* liveries.flightgear.org&lt;br /&gt;
* multiplayer map&lt;br /&gt;
* add ticket/issue tracker template here ?&lt;br /&gt;
* FGCom server&lt;br /&gt;
* Lenny's ATC website&lt;br /&gt;
&lt;br /&gt;
== Some suggestions ==&lt;br /&gt;
First off, implement this step by step, and think the architecture through during the process.  Do not lock yourself in early.&lt;br /&gt;
&lt;br /&gt;
I still have frustrations with annoying inconsistencies and non user friendly naming schemes in the FlightGear screenshot categories due to &amp;quot;flash-implementing&amp;quot; early ideas before thinking them through thoroughly.&lt;br /&gt;
&lt;br /&gt;
—[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 16:26, 27 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: just for the record, I do agree with this, but on the other hand, had bugman not taken my original idea and developed it much further, I would still be dabbling that - so, basically within a few hours, bugman went through several iterations of this, without needing much in terms of feedback, and I am pretty satisfied with it personally. I do get your point though, so I would suggest to document &amp;quot;best practices&amp;quot; - I am not much a wiki guru myself, I really only use a tiny fraction of its markup/features, and I am always glad for your contributions to my templates, because it's not something that I am very good at/interested in - I would rather write php/javascript code than having to memorize wikimedia templates myself. But if there is anything that we/I can do better to lighten your workload (Johan, Red Leader, Gijs), please just document your suggestions somewhere. In terms of the overall idea here, I believe it is the right thing to do, and while it my not address all your concerns, it is certainly better than the existing practice - and had we done this a few years ago, we would not be having certain problems now. So I would politely suggest that &amp;quot;we should not let the perfect be the enemy of the good&amp;quot; here, this isn't core development after all - it's just a wiki, and anything that helps reduce our workload is a good thing, until someone comes up with something better somewhere down the road. All in all, let's also keep [http://forum.flightgear.org/viewtopic.php?f=42&amp;amp;p=277816#p277816 this] in mind (which may have no immediate repercussions at all, or which may have unfortunate side effects in a few years/months. So, thanks again bugman for all you have handled so far - it's certainly much better, and much faster, than anything that I could have come up with in this timeframe, and I am very impressed with the quality of your wiki involvement - then again, thanks also to Johan for providing the kind of feedback that bugman asked for - but please let's not overthink this... Talking about the &amp;quot;architecture of a template&amp;quot; is a bit too much for my own taste --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 19:53, 27 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
=== The mode parameter ===&lt;br /&gt;
I think the '''mode''' parameter is slightly ambiguous and maybe misleading.  I would expect it to be something like for example '''type''' or '''infrastructure''' rather than '''mode'''.&lt;br /&gt;
&lt;br /&gt;
As this is an unnamed parameter this is merely a change in the documentation.&lt;br /&gt;
&lt;br /&gt;
—[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 16:26, 27 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
: I agree.  This was just a quick and random choice, as I've been generating a lot of template content very quickly recently with the aim of having practical and functional implementations.  So no real thought has gone into this.  I'd suggest '''type''' to allow this template to be a universal resource.&lt;br /&gt;
&lt;br /&gt;
: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 16:37, 27 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
=== The name value of the mode parameter ===&lt;br /&gt;
I would say that even though it is an important ''part'' of the project infrastructure SourceForge is merely the host of the main repositories.&lt;br /&gt;
&lt;br /&gt;
Here I would probably rather expect something like for example '''host''' or '''main-repo''' rather than '''name'''.&lt;br /&gt;
&lt;br /&gt;
—[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 16:26, 27 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
: Again a random and quick choice :)  What about '''provider'''?  Though SF is not the provider of everything FG related, so something along the lines of '''main...''' might be good.  I have no real preference - this is the default value of the ex-'''mode''' parameter, so you wouldn't normally use it when transcluding anyway.&lt;br /&gt;
&lt;br /&gt;
: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 16:44, 27 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
=== Slight variation of the current architecture ===&lt;br /&gt;
This might make for a slightly more complex template, but consider this:&lt;br /&gt;
&lt;br /&gt;
 {{obr}}project infrastructure|''infrastructure''|''attribute''{{cbr}}&lt;br /&gt;
&lt;br /&gt;
All parameters would be optional optional.  If none is given it could e.g. default to the URL of the project page at SourceForge.&lt;br /&gt;
&lt;br /&gt;
:; infrastructure:  Name of the infrastucture, e.g. '''forum''', '''wiki''', '''main-repo''', '''scenedb''' or '''website'''.  Could e.g. default to '''main-repo'''&lt;br /&gt;
:; attribute:  One of several attributes associated with the infrastructure, e.g. '''name''', '''abbreviation''', '''url''', '''host''' etc.  Could e.g. default to '''url'''&lt;br /&gt;
&lt;br /&gt;
I think the template would be slightly more flexible this way.&lt;br /&gt;
&lt;br /&gt;
It could be implemented with two levels of &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;{{#switch: }}&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; parser functions and use the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;#default =&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; case to catch most errors. Something like:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;{{#switch: {{{1|main-repo}}}&lt;br /&gt;
 | wiki = {{#switch: {{{2|url}}}&lt;br /&gt;
   | name = FlightGear wiki&lt;br /&gt;
   | short-name = wiki&lt;br /&gt;
   | url = http://wiki.flightgear.org&lt;br /&gt;
   | #default = {{error|Attribute '''{{{2}}}''' invalid for infrastructure '''wiki'''|project infrastructure}}&lt;br /&gt;
  }}&lt;br /&gt;
 | main-repo = {{#switch: {{{2|url}}}&lt;br /&gt;
   | name = Main FlightGear repository&lt;br /&gt;
   | short-name = main repo&lt;br /&gt;
   | host-name = SourceForge&lt;br /&gt;
   | host-short-name = SF&lt;br /&gt;
   | host-url = http://www.sourceforge.com&lt;br /&gt;
   | url = http://sourceforge.net/projects/flightgear/&lt;br /&gt;
   | #default = {{error|Attribute '''{{{2}}}''' invalid for infrastructure '''main-repo'''|project infrastructure}}&lt;br /&gt;
  }}&lt;br /&gt;
 | #default = {{error|Invalid '''infrastructure''' parameter|project infrastructure}}&lt;br /&gt;
}}&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The template documentation should probably be complemented by a table of available infrastructure and attribute combinations.&lt;br /&gt;
&lt;br /&gt;
—[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 16:26, 27 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
: Please feel free to change :)  This all sounds great.  My focus is on recursive transclusion for simply pulling out '''sf''', so we can pragmatically change the behaviour of templates.  I can quickly adapt all usage of this template to match.  For example {{tl|flightgear source}} uses it to completely avoid the SourceForge reference, to then pass it into the now very powerful {{tl|repo link}} template.  The table idea is good as well.  It could replace the examples section by absorbing the examples.  I just have some suggestions:&lt;br /&gt;
&lt;br /&gt;
:* A '''code''' value for the second option (replacing '''abbrev''').  This would return '''sf'''.  This would be used as a simple internal wiki code for programmatically changing template behaviour.&lt;br /&gt;
:* Alphabetical ordering of values in the switches, in case this becomes quite big.&lt;br /&gt;
:* '''url''' return values of &amp;lt;nowiki&amp;gt;[http://wiki.flightgear.org FlightGear wiki]&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
:* '''main-repo''' name as &amp;quot;Main FlightGear infrastructure&amp;quot;, as this is a collection of repositories, plus a lot of other FG infrastructure.  Maybe '''main-infrastructure''' would be better for a value, though it is a little long.  What about just '''main'''?&lt;br /&gt;
&lt;br /&gt;
: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 17:02, 27 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: Is that ok for you?  Only after I posted the above I saw how many places this template touches already.  Though still I would like to have it done.&lt;br /&gt;
&lt;br /&gt;
::* I am not sure I understand your first point. Is this for a switch in the templates?&lt;br /&gt;
::* Good point about alphabetical ordering of the attributes/values of the switches.&lt;br /&gt;
::* I would rather expect '''url''' to return a clean and somewhat more reusable url like &amp;lt;nowiki&amp;gt;http://wiki.flightgear.org&amp;lt;/nowiki&amp;gt;.  How about a '''link''' attribute to return the external link like &amp;lt;nowiki&amp;gt;[http://wiki.flightgear.org FlightGear wiki]&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
::* I am ok with '''main''' (even though I find it a slight bit ambiguous ;-)  ).&lt;br /&gt;
:: —[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 18:35, 27 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: I think I have a better grip on what you and Hooray are aiming for now.  You basically want to be able to get a link (with optional custom label), a name and the possibility to add an &amp;quot;URN&amp;quot; (not really an URN per see though ;-) ).&lt;br /&gt;
:: An early draft can be found at [[User:Johan G/project infrastructure]].&lt;br /&gt;
:: —[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 20:29, 27 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
::: For the first point, it would be a switch.  It would be used for auto-content generation within other templates, the {{tl|repo link}} template being the prime example.  For such an internal code, an ideal would be for the code to be returned by default, so that {{obr}}project infrastructure{{cbr}} returns '''sf'''.  These could be two letter codes. I'll make a proper table when I'm not on a mobile device.  E.g. sf=SourceForge, gh=GitHub, gl=GitLab, go=Gitorious, gs=Gnu Savannah, ga=Gna!, etc.&lt;br /&gt;
&lt;br /&gt;
::: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 05:57, 28 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
::: Something like this, for maybe placing into {{tl|project infrastructure/doc internal codes}} (for transclusion into templates that use the internal codes):&lt;br /&gt;
&lt;br /&gt;
::: {| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Open source infrastructure&lt;br /&gt;
!Internal code&lt;br /&gt;
|-&lt;br /&gt;
| [https://sourceforge.net/ SourceForge]&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | '''sf'''&lt;br /&gt;
|-&lt;br /&gt;
| [https://github.com/ GitHub]&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | '''gh'''&lt;br /&gt;
|-&lt;br /&gt;
| [https://gitlab.com/ GitLab]&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | '''gl'''&lt;br /&gt;
|-&lt;br /&gt;
| [https://gitorious.org/ Gitorious]&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | '''go'''&lt;br /&gt;
|-&lt;br /&gt;
| [https://savannah.gnu.org/ GNU Savannah]&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | '''gs'''&lt;br /&gt;
|-&lt;br /&gt;
| [http://gna.org/ Gna!]&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | '''ga'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
::: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 07:39, 28 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
::: I intend that switching between these internal codes solely within this template will fully switch the entire wiki from one open source infrastructure to another ;)  Obviously this will take a lot of work, and a number references to old Gitorious infrastructure must stay (until the repository is migrated by the original author elsewhere).  But I hope that searches for gitorious.org, sourceforge.net, etc. will return only a handful of hits on the wiki in the future.  Anyway, I really like the double switch design.  That is far more flexible and will allow for far better abstraction of the entire wiki contents.  And, from a practical sense, it is very easy to expand on.&lt;br /&gt;
&lt;br /&gt;
::: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 12:10, 28 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: I agree with bugman's goals - just look at the recently announced sale of Sourceforge/Slashdot and what that may /possibly/ mean for the project (and our wiki) sometime in the future, so it is better to &amp;quot;isolate&amp;quot; ourselves from these kinds of changes (external factors), so that the project can more easily adapt itself under such circumstances, helping lower the amount of work necessary to maintain/update the wiki accordingly is a very good idea in my opinion - and I would prefer that we review other parts of the wiki (and other project infrastructure) accordingly.--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 15:25, 28 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
::::: Having looked through how the template actually is used and what its purpose really is some days ago I noted that (at least as of now) the only real gain from my suggestion is an ever so slight bit more consistency and flexibility and a little less typing, but for the price of touching all the pages the template is used on.  I wonder if it would worth it.  If not, sorry for the noise.&lt;br /&gt;
::::: —[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 14:33, 4 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:::::: This is an illusion from transclusion ;)  The number of articles using this is actually quite low.  I have used it for all of the {{tl|repo link}} subtemplates, so any page that uses one of these subtemplates will appear in a [[Special:WhatLinksHere]] search.  I think your idea is great for improving this as a general framework.  It allows wiki text to be written in a way that would remain relevant when, in the distant future, another major infrastructure change is required.  It would extend its usefulness for abstracting away the infrastructure information so that old wiki pages can remain relevant for the decades to come.&lt;br /&gt;
&lt;br /&gt;
:::::: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 18:23, 4 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:::::: Actually, its only used for the FlightGear specific subset.  Also, most of those hits correspond to old Gitorious links that had been dead links for over a year now, and that I have recently fixed in the last few days using the {{tl|repo link}} subtemplates.&lt;br /&gt;
&lt;br /&gt;
:::::: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 18:54, 4 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
::::::: Ok then. :-)  How about [[User:Johan G/project infrastructure|this]] ([http://wiki.flightgear.org/index.php?title=User:Johan_G/project_infrastructure&amp;amp;oldid=95141 perm])?&lt;br /&gt;
::::::: —[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 02:27, 8 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:::::::: This looks great :)  It's much more flexible for extending the template functionality, and much better organised.  From my side, only the FlightGear specific templates listed at [[Template:Repo_link/doc_related]] would need updating.  I think Hooray has a few too.&lt;br /&gt;
&lt;br /&gt;
::::::::[[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 02:57, 8 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:::::::: Johan, I think it is time to convert this template to your new design ;)  There will be a few breakages, but the {{tl|repo link}} family of templates are safe.&lt;br /&gt;
&lt;br /&gt;
:::::::: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 18:57, 14 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
=== Unified search handling ===&lt;br /&gt;
&lt;br /&gt;
* Idea: [[Template:Search]]&lt;br /&gt;
* Motvation: [[Skydiving#Related]]&lt;br /&gt;
&lt;br /&gt;
Depending on what we come up with, this may either be integrated with the main template or refactored to be useful elsewhere.&lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 11:11, 17 April 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Abstraction of internal design changes using subtemplates ==&lt;br /&gt;
I was thinking that we could avoid disruptions to the {{tl|repo link}} family of subtemplates and anything else that uses {{tl|project infrastructure}} by using subtemplates.  For the internal codes used by other templates to switch between SourceForge, GitHub, GitLab, Gitorious, etc., we could have {{tl|project infrastructure/code}} that simply returns the 2 letter code via {{tl|project infrastructure}}.  This could be used as an abstraction mechanism so that all design changes to {{tl|project infrastructure}} would simply require the subtemplates to be updated.  Any other wiki pages using the subtemplates will be unaffected.&lt;br /&gt;
&lt;br /&gt;
[[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 13:32, 7 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
: I have created a temporary {{tl|project infrastructure/code}} subtemplate, and all of the {{tl|repo link}} templates now use this instead of {{tl|project infrastructure}} directly.  Therefore changing this template will not disrupt any pages that transclude the {{tl|repo link}} subtemplates.  The following templates might also need a similar strategy, or they are updated simultaneously.  Hooray, could you maybe help complete this list?&lt;br /&gt;
&lt;br /&gt;
: '''Templates and pages directly dependent on {{tl|project infrastructure}}''':&lt;br /&gt;
:* {{tl|project infrastructure/code}}&lt;br /&gt;
:* {{tl|forum}}&lt;br /&gt;
&lt;br /&gt;
: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 11:04, 15 March 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:: Sorry, I completely missed that you asked me to help with something - if that's still an issue, what exactly should I help complete ? --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 10:38, 17 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
::: Nope, that was just to help Johan make the transition to the newer and more flexible design.  When he makes the change, the {{tl|repo link}} templates will not be affected.  Then I'll switch the {{tl|project infrastructure/code}} subtemplate to use this template, or revert {{tl|repo link}} to use it directly.&lt;br /&gt;
&lt;br /&gt;
::: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 10:50, 17 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Related mailing list templates ==&lt;br /&gt;
&lt;br /&gt;
See:&lt;br /&gt;
* http://wiki.flightgear.org/Template:Mailing_list_e-mail_address&lt;br /&gt;
* http://wiki.flightgear.org/Template:Mailing_list_subscription_link&lt;br /&gt;
* http://wiki.flightgear.org/Template:Mailing_list_archive&lt;br /&gt;
* [[Template:Gmaneref]]&lt;br /&gt;
&lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 12:12, 5 May 2016 (EDT)&lt;/div&gt;</summary>
		<author><name>Elgaton</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=FlightGear_wiki:Village_pump&amp;diff=98552</id>
		<title>FlightGear wiki:Village pump</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=FlightGear_wiki:Village_pump&amp;diff=98552"/>
		<updated>2016-05-23T18:11:38Z</updated>

		<summary type="html">&lt;p&gt;Elgaton: /* Reorganizing the Git articles */ Screenshot templates&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Archives|[[/Archive 2012|2012]]|[[/Archive 2013|2013]]|[[/Archive 2014|2014]]|[[/Archive 2015|2015]]}}&lt;br /&gt;
{{shortcut|FGW:VP}}&lt;br /&gt;
Welcome to the '''Village Pump'''. This page is used to discuss the technical issues, operations and guidelines of the [[FlightGear wiki]].&lt;br /&gt;
&lt;br /&gt;
Please &amp;lt;span class=&amp;quot;plainlinks&amp;quot;&amp;gt;[{{fullurl:{{FULLPAGENAME}}|action=edit&amp;amp;section=new}} add new topics]&amp;lt;/span&amp;gt; to the '''bottom''' of this page.&lt;br /&gt;
&lt;br /&gt;
Old discussion should be moved to a [[FlightGear wiki:Village pump/Archive YEAR]]. These discussions can then be moved to a relevant talk page if appropriate.&lt;br /&gt;
&lt;br /&gt;
== Welcome template? ==&lt;br /&gt;
I have been thinking about suggesting a welcome template, for example named {{obr}}welcome{{cbr}}, to place on top of (at least) new users user discussion pages.&lt;br /&gt;
&lt;br /&gt;
It should welcome the (new) user&lt;br /&gt;
&lt;br /&gt;
In addition, it should probably mention and/or link to pages mentioning:&lt;br /&gt;
* The introduction page/tutorial (Hmm, I do not think I did finish that one. See [[Help talk:Tutorial]] ([http://wiki.flightgear.org/index.php?title=Help_talk:Tutorial&amp;amp;oldid=70843 perm])).&lt;br /&gt;
* Help pages&lt;br /&gt;
* How to use categories (in particular not like #tags, ;-) but also that image and article categories should be separate, but link to each other)&lt;br /&gt;
* The portals&lt;br /&gt;
* The style manual&lt;br /&gt;
* Discussion pages and where to discuss what:&lt;br /&gt;
** How to use discussion pages&lt;br /&gt;
** The wiki in general:  The village pump (this page)&lt;br /&gt;
** Wiki articles:  Article discussion pages&lt;br /&gt;
** Wiki user actions:  User discussion pages&lt;br /&gt;
&lt;br /&gt;
Maybe it should also mention that FGAddon aircraft, effects, other features etc. (except for their articles) and their bugs should be discussed on the forum, unless developers say otherwise, and that core features should be discussed on the developer mailing list and core bugs on the bug tracker.&lt;br /&gt;
&lt;br /&gt;
—[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 20:31, 30 January 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
: I think this is a great idea.  A nice concise summary with links to help a new user navigate the FlightGear jungle would be a great addition.  It should however remain very short with simple sentences - while being complete - as many users are not native speakers.  So maybe there should be translations of the template with manually added links at the bottom for easy access to all the translations?&lt;br /&gt;
&lt;br /&gt;
: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 03:35, 12 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: Regarding an introduction article, I have come to the conclusion that a complete but long article is probably not as helpful as short but specific help pages.  In essence the latter would be easier to navigate and absorb.  I have therefore started to slowly split up some of the help pages and have added one more section to [[Help:Contents]].&lt;br /&gt;
:: I think that a welcome phrase, a link to that page and the [[FlightGear wiki:Manual of Style|style manual]] might actually suffice for a welcome template for now.  It is at least better than what we currently have (i.e. more or less nothing).&lt;br /&gt;
:: —[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 14:47, 4 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: I now consider&lt;br /&gt;
::* A Welcome message&lt;br /&gt;
::* A link to this page&lt;br /&gt;
::* A link to the help pages&lt;br /&gt;
::* A link to the manual of style&lt;br /&gt;
::* Some final welcoming words&lt;br /&gt;
&lt;br /&gt;
:: A welcome template should probably also very briefly mention a pet peeve of mine: the categories.&lt;br /&gt;
:: Many (if not most) image uploaders seem to treat them like tags, but if say all screenshots of aircraft (probably &amp;gt;2000) would end up at [[:Category:Aircraft]] (instead of under a subcategory to [[:Category:Screenshots of aircraft]]), of what use would that page be when looking for a specific one?  If people would like to be able to search for an aircraft, a concise but comprehensive image description is very hard to beat.&lt;br /&gt;
:: How do I convey all that in a way that is, short, to the point and easy to absorb (and act by)? And where is the best place?&lt;br /&gt;
:: —[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 02:46, 8 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: An early draft is now at [[User:Johan G/Template:Welcome to the wiki]]&lt;br /&gt;
:: —[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 02:52, 18 April 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
::: Some comments on the draft:&lt;br /&gt;
::: * I'm not fully sure about using a prominent box - I think it stands out a bit too much. Wikipedia {{wikipedia|Template:Welcome|uses a simple thread on the Talk page}}; as an alternative, we could use lighter colors.&lt;br /&gt;
::: * I've also expanded the text a bit. My proposal would be (I've put it in a box, but I'm for the &amp;quot;thread&amp;quot; solution):&lt;br /&gt;
&amp;lt;div style=&amp;quot;background: #fff; border: 1px #585858 solid; padding: 12px; margin: 12px&amp;quot;&amp;gt;&lt;br /&gt;
[[Image:Example.png|left]] '''Welcome to the FlightGear wiki, {{#if: {{{name|}}} | {{{name}}} | {{BASEPAGENAME}}}}'''! We hope you will enjoy your stay!&lt;br /&gt;
&lt;br /&gt;
See [[Help:Contents#Reading|Reading]] to learn how wikis work. You can also [[Special:CategoryTree/Root category|browse the existing page categories]].&lt;br /&gt;
&lt;br /&gt;
Should you wish to create or edit some articles, ''do so''! Here are some resources to get you started:&lt;br /&gt;
* [[Help:Contents#Editing|How to edit pages]]&lt;br /&gt;
* [[Help:Discussion pages|Discussion pages]], where we discuss and agree on potential improvements&lt;br /&gt;
* [[FlightGear wiki:Manual of Style|The Manual of Style]], a set of guidelines to help editors maintain a consistent style and formatting (please follow them)&lt;br /&gt;
* [[Help:Contents|Wiki help page]]&lt;br /&gt;
&lt;br /&gt;
If you have any questions, just start a topic on the [[FlightGear wiki:Village pump|''Discuss!'' page]]. Again, welcome!&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
::: ...where the image on the left is an appropriately chosen icon.&lt;br /&gt;
::: Finally, we could use the {{mediawiki|Extension:NewUserMessage|NewUserMessage extension}} to have the wiki software automatically post the message to the new user's talk page.&lt;br /&gt;
::: ---- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 17:30, 1 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Permanently removing spam bots ==&lt;br /&gt;
For permanently removing spam bots, has the [https://www.mediawiki.org/wiki/Extension:UserMerge UserMerge] Mediawiki extension been considered?  I use that regularly on [http://wiki.nmr-relax.com my own wiki], though there we have also reverted to communicating to the person via email before manually granting access (probably not an option here), as all of the Mediawiki captcha methods were recently cracked.&lt;br /&gt;
&lt;br /&gt;
[[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 03:15, 12 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
: Oh, for the extension, we simply have a user called 'Spam bot' in a blocked state, and merge the spam bot accounts into this one, deleting the old account.&lt;br /&gt;
: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 03:20, 12 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: I'd use the [https://www.mediawiki.org/wiki/Extension:AbuseFilter abuse filter extension] instead (much more powerful and automated) - other users have also proposed different remedies, see [http://forum.flightgear.org/viewtopic.php?f=42&amp;amp;t=28734 this forum thread]. Anyway, Gijs is going to upgrade MediaWiki shortly and review the current anti-spam measures.&lt;br /&gt;
:: -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 06:26, 13 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
::: A lot of the spam bots are using their name as advertising nowadays, so the [https://www.mediawiki.org/wiki/Extension:UserMerge UserMerge] extension is the only one I know which will allow a user and associated name to be permanently deleted.&lt;br /&gt;
&lt;br /&gt;
::: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 12:04, 14 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:::: The problem now is that they're also adding the information to the page title, so that it will still show up in the deletion logs [http://wiki.flightgear.org/Special:Log/delete] in other words, there's still some SEO juice associated with deleted entries ... Another idea would be to allow admins to temporarily disable wiki registrations/article creation, e.g. if more than 2 admins agree, this could be done to protect the wiki from spam attacks.&lt;br /&gt;
&lt;br /&gt;
::::: Hooray, you should sign your posts ;)  The bots don't target the deletion logs, as that's a little pointless.  It's a Special:* page, and the default Mediawiki robots.txt file tells all search engines to not index these pages.  User pages, page histories, etc. are however normally indexed.&lt;br /&gt;
&lt;br /&gt;
::::: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 14:36, 19 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: The point was not what the bots are targeting, but what shows up in the logs - i.e. SEO-wise - Gijs' article blacklist stuff should help with that hopefully. PS: I could not find the signature button on the mobile device I am using, and I am not too good at remembering the correct number of tildes ;-) [[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 15:04, 19 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
== WIP vs. Under construction ==&lt;br /&gt;
I have been beginning to miss the under construction template[http://wiki.flightgear.org/index.php?title=Template:Under_Construction&amp;amp;direction=prev&amp;amp;oldid=46229] more and more (though I could it definitively could be improved).&lt;br /&gt;
&lt;br /&gt;
I have begun to appreciate the need to differentiate between letting readers that a page is to be considered a yet to be finished construction site (though we in a way have that through the {{tl|incomplete}} template) and letting the reader (and other editors) that a page will receive a large amount of work for some hours or even days, usually the use for {{tl|WIP}}.&lt;br /&gt;
&lt;br /&gt;
In summary i miss templates giving a clear distinction between conditions akin to &amp;quot;Under construction&amp;quot; and &amp;quot;Caution - Wet floors&amp;quot;, rather than &amp;quot;being worked on&amp;quot; and &amp;quot;could need more work&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
—[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 10:11, 17 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
== [[Fr/Pilote automatique]] ==&lt;br /&gt;
Bonjour,&lt;br /&gt;
&lt;br /&gt;
Je viens de créer la page de traduction en français de l'article original en anglais [[Autopilot]]. Vu mes faibles compétences en matière de pilotage, vu que je n'ai pas sur ma version téléchargée d'avion avec un pilote automatique, la traduction doit souffrir quelques approximations, si ce n'est des contresens plus ennuyeux. Si quelques bonnes âmes plus qualifiées pouvaient me faire la grâce d'une relecture... merci d'avance.&lt;br /&gt;
&lt;br /&gt;
Cordialement, et Hop ! --[[User:F-WTSS|F-WTSS]] ([[User talk:F-WTSS|talk]]) 15:30, 18 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
== MediaWiki updated to 1.26.2 ==&lt;br /&gt;
I've updated MediaWiki to the latest stable release (1.26.2) today. I've still got to update some of the extensions, so there may be regressions for now. Please report bugs if you find any. For a list of changes, see https://www.mediawiki.org/wiki/Release_notes/1.26&lt;br /&gt;
&lt;br /&gt;
[[User:Gijs|Gijs]] ([[User talk:Gijs|talk]]) 10:47, 19 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
: Cheers!  I was hoping that it would solve the uneditable Chinese, Russian, and other non-latin character-based pages (Polish strangely as well), but unfortunately [[FlightGear_wiki:Village_pump/Archive_2015#UTF-8_language_pages_cannot_be_edited|that issue remains]].&lt;br /&gt;
&lt;br /&gt;
: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 10:54, 19 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: Hm, looks that will require quite some attention indeed. I'm afraid that'll has to wait for now.&lt;br /&gt;
:: [[User:Gijs|Gijs]] ([[User talk:Gijs|talk]]) 12:29, 19 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
=== Nasal Syntaxhighlighting ===&lt;br /&gt;
: Thanks for your efforts, btw: Nasal syntax highlighting is gone again.&lt;br /&gt;
: {{unsigned|17:22, 19 February 2016‎|Hooray}}&lt;br /&gt;
&lt;br /&gt;
:: Unfortunately this time it isn't me forgetting to copy a file. The SyntaxHighlight extension no longer uses GeSHi, but has switched to Pygments. This means our Nasal mapping no longer works and has to be re-written. If anyone is interested, be my guest. See http://pygments.org/docs/lexerdevelopment/&lt;br /&gt;
:: [[User:Gijs|Gijs]] ([[User talk:Gijs|talk]]) 12:29, 19 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
::: Hi Gijs,&lt;br /&gt;
::: I'm interested in making a Pygments Nasal lexer, but unfortunately I won't be able to work on it until the end of March at the earliest.&lt;br /&gt;
::: [[User:Red_Leader|&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;'''''Red Leader'''''&amp;lt;/span&amp;gt;]] ([[User_talk:Red_Leader|Talk]], [[Special:Contributions/Red_Leader|contribs]]) 16:59, 23 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:::: Unless Gijs is facing any problems, I don't think it's necessarily needed, see my comment/suggestion in this revision: [http://wiki.flightgear.org/index.php?title=FlightGear_wiki:Village_pump&amp;amp;oldid=93166] [[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 17:20, 23 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:::Hi Gijs,&lt;br /&gt;
:::Here's the code for a Nasal lexer. Be warned, it's thoroughly untested, but has the following features:&lt;br /&gt;
:::* Full support for all three string types (backtick, single quote, and double quote), including escapes and formatting strings (e.g., for {{func link|sprintf}}).&lt;br /&gt;
:::* All kinds of numbers, including numbers in scientific notation and octal and hex numbers.&lt;br /&gt;
:::* All global functions and variables as of FG v2016.1.1.&lt;br /&gt;
:::* Some of the commonly-used &amp;lt;code&amp;gt;props.Node&amp;lt;/code&amp;gt; methods.&lt;br /&gt;
:::* All the other things that can be expected (keywords, punctuation, etc.).&lt;br /&gt;
:::I have also created a lexer based on the XML lexer for XML with embedded Nasal, which I thought would be useful.&lt;br /&gt;
:::Regards,&lt;br /&gt;
:::[[User:Red_Leader|&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;'''''Red Leader'''''&amp;lt;/span&amp;gt;]] ([[User_talk:Red_Leader|Talk]], [[Special:Contributions/Red_Leader|contribs]]) 16:35, 2 April 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:::http://pygments.org/docs/lexerdevelopment/#adding-and-testing-a-new-lexer&lt;br /&gt;
:::&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
	Lexer for Nasal.&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
from pygments.lexer import RegexLexer, words, include, inherit, bygroups, using&lt;br /&gt;
from pygments.token import Text, Keyword, Name, String, Number, Operator, Punctuation, Comment&lt;br /&gt;
from pygments.lexers.html import XmlLexer&lt;br /&gt;
&lt;br /&gt;
__all__ = ['NasalLexer', 'XMLNasalLexer']&lt;br /&gt;
&lt;br /&gt;
class NasalLexer(RegexLexer):&lt;br /&gt;
&lt;br /&gt;
	name = 'Nasal'&lt;br /&gt;
	aliases = ['nasal']&lt;br /&gt;
	filenames = ['*.nas']&lt;br /&gt;
&lt;br /&gt;
	tokens = {&lt;br /&gt;
		'formatters': [&lt;br /&gt;
			(r'%[-#0 +]*(?:[0-9]+)?(?:\.[0-9]+)?[dis%couxXeEfFgG]', String.Interpol),&lt;br /&gt;
		],&lt;br /&gt;
		'backtick': [&lt;br /&gt;
			(r'`', String.Backtick, '#pop'),&lt;br /&gt;
			(r'[^`\\]+', String.Backtick),&lt;br /&gt;
			(r'\\n|\\r|\\t|\\`|\\\\|\\x[0-9a-fA-F]{2}', String.Escape),&lt;br /&gt;
		],&lt;br /&gt;
		'sqstring': [&lt;br /&gt;
			(r&amp;quot;'&amp;quot;, String.Single, '#pop'),&lt;br /&gt;
			(r&amp;quot;[^'\\%]+&amp;quot;, String.Single),&lt;br /&gt;
			(r&amp;quot;\\'&amp;quot;, String.Escape),&lt;br /&gt;
			include('formatters'),&lt;br /&gt;
		],&lt;br /&gt;
		'dqstring': [&lt;br /&gt;
			(r'&amp;quot;', String.Double, '#pop'),&lt;br /&gt;
			(r'[^&amp;quot;\\%]+', String.Double),&lt;br /&gt;
			(r'\\n|\\r|\\t|\\&amp;quot;|\\\\|\\x[0-9a-fA-F]{2}', String.Escape),&lt;br /&gt;
			include('formatters'),&lt;br /&gt;
		],&lt;br /&gt;
		'root': [&lt;br /&gt;
			(r'\s+', Text),&lt;br /&gt;
			(r'#.*?$'m, Comment.Single),&lt;br /&gt;
			(r':|\?|[!=&amp;lt;&amp;gt;+\-*\/~&amp;amp;|^]=?', Operator),&lt;br /&gt;
			(words(('or', 'and'), suffix=r'\b'), Operator.Word),&lt;br /&gt;
			(r'[{(\[})\]\.;,]', Punctuation),&lt;br /&gt;
			(words(('for', 'foreach', 'forindex', 'while', 'break', 'return', 'continue', 'if', 'else', 'elsif'), suffix=r'\b'), Keyword),&lt;br /&gt;
			(words(('var', 'func'), suffix=r'\b'), Keyword.Declaration),&lt;br /&gt;
			(words(('nil'), suffix=r'\b'), Keyword.Constant),&lt;br /&gt;
			(words(('me', 'arg'), suffix=r'\b'), Name.Builtin.Pseudo),&lt;br /&gt;
			(words(('new', 'del', 'getNode', 'getParent', 'getChild', 'getChildren', 'removeChild', 'removeChildren', 'removeAllChildren', 'getName', 'getIndex', 'getType', 'getAttribute', 'setAttribute', 'getValue', 'setValue', 'setIntValue', 'setBoolValue', 'setDoubleValue', 'unalias', 'alias', 'getPath', 'getBoolValue', 'remove', 'setValues', 'getValues', 'initNode'), suffix=r'\b'), Keyword.Pseudo),&lt;br /&gt;
			(r'0o[0-7]+', Number.Oct),&lt;br /&gt;
			(r'0x[0-9a-fA-F]+', Number.Hex),&lt;br /&gt;
			(r'\d*(?:\.\d*)?[eE][+-]?\d+', Number.Float),&lt;br /&gt;
			(r'\d*\.\d*', Number.Float),&lt;br /&gt;
			(r'\b[0-9]+\b', Number.Integer),&lt;br /&gt;
			(words(('D2R', 'R2D', 'FT2M', 'M2FT', 'IN2M', 'M2IN', 'NM2M', 'M2NM', 'KT2MPS', 'MPS2KT', 'FPS2KT', 'KT2FPS', 'LB2KG', 'KG2LB', 'GAL2L', 'L2GAL'), suffix=r'\b'), Name.Variable.Global),&lt;br /&gt;
			(words(('abort', 'abs', 'addcommand', 'airportinfo', 'airwaysRoute', 'assert', 'carttogeod', 'cmdarg', 'courseAndDistance', 'createViaTo', 'createDiscontinuity', 'createWP', 'createWPFrom', 'defined', 'directory', 'fgcommand', 'findAirportsByICAO', 'findAirportsWithinRange', 'findFixesByID', 'findNavaidByFrequency', 'findNavaidsByFrequency', 'findNavaidsByID', 'findNavaidsWithinRange', 'finddata', 'flightplan', 'geodinfo', 'geodtocart', 'getprop', 'greatCircleMove', 'interpolate', 'isa', 'logprint', 'magvar', 'maketimer', 'md5', 'navinfo', 'parse_markdown', 'parsexml', 'print', 'printf', 'printlog', 'rand', 'registerFlightPlanDelegate', 'removecommand', 'removelistener', 'resolvepath', 'setlistener', 'setprop', 'settimer', 'srand', 'systime', 'thisfunc', 'tileIndex', 'tilePath', 'values'), suffix=r'\b'), Name.Builtin),&lt;br /&gt;
			(words(('append', 'bind', 'call', 'caller', 'chr', 'closure', 'cmp', 'compile', 'contains', 'delete', 'die', 'find', 'ghosttype', 'id', 'int', 'keys', 'left', 'num', 'pop', 'right', 'setsize', 'size', 'sort', 'split', 'sprintf', 'streq', 'substr', 'subvec', 'typeof'), suffix=r'\b'), Name.Builtin),&lt;br /&gt;
			(words(('_createCondition', '_fgcommand', '_interpolate', '_setlistener'), suffix=r'\b'), Keyword.Reserved),&lt;br /&gt;
			(r'`', String.Backtick, 'backtick'),&lt;br /&gt;
			(r&amp;quot;'&amp;quot;, String.Single, 'sqstring'),&lt;br /&gt;
			(r'&amp;quot;', String.Double 'dqstring'),&lt;br /&gt;
			(r'\b_\w*?\b', Keyword.Reserved),&lt;br /&gt;
			#(r'\b\w*?\b', Name),&lt;br /&gt;
		]&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
class XMLNasalLexer(XmlLexer):&lt;br /&gt;
	&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
	For Nasal code embedded in XML files.&lt;br /&gt;
	&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	name = 'XML-Nasal'&lt;br /&gt;
	aliases = ['xml-nasal', 'xml-ns']&lt;br /&gt;
&lt;br /&gt;
	tokens = {&lt;br /&gt;
		'root': [&lt;br /&gt;
			(r'(&amp;lt;(?:load|unload|script)&amp;gt;)(&amp;lt;!\[CDATA\[)?(.*?)(]]&amp;gt;)?(&amp;lt;/(?:load|unload|script)&amp;gt;)', bygroups(Name.Tag, Comment.Preproc, using(NasalLexer), Comment.Preproc, Name.Tag),&lt;br /&gt;
			inherit,&lt;br /&gt;
		],&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:: We can use the ECMAScript/JavaScript lexer[http://pygments.org/docs/lexers/#lexers-for-javascript-and-related-languages] for now, my suggestion would be to copy that over to a file so that we can work on a custom Nasal lexer (Syntax  is almost identical, with a few different keywords, and many others being irrelevant). What is missing/different can be obtained from other lexers that are similar, e.g. [http://pygments.org/docs/lexers/#lexers-for-other-c-like-languages] [[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 15:45, 19 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: Okay, here's the better/quick&amp;amp;easy way: We have Nasal support for some fairly popular editors, like [http://wiki.flightgear.org/Howto:Syntax_highlighting_for_Nasal#Vim|vim](originally created by Melchior&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/flightgear/ci/next/tree/scripts/syntax/nasal.vim&amp;lt;/ref&amp;gt;), listed at [[Howto:Syntax_highlighting_for_Nasal]] - there are various free converters available that will read such a syntaxhighlighting file and convert it to a pygments class, e.g. see: https://github.com/honza/vim2pygments [[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 16:00, 19 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
==== References ====&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== The repository link templates ==&lt;br /&gt;
=== Complete overhaul of the repository link templates ===&lt;br /&gt;
&lt;br /&gt;
I have now performed a complete overhaul of the repository link templates (see {{tl|repo link/doc related}}).  This was motivated by the incomplete state of these templates, the lack of standardisation, the lack of SourceForge git repository support for {{tl|repo link}}, web-interface only support, etc.  I have used a lot of recursive transclusion for standardisation, so that there is a single point for updating for any FlightGear infrastructure changes.  This is the master {{tl|repo link}} template.  All the other templates are subtemplates which recursively transclude from this master template.  I have also created a number of documentation templates for simplifying template maintenance (see {{tl|repo link/doc related‎}}, {{tl|repo link/doc specific file git‎‎}}, {{tl|repo link/doc git clone‎‎}}, and {{tl|repo link/doc commit}}).  The changes were constrained to maintain backwards compatibility as much as possible.  However I would like to break this to allow the following templates to be updated to transclude from the master {{tl|repo link}} template:&lt;br /&gt;
&lt;br /&gt;
* {{tl|flightgear file}},&lt;br /&gt;
* {{tl|simgear file}},&lt;br /&gt;
* {{tl|fgdata file}},&lt;br /&gt;
* {{tl|fgaddon file}}.&lt;br /&gt;
&lt;br /&gt;
If no one objects, I would like to completely break these and expand and rename the parameter set to match the other &amp;lt;nowiki&amp;gt;{{* file}}&amp;lt;/nowiki&amp;gt; repository templates (e.g. {{tl|terragear file}}).  My overhaul currently does not include Hooray's ideas for non command line usages, i.e. different GUIs, but it enables it to be easily added via the master template and the addition of a single parameter to any subtemplates.&lt;br /&gt;
&lt;br /&gt;
[[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 15:05, 25 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
: I don't have any objections myself, I appreciate all the work you are putting into this, and would like to thank you for helping us clean up all that mess by doing such unglamorous work ;-) I also appreciate that your changes would facilitate adding a non-CLI mode to the corresponding templates. However, I would suggest to wait for Gijs' feedback, because he's ultimately the most likely person to veto something around here ;-) [[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 17:31, 25 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: Johan seems to be the one who did a lot of the initial work on these &amp;lt;nowiki&amp;gt;{{* file}}&amp;lt;/nowiki&amp;gt; templates, and Red Leader with the {{tl|repo link}} template.  And they were involved in the general discussions ([[http://wiki.flightgear.org/index.php?title=FlightGear_wiki:Village_pump&amp;amp;oldid=87148#Repository_link_templates perm]).  But I know Gijs was also involved in the design.&lt;br /&gt;
&lt;br /&gt;
:: For the non-CLI mode, that will need -a lot- more planning.  For example a definitive list of all these modes would be useful.  Should this use an optional Mediawiki pop up extension showing a link to a general page that describes the action for all different GUIs, CLI, etc.?  Should we have a switch box so that the reader can switch in-text between CLI, and the numerous GUIs?  Are we going to have a large set of screenshots for each GUI?  If so, I would strongly recommend the [https://www.mediawiki.org/wiki/Extension:Labeled_Section_Transclusion labelled section transclusion extension] for creating a single page for one GUI with everything for that GUI, as a tutorial.  Here is [http://wiki.nmr-relax.com/Relax_4.0.1 an external example where I have used this], to fragment the base release page to create [http://wiki.nmr-relax.com/Relax_release_descriptions this meta page], as well as many other meta pages.&lt;br /&gt;
&lt;br /&gt;
:: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 03:14, 26 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
I am also thinking of changing the name of the &amp;lt;nowiki&amp;gt;{{* file}}&amp;lt;/nowiki&amp;gt; templates, as I hope to make the scope of the templates far more general.  The name &amp;lt;nowiki&amp;gt;{{* source}}&amp;lt;/nowiki&amp;gt; or &amp;lt;nowiki&amp;gt;{{* repo}}&amp;lt;/nowiki&amp;gt; might be better.  For example these will allow the repository commit, tree view, log view (and maybe rss feed), with or without a file/directory path.  And I would like to generalise this to handle both the SF web-interface and non-web net protocols (git://, ssh://, svn://, etc.).  It will allow for CLI instructions to be built up and embedded in &amp;lt;nowiki&amp;gt;{{#tag:source|&amp;lt;content&amp;gt;|lang=sh}}&amp;lt;/nowiki&amp;gt; tags.  And I will defer all infrastructure decisions in the subtemplates to the single point of {{tl|project infrastructure}}, so that if there are changes in the future, then only this single template needs to be updated to update the entire wiki.&lt;br /&gt;
&lt;br /&gt;
[[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 03:22, 26 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
: The {{tl|project infrastructure}} template as a single point provider of various project infrastructure names and URL pairs seem like a great idea.  If it work out well it will really lessen the maintenance by having less places needing updates, while allowing the various repository templates to be simple to use, in essence by having comprehensible names and no boiler plate parameters for their users.&lt;br /&gt;
: —[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 15:15, 27 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
==== Repository link update ====&lt;br /&gt;
For those following, I have massively expanded the capabilities of the {{tl|repo link}} template:&lt;br /&gt;
* The SourceForge URLs are now comprehensive.&lt;br /&gt;
* Full support for the new query-based URLs for the Gitorious archives.&lt;br /&gt;
* Functional GitLab URLs.&lt;br /&gt;
* Generic repository support (used to create the {{tl|openscenegraph co}} template).&lt;br /&gt;
* Detailed documentation and extensive examples for checking the implementation (if you find any non-supported links, please add these as examples).&lt;br /&gt;
* Isolation of the '''cmd''' parameter from the CLI options &amp;amp;mdash; this is to enable future support for non-CLI instructions based on the value of '''cmd'''.&lt;br /&gt;
&lt;br /&gt;
I have also completed a large set of subtemplates of {{tl|repo link}}, see the list at {{tl|repo link/doc related}}.  This includes a full set of &amp;lt;nowiki&amp;gt;{{* source}}&amp;lt;/nowiki&amp;gt; templates.  I have left the original &amp;lt;nowiki&amp;gt;{{* file}}&amp;lt;/nowiki&amp;gt; templates, rather than renaming and modifying them, so these are now redundant.  All of the &amp;lt;nowiki&amp;gt;{{* source}}&amp;lt;/nowiki&amp;gt;, &amp;lt;nowiki&amp;gt;{{* commit}}&amp;lt;/nowiki&amp;gt;, &amp;lt;nowiki&amp;gt;{{* clone}}&amp;lt;/nowiki&amp;gt;, and &amp;lt;nowiki&amp;gt;{{* co}}&amp;lt;/nowiki&amp;gt; templates transclude from the master {{tl|repo link}} template to do all of the work.&lt;br /&gt;
&lt;br /&gt;
One important template is {{tl|gitorious source}}.  The support for the new query-based URLs for the Gitorious archives is now quite comprehensive in {{tl|repo link}}.  Therefore I have converted almost every single FlightGear wiki link to https://gitorious.org to use {{tl|gitorious source}} instead.  This fixes a lot of broken links and broken git instructions.  I have reduced the number of hits for gitorious.org on the wiki (searching just for &amp;quot;gitorious&amp;quot;) to 22 hits.  This includes 2 very outdated articles ([[FlightGear Git: aircraft authors]], [[Fr/FlightGear et Git]]), 15 locked newsletters, 1 with no longer existent Gitorious merge request links, and 4 base URL links for Hangars.  This way we can maintain the Gitorious web interface links and git command instructions in a functional state by simply updating the single source of {{tl|repo link}}.&lt;br /&gt;
&lt;br /&gt;
[[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 11:38, 29 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
: I just remembered [[Special:LinkSearch]], so make that 184 broken gitorious.org links remaining.  Lots more work to do :)&lt;br /&gt;
&lt;br /&gt;
: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 14:46, 29 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
For some of these templates, e.g. {{tl|repo link/doc usage}}, I'm trying to implement some logic for automatic whitespace padding for documentation formatting, but the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;{{#len:string}}&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; function is not enabled.  According to {{mediawiki|Wikitext_parser/Core_parser_functions#.23len}} and {{mediawiki|Extension:StringFunctions}}, the option &amp;lt;code&amp;gt;$wgPFEnableStringFunctions = true;&amp;lt;/code&amp;gt; should be set (in &amp;lt;code&amp;gt;LocalSettings.php&amp;lt;/code&amp;gt;).  Unless there is a reason for not using this, I was wondering if someone could enable this?  Cheers!&lt;br /&gt;
&lt;br /&gt;
[[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 09:53, 8 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
=== Archived newsletters and dead links? ===&lt;br /&gt;
&lt;br /&gt;
Do we have a policy for the dead links in the FlightGear newsletters?  It is obviously good to preserve the historic state.  But there are many Gitorious links that could be made functional again using the {{tl|gitorious source}} template to point to the historic Gitorious archives (including the official FlightGear repositories, rather than using {{tl|fgdata source}}, for example).  The https://gitorious.org links have been converted from URL/path based to query based, so absolutely all of the old links are broken.  I am steadily converting all Gitorious links to use the [[Template:repo link/doc related|{{obr}}repo link{{cbr}} family of templates]], with the exception of the newsletters.&lt;br /&gt;
&lt;br /&gt;
[[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 04:52, 8 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
: I think it could be a good idea to try update old links in those newsletters.  I sometimes look back at things and tend to think that I probably are not the only one doing that.&lt;br /&gt;
: I wonder if the rotten links should be replaced or stricken, but I think they could just as well be replaced.  The key thing is that they go to the same resource or content, not weather they have been updated or not (also, the change will be visible in the revision history after all).&lt;br /&gt;
: —[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 07:11, 8 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: I should add that I'm using [http://wiki.flightgear.org/index.php?title=Special:LinkSearch&amp;amp;limit=500&amp;amp;offset=0&amp;amp;target=http%3A%2F%2Fgitorious.org &amp;lt;nowiki&amp;gt;Special:LinkSearch for http://gitorious.org&amp;lt;/nowiki&amp;gt;] and [http://wiki.flightgear.org/index.php?title=Special:LinkSearch&amp;amp;limit=500&amp;amp;offset=0&amp;amp;target=https%3A%2F%2Fgitorious.org &amp;lt;nowiki&amp;gt;Special:LinkSearch for https://gitorious.org&amp;lt;/nowiki&amp;gt;].  And I am also not touching the &amp;lt;code&amp;gt;User*&amp;lt;/code&amp;gt; pages, &amp;lt;code&amp;gt;*talk*&amp;lt;/code&amp;gt; pages, or pages tagged as out of date or up for deletion.  For the newsletters I might look at these later when the broken Gitorious links are fixed in the rest of the wiki but, as these are locked, someone else might have make the switch to {{tl|gitorious source}}, {{tl|gitorious url}}, {{tl|gitorious clone}}, and {{tl|gitorious merge request}}.&lt;br /&gt;
&lt;br /&gt;
:: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 02:53, 9 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
::: I will temporarily add a table here for the templates in the newsletters and will slowly fix them one by one together with any other admin.&lt;br /&gt;
{{navbox&lt;br /&gt;
| title = Click &amp;quot;show&amp;quot; to show --&amp;gt;&lt;br /&gt;
| state = collapsed&lt;br /&gt;
| navbar = plain&lt;br /&gt;
| list1 =&lt;br /&gt;
http:...&lt;br /&gt;
{{{!}} class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Fixed !! Newsletter !! Gitorious URL !! Notes&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter May 2010]]&lt;br /&gt;
{{!}} http://gitorious.org/fg&lt;br /&gt;
{{!}} No equivalent link for the Gitorious archive - project pages are dead.  Maybe just use http://gitorious.org/?&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter May 2010]]&lt;br /&gt;
{{!}} http://gitorious.org/fg&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter September 2010]]&lt;br /&gt;
{{!}} http://gitorious.org/fg/flightgear/commit/5c6fe952598053fa63631fc0161d666f22a50f51&lt;br /&gt;
{{!}} Functional link, equivalent to {{gitorious url|fg|flightgear|commit=5c6fe952598053fa63631fc0161d666f22a50f51}}.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter September 2010]]&lt;br /&gt;
{{!}} http://gitorious.org/fg/flightgear/commit/5c6fe952598053fa63631fc0161d666f22a50f51&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter January 2011]]&lt;br /&gt;
{{!}} http://gitorious.org/jsbsim/jsbsim&lt;br /&gt;
{{!}} Functional link.  Switched to {{gitorious url|jsbsim|jsbsim}} to future-protect the link.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter January 2011]]&lt;br /&gt;
{{!}} http://gitorious.org/jsbsim/jsbsim&lt;br /&gt;
{{!}} Functional link.  Switched to {{gitorious url|jsbsim|jsbsim}} to future-protect the link.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter February 2011]]&lt;br /&gt;
{{!}} http://gitorious.org/headtrack&lt;br /&gt;
&lt;br /&gt;
http://gitorious.org/arduinocockpit&lt;br /&gt;
{{!}} Project pages are dead, switched to {{gitorious url|headtrack|headtrack}}&lt;br /&gt;
&lt;br /&gt;
{{gitorious url|arduinocockpit|arduinocockpit}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter February 2011]]&lt;br /&gt;
{{!}} http://gitorious.org/arduinocockpi&lt;br /&gt;
&lt;br /&gt;
http://gitorious.org/headtrack&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter March 2011]]&lt;br /&gt;
{{!}} http://gitorious.org/lockheed-l10-electra&lt;br /&gt;
{{!}} Missing project - i.e. {{gitlab source|user=emilianh|repo=Lockheed-L10-Electra|text=migrated to GitLab}}.  Switched to {{gitlab source|user=emilianh|repo=Lockheed-L10-Electra}}.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter March 2011]]&lt;br /&gt;
{{!}} http://gitorious.org/lockheed-l10-electra&lt;br /&gt;
{{!}} Switched to {{gitlab source|user=emilianh|repo=Lockheed-L10-Electra}}.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter November 2011]]&lt;br /&gt;
{{!}} http://gitorious.org/flightgear-aircraft&lt;br /&gt;
{{!}} Switched to {{gitorious source}} and rephrased text slightly to help readers find the repositories.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter October 2012]]&lt;br /&gt;
{{!}} http://gitorious.org/anders-hangar/mtb_20m/trees/master&lt;br /&gt;
{{!}} Switch to {{gitorious url|proj=anders-hangar|repo=mtb_20m}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter March 2013]]&lt;br /&gt;
{{!}} http://gitorious.org/fg/flightgear/blobs/next/scripts/java/FGClient/src/FGFSDemo.java&lt;br /&gt;
{{!}} Switched to {{gitorious url|proj=fg|repo=flightgear|path=scripts/java/FGClient/src/FGFSDemo.java}}.  This points to the old Gitorious repository to protect against path changes in the future.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter September 2013]]&lt;br /&gt;
{{!}} http://gitorious.org/boeing/707&lt;br /&gt;
{{!}} Switched to {{gitorious source|proj=boeing|repo=707}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter September 2013]]&lt;br /&gt;
{{!}} http://gitorious.org/boeing/707&lt;br /&gt;
{{!}} Switched to {{gitorious source|proj=boeing|repo=707}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter November 2013]]&lt;br /&gt;
{{!}} http://gitorious.org/fg/fgrun&lt;br /&gt;
{{!}} Switch to {{gitorious url|proj=fg|repo=fgrun}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter November 2013]]&lt;br /&gt;
{{!}} http://gitorious.org/fg/fgrun&lt;br /&gt;
{{!}} Switch to {{gitorious url|proj=fg|repo=fgrun}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter July 2014]]&lt;br /&gt;
{{!}} http://gitorious.org/nasal-support/nasal-npp&lt;br /&gt;
{{!}} Switched to {{gitorious url|nasal-support|nasal-npp}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter April 2015]]&lt;br /&gt;
{{!}} http://gitorious.org&lt;br /&gt;
{{!}} Switched to {{tl|gitorious source}} without parameters for the Gitorious base URL, to future-protect it.&lt;br /&gt;
{{!}}}&lt;br /&gt;
&lt;br /&gt;
https:...&lt;br /&gt;
{{{!}} class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Fixed !! Newsletter !! Gitorious URL !! Notes&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter April 2011]]&lt;br /&gt;
{{!}} https://gitorious.org/papillon81/flightgear-custom-scenery/&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/dvanmosselbeen/flightgear-custom-scenery&lt;br /&gt;
{{!}} Switched to {{gitorious source|dvanmosselbeen|flightgear-custom-scenery}} and {{gitorious source|papillon81|flightgear-custom-scenery}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter April 2011]]&lt;br /&gt;
{{!}} https://gitorious.org/dvanmosselbeen/flightgear-custom-scenery&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/papillon81/flightgear-custom-scenery/&lt;br /&gt;
{{!}} Switched to {{gitorious source|dvanmosselbeen|flightgear-custom-scenery}} and {{gitorious source|papillon81|flightgear-custom-scenery}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter July 2011]]&lt;br /&gt;
{{!}} https://gitorious.org/dvanmosselbeen/flightgear-custom-scenery&lt;br /&gt;
{{!}} Switched to {{gitorious source|dvanmosselbeen|flightgear-custom-scenery}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter July 2011]]&lt;br /&gt;
{{!}} https://gitorious.org/dvanmosselbeen/flightgear-custom-scenery&lt;br /&gt;
{{!}} Switched to {{gitorious source|dvanmosselbeen|flightgear-custom-scenery}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter December 2011]]&lt;br /&gt;
{{!}} https://gitorious.org/dvanmosselbeen/flightgear-custom-scenery&lt;br /&gt;
{{!}} Switched to {{gitorious source|dvanmosselbeen|flightgear-custom-scenery}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Fr/Nouvelles du projet FlightGear - décembre 2011]]&lt;br /&gt;
{{!}} https://gitorious.org/dvanmosselbeen/flightgear-custom-scenery&lt;br /&gt;
{{!}} Switched to {{gitorious source|dvanmosselbeen|flightgear-custom-scenery}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter April 2012]]&lt;br /&gt;
{{!}} https://gitorious.org/fg/fgdata/blobs/master/Aircraft/Instruments-3d/garmin196/README&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/fgdata/blobs/master/Aircraft/Instruments-3d/garmin196/doc/doc-en.htm&lt;br /&gt;
{{!}} Switched to {{fgdata source|path=Aircraft/Instruments-3d/garmin196/README|full=1}} and {{fgdata source|path=Aircraft/Instruments-3d/garmin196/doc/doc-en.htm|full=1}} to point to the current FGData locations and removed the name &amp;quot;Gitorious&amp;quot; to make the text of the Garmin 196 GPS section still relevant&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter August 2012]]&lt;br /&gt;
{{!}} https://gitorious.org/mil-mi-6&lt;br /&gt;
{{!}} Switched to {{gitorious url|proj=mil-mi-6|repo=mi6dev}}, and changed from the non-existent project page to the main repository.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter October 2012]]&lt;br /&gt;
{{!}} https://gitorious.org/fgradar&lt;br /&gt;
{{!}} Switched from the project page to the direct repository {{gitorious url|fgradar|fgradar}}.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter March 2013]]&lt;br /&gt;
{{!}} https://gitorious.org/fg/flightgear/commit/913727239d6776c0508d206f395e16c265413ec3&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/flightgear/commit/eba03b5e469824ee8f1494723fcddbbc56155a08&lt;br /&gt;
{{!}} Switched to {{flightgear url|commit=913727239d6776c0508d206f395e16c265413ec3}} and {{flightgear url|commit=eba03b5e469824ee8f1494723fcddbbc56155a08}}.  This deliberately points to the current repository.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter April 2013]]&lt;br /&gt;
{{!}} https://gitorious.org/fg-radi/osm2city&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/scenery-france-850&lt;br /&gt;
{{!}} Switched to the new GitLab repository {{gitlab source|proj=fg-radi|repo=osm2city|full=1}}&lt;br /&gt;
&lt;br /&gt;
and removed the no longer existent scenery-france-850 repository, replacing it with &amp;quot;&amp;lt;s&amp;gt;Scenery repository (Gitorious)&amp;lt;/s&amp;gt;&amp;quot;.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter October 2013]]&lt;br /&gt;
{{!}} https://gitorious.org/fg/galvedros-fgdata&lt;br /&gt;
{{!}} Switch to {{gitorious url|proj=fg|repo=galvedros-fgdata}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter October 2013]]&lt;br /&gt;
{{!}} https://gitorious.org/fg/galvedros-fgdata&lt;br /&gt;
{{!}} Switch to {{gitorious url|proj=fg|repo=galvedros-fgdata}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter November 2013]]&lt;br /&gt;
{{!}} https://gitorious.org/ec130/&lt;br /&gt;
{{!}} Switched from the project page to the direct repository {{gitorious source|ec130|ec130}}.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter November 2013]]&lt;br /&gt;
{{!}} https://gitorious.org/ec130/&lt;br /&gt;
{{!}} Switched from the project page to the direct repository {{gitorious source|ec130|ec130}}.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter February 2014]]&lt;br /&gt;
{{!}} https://gitorious.org/fg/philosophers-fgdata/source/022bef27f05d4837d720f63c6507b47466ff2a59:Nasal/console/repl.nas#L436&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/philosophers-fgdata/source/nasal-console:Nasal/console&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/fgdata/commit/eaaf816b772649d5b0826a1d0bdd166dbc5b968f&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/flightgear/commit/34ed79e5f88ffdfc5e651a1fe3e639cb8f4d3353&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/flightgear/commit/5eee5e42ae4f5cf56283b3bf5a3be46efc2b51c4&lt;br /&gt;
&lt;br /&gt;
https://www.gitorious.org/fg/flightgear/merge_requests/26&lt;br /&gt;
{{!}} Switched to {{gitorious source|proj=fg|repo=philosophers-fgdata|branch=nasal-console|path=Nasal/console/repl.nas|line=708}}&lt;br /&gt;
&lt;br /&gt;
{{gitorious url|proj=fg|repo=philosophers-fgdata|branch=nasal-console|path=Nasal/console|view=tree}}&lt;br /&gt;
&lt;br /&gt;
{{fgdata-old url|commit=eaaf816b772649d5b0826a1d0bdd166dbc5b968f}}&lt;br /&gt;
&lt;br /&gt;
{{flightgear commit|34ed79e5f88ffdfc5e651a1fe3e639cb8f4d3353}}&lt;br /&gt;
&lt;br /&gt;
{{gitorious merge request|mr=54}}&lt;br /&gt;
&lt;br /&gt;
{{gitorious merge request|mr=26}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter February 2014]]&lt;br /&gt;
{{!}} https://gitorious.org/fg/philosophers-fgdata/source/022bef27f05d4837d720f63c6507b47466ff2a59:Nasal/console/repl.nas#L436&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/philosophers-fgdata/source/nasal-console:Nasal/console&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/fgdata/commit/eaaf816b772649d5b0826a1d0bdd166dbc5b968f&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/flightgear/commit/34ed79e5f88ffdfc5e651a1fe3e639cb8f4d3353&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/flightgear/commit/5eee5e42ae4f5cf56283b3bf5a3be46efc2b51c4&lt;br /&gt;
&lt;br /&gt;
https://www.gitorious.org/fg/flightgear/merge_requests/26&lt;br /&gt;
{{!}} Changes match the English article.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter April 2014]]&lt;br /&gt;
{{!}} https://gitorious.org/fg/fgdata/flightgear?p=fg/fgdata:flightgear.git;a=blob;f=keyboard.xml&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/fgdata?p=fg:fgdata.git;a=commit;h=f8c56dcc52ffd3d6dfca1d39dc4a72b6b3478368&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/hoorays-flightgear?p=fg:hoorays-flightgear.git;a=shortlog;h=refs/heads/topics/cppbind-fgprotocol&lt;br /&gt;
{{!}} This first link was the broken {{tl|git link}} template (see the table below).  The other two links are not in the article?!&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter June 2014]]&lt;br /&gt;
{{!}} https://gitorious.org/eddp-custom-scenery/eddp-custom-scenery/&lt;br /&gt;
{{!}} Switched to {{tl|gitorious clone}} to provide functional '''git clone''' instructions.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter November 2014]]&lt;br /&gt;
{{!}} https://gitorious.org/fg/hoorays-fgdata/source/2857d8fc9fcfe2bb162a9eb9d3dcca4d41b3a876:Nasal/ai/aim9/aim9.fdm#L9&lt;br /&gt;
{{!}} Switch to {{gitorious url|proj=fg|repo=hoorays-fgdata|commit=2857d8fc9fcfe2bb162a9eb9d3dcca4d41b3a876|path=Nasal/ai/aim9/aim9.fdm|line=9}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter January 2015]]&lt;br /&gt;
{{!}} https://gitorious.org/fg/canvas-hackers-fgdata/source/f59c42134a5a77e343981dcff8278c3e2f094e87&lt;br /&gt;
{{!}} Switch to {{gitorious url|proj=fg|repo=canvas-hackers-fgdata|commit=f59c42134a5a77e343981dcff8278c3e2f094e87|view=summary}}&lt;br /&gt;
{{!}}}&lt;br /&gt;
&lt;br /&gt;
Broken templates:...&lt;br /&gt;
{{{!}} class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Fixed !! Newsletter !! Template !! Notes&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter April 2014]]&lt;br /&gt;
{{!}} {{tlx|Git link|gitorious|fg/fgdata|master|keyboard.xml|pre=$FG_ROOT/}}&lt;br /&gt;
{{!}} Switched to {{fgdata source|path=keyboard.xml|pre=$FG_ROOT}} to fix the Gitorious link created by the broken and depreciated {{tl|git link}} template.&lt;br /&gt;
{{!}}}&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
::: —[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 12:06, 9 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:::: I've added a '''notes''' column to help a little.&lt;br /&gt;
&lt;br /&gt;
:::: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 12:30, 9 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
=== Elimination of the dead Gitorious links ===&lt;br /&gt;
Thanks largely to the diversity and flexibility of the [[:Category:Repository link templates|{{obr}}repo link{{cbr}} family of templates]], I have now managed to eliminate almost every last dead Gitorious link in the FlightGear wiki!  The locked Newsletter articles, user pages, and talk pages are the only exceptions.  The page counts from the (Main) namespace are:&lt;br /&gt;
* [http://wiki.flightgear.org/index.php?target=http%3A%2F%2Fgitorious.org&amp;amp;namespace=0&amp;amp;title=Special%3ALinkSearch &amp;lt;nowiki&amp;gt;Special:LinkSearch for http://gitorious.org&amp;lt;/nowiki&amp;gt;] &amp;amp;mdash; 37.  Of these, 17 are for the front page with the news of the Gitorious to SourceForge migration, and the rest are Newsletters.&lt;br /&gt;
* [http://wiki.flightgear.org/index.php?title=Special:LinkSearch&amp;amp;limit=500&amp;amp;offset=0&amp;amp;target=https%3A%2F%2Fgitorious.org&amp;amp;namespace=0 &amp;lt;nowiki&amp;gt;Special:LinkSearch for https://gitorious.org&amp;lt;/nowiki&amp;gt;] &amp;amp;mdash; 166.  Most of these links are valid and created by the {{obr}}gitorious *{{cbr}} subtemplates of {{tl|repo link}}.  The remaining broken links are all in the locked Newsletters.&lt;br /&gt;
The Howto:* pages are not in the (Main) wiki namespace, but I've knocked those out too.&lt;br /&gt;
&lt;br /&gt;
[[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 13:54, 10 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
: thanks for doing all this unglamorous work - I am sorry that Gijs was apparently too busy to follow up on my suggestion to either provide you with admin access around here, or at least to help you run a Python script to do all this work in an automated, rather than manual, fashion. Hopefully, things will work out better next time. Again, thank you. Like I said, I think you should definitely be given admin access on the wiki, especially given your recent contributions - and I would gladly have my wiki status downgraded accordingly. In fact, if I was able to directly promote accounts accordingly, I would have done so months ago - however, it seems that Gijs is the only one to have those privileges, and he mentioned off-list that he's kinda busy with RL/exams etc, so it is to be expected that he's going to become a bottleneck more often - hopefully, this will be recongized as an actual issue, so that there will be more people able to promote new wiki admins. Sorry that things didn't work out better this time, and thanks so much for doing all this stuff manually. -[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 14:49, 10 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: No problems!  As for automating this, that would not have been possible.  If you look at the changes, you'll see that each one is different &amp;lt;sup&amp;gt;[http://wiki.flightgear.org/index.php?title=Special:RecentChanges&amp;amp;to=20160310210655&amp;amp;limit=500]&amp;lt;/sup&amp;gt;.  I had to check each one, and update the link as required.&lt;br /&gt;
&lt;br /&gt;
:: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 16:08, 10 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
::: There's three of us actually (Curt, Simon and myself), no need to wait on me. See http://wiki.flightgear.org/index.php?title=Special%3AListUsers&amp;amp;username=&amp;amp;group=bureaucrat&amp;amp;limit=100 (Sek is inactive nowadays) ;-)&lt;br /&gt;
::: Please note that forum pms are really not the best way to contact me. I very much prefer email over forum pms as it's a lot easier to filter out the huge amounts of nonsense I'm receiving from stuff requiring actual attention.&lt;br /&gt;
::: Anyhow I've just  promoted Bugman so he can edit locked articles.&lt;br /&gt;
::: [[User:Gijs|Gijs]] ([[User talk:Gijs|talk]]) 05:06, 11 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:::: Thank you.  I'll try to preserve the original intent of the Newsletters while fixing the broken links (maybe even preserving any original URLs as Mediawiki link text, while pointing to the new URL).  I will use the {{obr}}gitorious *{{cbr}} templates to point to the historical sources, and will probably use this for all of the Gitorious URLs so that we have full control over any future URL breakages via the single location of {{tl|repo link}}.  For example, if they change the gitorious.org domain name to a https://archive.org subdomain (i.e. gitorious.archive.org).&lt;br /&gt;
&lt;br /&gt;
:::: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 06:40, 11 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
=== Regex parsing of template parameters? ===&lt;br /&gt;
&lt;br /&gt;
For the {{tl|repo link}} template, I am currently trying to work out what to do for git branches and tags on the SourceForge infrastructure.  The problem is that the presence of the character &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt; within a branch or tag name requires the text &amp;lt;code&amp;gt;/~&amp;lt;/code&amp;gt; to be appended to that name in the URL, for example:&lt;br /&gt;
&lt;br /&gt;
* Tag &amp;lt;code&amp;gt;version/2016.1.1&amp;lt;/code&amp;gt;:  https://sourceforge.net/p/flightgear/simgear/ci/version/2016.1.1/~/tree/simgear/ephemeris/ephemeris.cxx&lt;br /&gt;
* Branch &amp;lt;code&amp;gt;release/2016.1&amp;lt;/code&amp;gt;:  https://sourceforge.net/p/flightgear/simgear/ci/release/2016.1/~/tree/simgear/ephemeris/ephemeris.cxx&lt;br /&gt;
&lt;br /&gt;
I haven't found out a way to use regex to parse the &amp;lt;code&amp;gt;tag&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;branch&amp;lt;/code&amp;gt; template parameters to automate this, hence I am thinking of just giving the instruction for the template user to append this text to the &amp;lt;code&amp;gt;tag&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;branch&amp;lt;/code&amp;gt; parameter text themselves.  However this is not ideal - a change of this behaviour on the SourceForge side requires end pages with SourceForge URLs to be updated, rather than just updating {{tl|repo link}}.  I was wondering about possibility of installing the extension:&lt;br /&gt;
&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Extension:RegexParserFunctions Extension:RegexParserFunctions]&lt;br /&gt;
&lt;br /&gt;
Though I'm not 100% sure if that will work.  Or does someone else know an alternative?  Cheers!&lt;br /&gt;
&lt;br /&gt;
[[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 12:09, 22 April 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
: not a solution, just a potential workaround would be checking for the most common prefix strings used in tags/branches (e.g. version, release, topic, topics) and explicitly rewrite the URL accordingly to append the /~ suffix -[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 12:59, 22 April 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:: That might be a solution.  But I don't know how to do that without regex ;)  We really only have #ifeq statements, but that has to match the whole string.&lt;br /&gt;
&lt;br /&gt;
:: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 13:44, 22 April 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
As a temporary workaround, I'll update the SourceForge {{tl|repo link}} template instructions to tell the user to append &amp;lt;code&amp;gt;/~&amp;lt;/code&amp;gt; to the branch or tag name, if the &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt; character is present.&lt;br /&gt;
&lt;br /&gt;
[[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 10:31, 20 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Discussion about quotes on the wiki ==&lt;br /&gt;
{{usr|Hooray}} have started a page now at [[FlightGear wiki:Quoting Guidelines]] ([http://wiki.flightgear.org/index.php?title=FlightGear_wiki:Quoting_Guidelines&amp;amp;oldid=96104 perm]) for a discussion regarding guidelines for the use of quotes on the wiki.  Join the discussion.&lt;br /&gt;
&lt;br /&gt;
—[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 18:17, 21 March 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In slight relation to this I have tried to make the wiki more consistently use the most common spelling and case, &amp;quot;Instant-Cquotes&amp;quot; and have changed the automatic categorization accordingly.  All articles using the {{tl|FGCquote}} template can now be found in [[:Category:Articles containing Instant-Cquotes]] (currently some ~250 articles).&lt;br /&gt;
&lt;br /&gt;
—[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 08:21, 23 March 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Reorganizing the Git articles ==&lt;br /&gt;
I've noticed that the [[Category:Git|Git articles]] suffer from duplication and are in part obsolete (especially with regard to the instructions for running Git on Windows). Thus, I propose the following reorganization:&lt;br /&gt;
* [[Development workflow]]: reorganization to explain how the patch submission process is organized from a high-level point of view (forking the repository from SourceForge, developing, pushing the commits to the personal fork, submitting a merge request/sending a patch to the mailing list);&lt;br /&gt;
* [[FlightGear Git]]: leave as is;&lt;br /&gt;
* '''Installing and configuring Git''' - new article about installing Git and configuring it (setting the username/e-mail address); merge the contents of [[FlightGear Git on Windows]] and [[Resources WRT running git on Win32]] here;&lt;br /&gt;
* [[FlightGear Git for laymen]] - make it follow [[FGW:MOS]], merge the contents of [[Howto:Start using git]] here;&lt;br /&gt;
* [[FlightGear Git: core developers]] and [[FlightGear Git: data developers]] - I'm uncertain about what I should do with them: the only piece information that would not be written in other articles is the list of alternative methods for cloning FGData;&lt;br /&gt;
* [[FlightGear Git: gitiquette]] and [[FlightGear Git: tips]] - make them follow [[FGW:MOS]].&lt;br /&gt;
Any comments? -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 06:11, 13 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
: This is sorely needed!  For [[FlightGear Git: core developers]] and [[FlightGear Git: data developers]], maybe these can be merged into something like [[FlightGear Git: working with the repositories]]?  The only real difference is the URL, but that is a minor difference with the [[:Category:Repository link templates]].  This could be generalised into a set of instructions for working with all git repositories for the core infrastructure, including forking and merge requests, with a current focus on the SourceForge web and non-web interfaces.&lt;br /&gt;
&lt;br /&gt;
: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 08:17, 13 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:: Yes, I was thinking about a similar solution as well. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 10:16, 13 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
: For the reorganisation of the articles, it would be good to make a lot of use of the {{tl|Project infrastructure}} template.  This will abstract away the SourceForge infrastructure (well some instructions will be 100% SourceForge specific, so it won't be perfect).  I would like to however have [[Template talk:Project infrastructure#Slight variation of the current architecture|Johan's design]] implemented first, as it would be quite beneficial.&lt;br /&gt;
&lt;br /&gt;
: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 18:43, 14 May 2016 (EDT)&lt;br /&gt;
:: Thanks, didn't know it existed. Right now I'm fixing some last-minute bugs before the release, but I'll have a look at this. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 09:05, 15 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
::: And while we're at it, we also have a handful of git related templates to abstract away UI-specifics, which would allow us/me to upload screenshots for different interfaces (CLI, tortoisegit etc), so that we only need to update the templates, and not touch any  of those articles. OTOH, I cannot seem to find a recent discussion of the idea, only http://wiki.flightgear.org/Talk:Development_workflow and that has not been updated in 3 years. Any opinions ? -[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 20:52, 15 May 2016 (EDT)&lt;br /&gt;
:::: I'm not fully sold on this one. I see the point of creating templates (for example, the Git commands mentioned in [[Talk:Development workflow]] can be used in aircraft pages to explain how to checkout a development version from a private repository), but, in my opinion, screenshots are a bit &amp;quot;heavy&amp;quot; to be reused in other articles (beside the Git ones). Did you plan to use them in other pages and, if yes, how? -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 14:11, 23 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== UTF-8 language pages cannot be edited ==&lt;br /&gt;
&lt;br /&gt;
This is a continuation of [[FlightGear wiki:Village pump/Archive 2015#UTF-8 language pages cannot be edited]].  I can see that wiki editors are [[Zh/FlightGear Wiki|forced to create workarounds]], as the [[Main page]] in Chinese [http://wiki.flightgear.org/index.php?title=Zh/%E9%A6%96%E9%A1%B5&amp;amp;action=edit cannot be edited].  I think it is quite important to solve this ''&amp;quot;A database query error has occurred. This may indicate a bug in the software&amp;quot;'' issue.  As the fix is quite dangerous (see {{mediawiki|Topic:S1q54kosfdkhz6w1}}), do we have a backup system?  Do we have regular mysql and ftp dumps that can be backed up locally using rsync?&lt;br /&gt;
&lt;br /&gt;
[[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 05:16, 15 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Making wiki specific templates available via editor ? == &lt;br /&gt;
We now have an increasing number of wiki specific templates that should be more widely used, so that it would make sense to integrate those with the default mediawiki editor - e.g. the URL encapsulating templates. -[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 10:12, 16 May 2016 (EDT)&lt;/div&gt;</summary>
		<author><name>Elgaton</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=FlightGear_wiki_talk:Instant-Refs&amp;diff=98504</id>
		<title>FlightGear wiki talk:Instant-Refs</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=FlightGear_wiki_talk:Instant-Refs&amp;diff=98504"/>
		<updated>2016-05-21T21:34:50Z</updated>

		<summary type="html">&lt;p&gt;Elgaton: /* Code beautifier ? */ JSLint&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== more sources ==&lt;br /&gt;
&lt;br /&gt;
at some point, we may also want to add support for other sources, such as:&lt;br /&gt;
* old forum URLs, i.e. not yet using the subdomain format (should be easy, it's just a different/additional URL after all)&lt;br /&gt;
* thread.gmane.org/gmane.games.flightgear.devel/&lt;br /&gt;
* jsbsim devel list&lt;br /&gt;
* github tickets&lt;br /&gt;
* the new SF.net issue tracker &lt;br /&gt;
* SF.net commit logs http://gitorious.org/fg/&lt;br /&gt;
* http://www.mail-archive.com/flightgear-devel@flightgear.org/ (until 2005)&lt;br /&gt;
* http://www.mail-archive.com/flightgear-devel@lists.sourceforge.net/maillist.html (until 10/2013)&lt;br /&gt;
&lt;br /&gt;
that should cover all important sources. And it would allow us to also use the same script to help populate [[FlightGear Newsletter]] &amp;amp; [[Changelog 3.2|changelogs]], but also [[Release plan/Lessons learned]]. So this could be a real time-saver. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 14:40, 1 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Automatic update of script and old quotes ==&lt;br /&gt;
Thanks for the heads-up. Now, that makes me wonder if I can adapt the script to automatically parse existing wiki articles and update cquotes there automatically by re-opening the URL and re-running the extraction logic :) BTW: That reminds me: I was going to investigate adopting the '''downloadURL''' attribute[http://stackoverflow.com/questions/15095055/why-isnt-my-greasemonkey-script-updating] so that scripts can auto-update --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 22:51, 11 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
:: if we should continue to see this widely used, having a good way to re-download and re-run the script on pages with existing cquotes would be a good way to automatically update quotes. For that, we would want to encode certain meta info in each template, e.g.:&lt;br /&gt;
* script version&lt;br /&gt;
* quoting date/time&lt;br /&gt;
* quote URL&lt;br /&gt;
* selection offsets &lt;br /&gt;
* quoting settings (format)&lt;br /&gt;
&lt;br /&gt;
We can hook into form submission to update arbitrary quotes/contents using this: http://commons.oreilly.com/wiki/index.php/Greasemonkey_Hacks/Developer_Tools#Intercept_and_Modify_Form_Submissions&lt;br /&gt;
&lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 07:19, 15 November 2015 (EST)&lt;br /&gt;
&lt;br /&gt;
=== Hosting ===&lt;br /&gt;
The script seems to be about to become sufficiently complex to deserve actual hosting:&lt;br /&gt;
* http://wiki.greasespot.net/User_Script_Hosting&lt;br /&gt;
* https://openuserjs.org/&lt;br /&gt;
&lt;br /&gt;
(that would allow updating the script automatically)&lt;br /&gt;
&lt;br /&gt;
: Hi, is there any progress being made on this? I think the best way to host it would be to put in in a SourceForge repository under the FlightGear project (I don't know if it allows direct downloads, though, and we would need to relicense the script because [https://opensource.org/faq#public-domain public domain licenses are not OSI-approved]); otherwise, I can submit it to [https://greasyfork.org/ GreasyFork] (OpenUserJS is unsuitable as [https://openuserjs.org/about/Terms-of-Service public domain licenses are not allowed]). -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 03:58, 1 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:: I don't think anybody has looked into this recently - however, relicensing should be a no-brainer, given that all the code is in the public domain anyway. I am not sure if it's worth the hassle to put up under sourceforge/FlightGear; we also need to keep in mind that this is not exactly the most popular &amp;quot;tool&amp;quot; around here. So, before this becomes even better accessible, it might be a good idea to comply with some of the requests made, e.g. by adding support for a different output mode (without using the FGCquote template, just the copied text, plus the ref part), so that quote-heavy pages don't look that obnoxious.&lt;br /&gt;
:: Regarding hosting in general, I still think it may be a good idea, but we would probably need to make sure that some requirements are met, e.g. having a revision history, and to provide other contributors with access-alternatively, we should maintain a copy of the script in the wiki, and add a note saying that changes to it will be reviewed/integrated with the hosted script by one of us (if you'd volunteer to help with that, I'd suggest to just go ahead and set up a public repository).&lt;br /&gt;
:: Admittedly, this is going to remain a fairly FG specific script, it would need quite a bit of work to become useful for other purposes (even though other OSS projects may be easy to support). --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 06:33, 1 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
::: OK, I think we can leave the script here and host it on GreasyFork (it allows public domain scripts) - I'll put the page on my watchlist to make sure I update the script there every time there's a version bump. Does that look good to you and the other contributors? -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 09:26, 1 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:::: Sounds good to me, given how the script has evolved over time, we've probably hit a natural limit already, i.e. being able to use multiple files easily, and update scripts automatically sounds like a useful thing to me. I don't know if greasyfork supports &amp;quot;teams&amp;quot; of contributors for better collaboration ? It might also be a good idea to generalize the script so that it supports arbitrary phpBB installations and mailing list archives other than just sourceforge (think gmane) - and maybe output formats other than just wikimedia markup, that way, the script may become more useful over time.--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 13:46, 1 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
::::: It doesn't as it only offers a user script downloading facility (source code repositories like GitHub and SourceForge are better suited for the kind of work you mention). I'll wait a bit in case Red Leader, Philosopher or bigstones have any objections/remarks, then I'll upload the script there. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 17:14, 1 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:: do they support extensions spread across multiple files ? That is something that would help us quite a bit cleaning up the current code, which has become a bit convoluted over time. Apart from that, nothing wrong with github et al - I am just not sure if they're suitable for automatically propagating updated changes.--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 10:12, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
::: No, not that I know of (generally speaking, all user scripts are made of a single .user.js file). We could &amp;quot;hack&amp;quot; it by splitting the current script in multiple files and requiring them from a main one as libraries via the &amp;lt;tt&amp;gt;@include&amp;lt;/tt&amp;gt; directive, but that would rule out most hosting solutions (many providers only allow GreaseMonkey scripts which include additional files only from a handful of trusted domains/CDNs, for safety reasons).&lt;br /&gt;
::: As for propagating changes on GitHub and other code repository, the update URL must remain constant throughout the lifetime of the script. I'm sure this can be done on GitHub by publishing updates not as releases (where the addresses change), but on GitHub Pages (a user script I use does exactly this); on SourceForge, the usual download hosting could do the trick, but I'd need to perform a test first. (I'd prefer SF to keep the script &amp;quot;inside&amp;quot; the FG project hierarchy, if possible). -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 10:50, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
: actually, user scripts can be compromised of multiple files, e.g. via the require directive [http://stackoverflow.com/questions/8695459/is-it-possible-to-split-greasemonkey-user-scripts-into-multiple-files]. Personally, I would like to make use of that - we are already using that to include jQuery stuff, and it would help us organize the script a little better. I am not oposed to seeing the script hosted as some part of FG/SF, but I just don't think it's going to be a very popular idea - so far, everything worked out without major hinderance, so I would rather use an independent hosting solution, or continue to use the wiki to ensure that the barrier to entry/contributing isn't raised, e.g. by going through merge requests etc. Major contributions to the script like those from bigstones or Red Leader were simply &amp;quot;dropped&amp;quot; here directly, so this seems to have worked out really well.--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 11:26, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:: I've checked the [https://greasyfork.org/it/help/external-scripts GreasyFork external script policy]: as long as all the files are hosted on/uploaded to GreasyFork, it's not a problem. (Also, sorry about the typo, I wrote &amp;lt;tt&amp;gt;@include&amp;lt;/tt&amp;gt; instead of &amp;lt;tt&amp;gt;@require&amp;lt;/tt&amp;gt; by mistake). I guess I can proceed with the upload now? -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 12:22, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
: sure, why not - it's in the public domain after all - feel free to make any changes to the script to have it auto-update. We can review everything once we have gathered a little more experience with this kind of scheme. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 12:27, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:: {{done}} - I'm updating the installation instructions in the main page. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 13:52, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
::: Script at: https://greasyfork.org/en/scripts/19331-instant-cquotes &lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 14:18, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:::: Regarding updates, bumping the version number is fine - I'll take the script at the wiki revision where the version is bumped and upload it. (Note that I will not perform any prior testing, so be extra careful - maybe I should add this in the note above the script?). -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 18:08, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:: sounds good, I will be sure to stop updating the version number without prior testing, we could also add some tests to the code to spot the more obvious mistakes - in fact, there is already an OpenLink helper that could be used to download a few postings and try to extract the corresponding fields, so that we would only bump the version number if that succeeds. BTW: Thanks for handling the hosting part, much appreciated ! --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 18:25, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Issues ==&lt;br /&gt;
=== too greedy non-greedy regexes ===&lt;br /&gt;
The problem described in the previous section regarding regexes that eat up half messages seems to be related to my  [http://blog.liip.ch/archive/2009/07/24/the-greedyness-of-non-greedy-regular-expressions.html misunderstanding of the non-greediness]. So, I managed to fix it for this one case, but this means that using .*? to match everything until you meet the following character (as I currently do pretty much everywhere) is dangerous and prone to failure. Any occurrence of that should be changed as I did in [http://wiki.flightgear.org/index.php?title=FlightGear_wiki:Instant-Cquotes&amp;amp;oldid=72839 this edit] and that's clearly cumbersome, not to say that it can still be incorrect: say I have&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;a someprop=&amp;quot;href&amp;quot; href=&amp;quot;http://www.link.org&amp;quot; ... &amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
If I want to mach anything between a and href, I use &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;[^(?:href)]*&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;, but that would match only up to the text inside someprop, so I'd have to check that it's not inside doublequotes... Well, I guess this is getting too complicated for handling it [http://blog.codinghorror.com/parsing-html-the-cthulhu-way/ the Chtulu way].&lt;br /&gt;
&lt;br /&gt;
So my approach would be: fix this whenever the problem comes up, but don't overdo because we're already moving in dangerous ground. Or, rewrite it all using ''only'' xpaths *sobs*.&lt;br /&gt;
--[[User:Bigstones|Bigstones]] ([[User talk:Bigstones|talk]]) 16:49, 17 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
=== regex vectors ===&lt;br /&gt;
&lt;br /&gt;
When testing things I realized that you are right: there are some scenarios where the regex may fail depending on how &amp;quot;complete&amp;quot; the selection is, because we obviously have hard-coded assumptions here. I'll see if it's feasible to also support vectors for regexes to extract the corresponding fields and try each regex in order to get a certain field, or if that doesn't make any sense... But quoting with/without author (anonymous quote) would be a valid test case here.--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 16:46, 16 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
: Probably going to look into this sooner or later because this could be a simple solution to also support PM quoting - without having to parse the actual URL, we'd just try different regexes in order and use the one that succeeds. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 16:46, 16 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
=== Syntaxhighlighting ===&lt;br /&gt;
Need to investigate what needs to be updated to support quoting code sections, as per [http://forum.flightgear.org/viewtopic.php?f=66&amp;amp;t=21855&amp;amp;p=212585#p212581] --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 22:33, 14 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
=== Postings that break our script for some reason ===&lt;br /&gt;
* http://forum.flightgear.org/viewtopic.php?f=19&amp;amp;t=23365&lt;br /&gt;
&lt;br /&gt;
== Misc notes ==&lt;br /&gt;
&lt;br /&gt;
=== Detecting failed XPaths === &lt;br /&gt;
you've got a point, we should probably check if xpath/regexes succeed or fail, and show a warning so that we know that the scripts needs to be updated because some xpath/regex may have changed. &lt;br /&gt;
&lt;br /&gt;
=== Paragraphs / br (trailing slash) ===&lt;br /&gt;
There are some minor issues now, i.e. newline2br will no longer contain the trailing forward slash, so there's probably some JavaScript/regex oddity involved here, maybe slashes just need to be escaped. Will be testing the code with a few different forum postings and check the resulting cquote&lt;br /&gt;
: {{done}}. That's because newline2br wasn't used at all in html mode. I added addNewlines which puts newlines after br's and list related tags, if there are more newlines to be added that should be the place.&lt;br /&gt;
: --[[User:Bigstones|Bigstones]] ([[User talk:Bigstones|talk]]) 14:03, 17 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
=== support/ignore highlighted keywords/smilies ===&lt;br /&gt;
see [[Understanding Forward Compatibility]] for examples&lt;br /&gt;
: {{done}} --[[User:Bigstones|Bigstones]] ([[User talk:Bigstones|talk]]) 15:13, 17 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Beyond just cquotes (newsletter/changelog) ==&lt;br /&gt;
&lt;br /&gt;
Gijs has recently revamped the newsletter template rather significantly, see: [[FlightGear_Newsletter_June_2014]], and [[User_talk:Gijs#06.2F2014_newsletter:_too_much_of_a_]] - basically, we could extend the script to support another output FORMAT to directly create markup for the newsletter/changelog. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 20:40, 30 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
== more styles/output formats ==&lt;br /&gt;
&lt;br /&gt;
looking at some of the cleanup done by Red Leader recently, we could also directly support other styles/output formats to directly provide a format that looks well enough without requiring tons of manual editing. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 11:11, 13 February 2015 (EST)&lt;br /&gt;
&lt;br /&gt;
== token matching for keywords/variables ==&lt;br /&gt;
&lt;br /&gt;
seems like it might make sense to match common keywords/acronyms and variables, such as e.g.:&lt;br /&gt;
* FG_ROOT =&amp;gt; [[$FG_ROOT]]&lt;br /&gt;
* FG_HOME =&amp;gt;  [[$FG_HOME]]&lt;br /&gt;
* FG_SRC =&amp;gt; [[$FG_SRC]]&lt;br /&gt;
&lt;br /&gt;
file names with a known prefix like $FG_ROOT could even be pattern-matched using git link: $FG_ROOT/Nasal/canvas/MapStructure.nas would become [[$FG_ROOT]]{{Git link|gitorious|fg/fgdata|master|Nasal/canvas/MapStructure.nass|text=/Nasal/canvas/MapStructure.nas}}&lt;br /&gt;
&lt;br /&gt;
Equally, we could match common property paths to use code tags, e.g.: /sim/rendering would become &amp;lt;code&amp;gt;/sim/rendering&amp;lt;/code&amp;gt;&lt;br /&gt;
Ultimately, it might be a good idea to get in touch with Johan_G, Gijs and Red Leader to see what kind of format they'd prefer, especially because this could then be directly used for creating newsletter contents. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 11:19, 13 February 2015 (EST)&lt;br /&gt;
&lt;br /&gt;
== matching repository references using git link template ==&lt;br /&gt;
&lt;br /&gt;
Most of us commonly refer to repository files using either the $FG_* references, or relative paths in the form of &amp;lt;code&amp;gt;src/Main/fg_init.cxx:line number&amp;lt;/code&amp;gt;, we could automatically convert such references using the git/repo link template, e.g.: &lt;br /&gt;
&lt;br /&gt;
{{FGCquote&lt;br /&gt;
  |Further investigation found that the launcher *is* trying to add this directory to fg-aircraft (src/GUI/QtLauncher.cxx:772), but that this doesn't work because this option is processed before the launcher is run (intentionally, to allow the launcher to find aircraft in fg-aircraft: '''src/Main/main.cxx:448''').&lt;br /&gt;
  |{{cite web |url=http://sourceforge.net/p/flightgear/mailman/message/33686356/&lt;br /&gt;
     |title=&amp;lt;nowiki&amp;gt;Re: [Flightgear-devel] Launcher issues on Linux&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
     |author=&amp;lt;nowiki&amp;gt;Rebecca N. Palmer&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
     |date=&amp;lt;nowiki&amp;gt;2015-04-01&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
   }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 12:48, 1 April 2015 (EDT)&lt;br /&gt;
&lt;br /&gt;
== chrome specific port ==&lt;br /&gt;
&lt;br /&gt;
Hi Red Leader, when/if you do come up with a chrome specific version of the script, I would suggest to refactor existing APIs accordingly, so that we can come up with a common library of general purpose/utility helpers, so that both scripts can co-exist and use a common/shared file (think all the extraction/transformation logic), by referencing an external .js/JavaScript file that will be maintained/updated and hosted separately. I think this could be accomplished easily using jsfiddle. So basically, I am suggesting to come up with a shared back-end for both versions of the script. Given the complexity we're reaching meanwhile, as well as the number of edits and contributors, it may also make sense to consider using github for this at some point. One of the main advantages being that we could easily distribute updates automatically to all people who've installed the script, without them having to do anything manually.--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 08:38, 23 June 2015 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Development resources ==&lt;br /&gt;
&lt;br /&gt;
* https://www.youtube.com/watch?v=xpXNDT0SxM0&lt;br /&gt;
* http://wiki.greasespot.net/GM_getResourceText&lt;br /&gt;
* http://stackoverflow.com/questions/14594346/create-a-config-or-options-page-for-a-greasemonkey-script&lt;br /&gt;
&lt;br /&gt;
== Future focus/development and priorities (De-quoting) ==&lt;br /&gt;
&lt;br /&gt;
Given that most people involved in maintaining the wiki don't seem to particularly appreciate the nature of articles consisting mainly of quotes, and that we don't seem to have any other good way to populate new articles quickly, I was thinking of changing the focus of the script to dynamically create articles using quotes (with proper refs), that would be merely copy-edited, i.e. using the process we are currently using to &amp;quot;de-quote&amp;quot; such articles by 1) categorizing related quotes, 2) coming up with headers/sub-headers, 3) re-writing/merging certain quotes, 4) attributing them - linking back to the quotes archives.&lt;br /&gt;
Should we decide to pursue this, the script would be turned into a &amp;quot;wizard&amp;quot; where we can topics and sub-topics (wiki headings) and then add arbitrary text using the existing approach, but without using cquotes - i.e. the focus would be on extracting relevant contents, distilling them down and adding plenty of refs, including a references section at the bottom. Some tokens/words could be changed dynamically, but some kind of proof-reading/copy-editing would still need to be done afterwards, because people tend to use first person speech in their announcements/postings, which we would need to convert to 3rd person semi-automagically. Thoughts/ideas ?--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 07:11, 15 November 2015 (EST)&lt;br /&gt;
&lt;br /&gt;
== changing and automating regex/xpath handling ==&lt;br /&gt;
{{See also|#Genetic_Expression_solver}}&lt;br /&gt;
&lt;br /&gt;
We have currently hard-coded handling of different websites, regexes and xpath expressions so that things are a  bit fragile at the moment, and once a website changes its style/template, our script would break immediately. However, we could change the way the script works by using a very simple NN (neural network) to come up with matching regex/xpath expressions automatically. The way this could work would be &amp;quot;supervised&amp;quot; training, where we would replace/adapt our existing CONFIG hash with a vector of URLs and contents to be extracted (date, time, title, posting). This kind of data would suffice entirely for a neural network to self-train itself and &amp;quot;learn&amp;quot; how to come up with regex/xpath expressions to extract the relevant contents, including not only hard-coded websites like sourceforge, but even completely different websites (think gmane) - because the &amp;quot;learning&amp;quot; routine would self-adapt by looking at how to get its contents, and never contain any hard-coded regex/xpath expressions anymore. The CONFIG hash would end up being a vector with &amp;quot;training data&amp;quot; for different websites to be supported. And whenever an expression fails, it could re-train itself accordingly.--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 13:33, 15 November 2015 (EST)&lt;br /&gt;
&lt;br /&gt;
== nested quotes and AJAX for thread titles ==&lt;br /&gt;
&lt;br /&gt;
{{FGCquote&lt;br /&gt;
|1= http://sourceforge.net/p/flightgear/mailman/message/33451055/&lt;br /&gt;
{{cquote|As we move forward with FlightGear development and future versions, we will be expanding the &amp;quot;in app&amp;quot; aircraft center. This dialog inside flightgear lets you select, download, and switch to any of the aircraft in the library.|Curt}}&lt;br /&gt;
|2= {{cite web&lt;br /&gt;
  | url    = http://forum.flightgear.org/viewtopic.php?p=259879#p259879&lt;br /&gt;
  | title  = &amp;lt;nowiki&amp;gt;Re: New Canvas GUI&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  | author = &amp;lt;nowiki&amp;gt;Hooray&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  | date   = Oct 7th, 2015&lt;br /&gt;
  }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== AJAX mode/testing ==&lt;br /&gt;
&lt;br /&gt;
We should probably add a dialog to store credentials that we can use for accessing the wiki, which would need to be shown after installing the script, i.e. first-time use&lt;br /&gt;
&lt;br /&gt;
* http://stackoverflow.com/questions/14594346/create-a-config-or-options-page-for-a-greasemonkey-script&lt;br /&gt;
* http://commons.oreilly.com/wiki/index.php/Greasemonkey_Hacks/Getting_Started#During_Installation&lt;br /&gt;
* https://www.safaribooksonline.com/library/view/greasemonkey-hacks/0596101651/ch01s06.html&lt;br /&gt;
&lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 12:59, 20 November 2015 (EST)&lt;br /&gt;
&lt;br /&gt;
== libraries ==&lt;br /&gt;
&lt;br /&gt;
Referring to the [[#Hosting]] section, and my comment on wanting to use additional libs (like jQuery), I am primarily thinking about using a wizard-framework (e.g. jQuery steps) and a framework for creating wikimedia editor plugins (actions):&lt;br /&gt;
&lt;br /&gt;
* http://mstratman.github.io/jQuery-Smart-Wizard/&lt;br /&gt;
* http://www.jquery-steps.com/&lt;br /&gt;
* http://www.jqueryrain.com/demo/jquery-step-form-wizard/&lt;br /&gt;
* https://www.mediawiki.org/wiki/Extension:WikiEditor&lt;br /&gt;
&lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 12:07, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== About dequoting the script's article ==&lt;br /&gt;
&lt;br /&gt;
Thanks for doing this, but I am frankly not sure if it's worth the effort - there are much more popular/important articles using tons of quotes than this one, and given the reputation of the script, having quotes in this article may actually be a useful thing to make the case for having quotes in the first place - thus, I would frankly not spend much time going through this particular article - in fact, I'd be very surprised if the greasyfork download stats showed more than 3-5 people actually downloading, and using, the script - so this is really just a niche tool, and we probably better spend our time doing other things, and reviewing other wiki articles, than the script's article - at the very least, I would suggest to retain the references to the original discussions revolving these quotes (just my 2c). --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 19:00, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
: {{done}} I've added back the quotes as references. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 02:53, 3 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Script configuration (persistence) ==&lt;br /&gt;
&lt;br /&gt;
* https://wiki.greasespot.net/GM_config&lt;br /&gt;
* https://github.com/sizzlemctwizzle/GM_config/wiki&lt;br /&gt;
* https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API&lt;br /&gt;
&lt;br /&gt;
== Work in progress ==&lt;br /&gt;
&lt;br /&gt;
We have now several more or less related development efforts going on, and the code is also growing because of that - so it seems to make sense to summarize what's been going on recently. In general, all changes were made in response to the collection of feature requests and ideas we have accumulated over time  - specifically, that means that the following roadmap is in the process of being implemented:&lt;br /&gt;
&lt;br /&gt;
* establish unit testing, and add a few self-tests, so that the script can be more easily tested, updated/reviewed in the future&lt;br /&gt;
* rework the script to more easily support other sources (think gmane)&lt;br /&gt;
* make it much easier to update modified xpath/regex expressions (i.e. provide a UI for that)&lt;br /&gt;
* support persistence for script-specific settings&lt;br /&gt;
* make it easier for people to port/maintain the script by encapsulating platform specifics&lt;br /&gt;
* support asynchronous fetching of postings (AJAX), e.g. to fetch posting titles, attachments etc&lt;br /&gt;
* prepare the groundwork for supporting template-based output formats (think newsletter, changelog, articles)&lt;br /&gt;
* review what's necessary to allow the script to update fgcquote-based quotes automagically&lt;br /&gt;
&lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 16:47, 4 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== External genetic/neural network libraries ==&lt;br /&gt;
While uploading the latest version of the script, I noticed that the Genetic and Synaptic libraries are hosted on sites not on [https://greasyfork.org/en/help/external-scripts the approved GreasyFork list]. Shall I ask them to host them? -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 13:28, 11 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
: Thanks for pointing that out, I missed that completely, because everything is working correctly here - but obviously, I rarely get to actually download/install the latest version via greasyfork. Those libs should be safe to be added to the list, i.e. they're fairly established/popular, lest I'd not be using them. For now, this is just an experiment anyway. The idea is to update the xpath/regex code to evolve if/when the underlying website (theme) changes. But if there is a problem, we could use other libs - the code is just used for testing ATM. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 13:41, 11 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
* https://github.com/subprotocol/genetic-js&lt;br /&gt;
* https://github.com/cazala/synaptic&lt;br /&gt;
&lt;br /&gt;
:: {{ongoing}} I have submitted the libraries to the JSDelivr CDN; once they are up, I'll change the source URLs in the script and update it on GreasyFork as well. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 18:32, 17 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
::: Hi Elgaton, thank you for taking care of this, it's very much appreciated ! --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 18:55, 17 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:::: You're welcome! My merge requests for the CDN were approved (this took a bit longer than expected because I had made a small mistake - I forgot to include a file required by the Genetic.js library). The libraries should be up in a day or two, at which point I'll update the URLs in the script and submit the new version to GreasyFork. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 02:59, 20 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
::::: {{done}} Everything should be fine now. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 09:16, 20 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:: Thank you for all the help with this, and also for updating the greasyfork info/screenshots ! --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 07:16, 21 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Genetic Expression solver ==&lt;br /&gt;
[[File:Instant-cquotes-genetic-regex-solving.png|thumb|Screenshot showing the instant cquotes script with integrated regex solving support using genetic algorithms.]]&lt;br /&gt;
&lt;br /&gt;
The genetic-js framework has been integrated, it is intended to help solve xpath/regex expressions procedurally using genetic algorithms/programming. &lt;br /&gt;
&lt;br /&gt;
The idea is to provide a set of desired outputs (needles), available input data (haystack), and use existing (possibly outdated) regex/xpath expressions to seed a pool with potential solutions for retrieving the desired output. For now, this is just proof-of-concept, i.e. just an experiment.&lt;br /&gt;
&lt;br /&gt;
For example, let's consider the typical format of a from header for any sourceforge posting:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var regexTests = [&lt;br /&gt;
  {haystack: &amp;quot;From: John Doe &amp;lt;John@do...&amp;gt; - 2020-07-02 17:36:03&amp;quot;, needle: &amp;quot;John Doe&amp;quot;}, &lt;br /&gt;
  {haystack: &amp;quot;From: Marc Twain &amp;lt;Marc@ta...&amp;gt; - 2010-01-03 07:36:03&amp;quot;, needle: &amp;quot;Marc Twain&amp;quot;},&lt;br /&gt;
  {haystack: &amp;quot;From: George W. Bush &amp;lt;GWB@wh...&amp;gt; - 2055-11-11 17:33:13&amp;quot;, needle: &amp;quot;George W. Bush&amp;quot;}&lt;br /&gt;
];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The basic idea is to run a fitness function and score regex expressions based on not throwing an exception (which makes them valid), and by checking if the desired tokens are part of the output string, and evolve (mutate/cross-over) the &amp;quot;fittest&amp;quot; expressions - i.e. those that satisfy at least /some/ of the heuristics.&lt;br /&gt;
&lt;br /&gt;
Some of the metrics that can be used by the fitness function to determine if an expression is &amp;quot;fit&amp;quot;, are:&lt;br /&gt;
* valid expression&lt;br /&gt;
* relative offset/excess bytes in matches string&lt;br /&gt;
* number of examples it can successfully extract&lt;br /&gt;
* length of the expression&lt;br /&gt;
* runtime of the expression&lt;br /&gt;
&lt;br /&gt;
The search space, and runtime, can be significantly reduced by looking at similarities between all examples and coming up with a subset string that contains all identical components (e.g. the &amp;lt;code&amp;gt;From:&amp;lt;/code&amp;gt; part in the author regex) and use that for seeding the initial generations.&lt;br /&gt;
&lt;br /&gt;
Ultimately, this would allow the script to self-update its regex/xpath expressions if/when the underlying website (themes) change, but it would also allow to add support for new websites, without ever manually adding the required xpath/regex expressions, i.e. all that is needed is a sufficiently large number of example datasets to obtain the author, date and title information, and a URL for the script to download the HTML markup of the posting in question:&lt;br /&gt;
&lt;br /&gt;
{{Note|The date field won't work as is, because it's actually post-processed using a transformation function, so we'd need to undo the transformation or use the actual date string instead}}&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt; // vector with tests to be executed for sanity checks (unit testing)&lt;br /&gt;
    tests: [&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://sourceforge.net/p/flightgear/mailman/message/35059454/',&lt;br /&gt;
        author: 'Erik Hofman',&lt;br /&gt;
        date: 'May 3rd, 2016', // NOTE: using the transformed date here &lt;br /&gt;
        title: 'Re: [Flightgear-devel] Auto altimeter setting at startup (?)'&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://sourceforge.net/p/flightgear/mailman/message/35059961/',&lt;br /&gt;
        author: 'Ludovic Brenta',&lt;br /&gt;
        date: 'May 3rd, 2016',&lt;br /&gt;
        title: 'Re: [Flightgear-devel] dual-control-tools and the limit on packet size'&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://sourceforge.net/p/flightgear/mailman/message/20014126/',&lt;br /&gt;
        author: 'Tim Moore',&lt;br /&gt;
        date: 'Aug 4th, 2008',&lt;br /&gt;
        title: 'Re: [Flightgear-devel] Cockpit displays (rendering, modelling)'&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://sourceforge.net/p/flightgear/mailman/message/23518343/',&lt;br /&gt;
        author: 'Tim Moore',&lt;br /&gt;
        date: 'Sep 10th, 2009',&lt;br /&gt;
        title: '[Flightgear-devel] Atmosphere patch from John Denker'&lt;br /&gt;
      } // add other tests below&lt;br /&gt;
&lt;br /&gt;
    ], // end of vector with self-tests&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note how this no longer contains any hard-coded xpath/regex expressions - instead, the script can refer to the website specific defaults, and try those first, and if they fail, use those to seed new generations and evolve them procedurally until all tests succeed.&lt;br /&gt;
&lt;br /&gt;
For a regex to be valid, it must work for all tests/examples.&lt;br /&gt;
&lt;br /&gt;
Once the regex solver is working correctly, the code can be further generalized to also evolve xpath expressions (NOTE: the DOMParser API is /not/ available to webworkers ...) and chain those two components together.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* http://regex.inginf.units.it/how.html&lt;br /&gt;
* http://www.i-programmer.info/programming/perl/9503-automatically-generating-regular-expressions-with-genetic-programming.html&lt;br /&gt;
* http://jkff.info/articles/ire/&lt;br /&gt;
* http://www.networkworld.com/article/2955126/software/genetic-programming-meets-regular-expressions.html&lt;br /&gt;
* https://handcraftsman.wordpress.com/2012/04/11/evolving-a-regular-expression-with-go/&lt;br /&gt;
* http://stackoverflow.com/questions/4880402/how-to-auto-generate-regex-from-given-list-of-strings&lt;br /&gt;
* http://regex.inginf.units.it/&lt;br /&gt;
* http://www.genetic-programming.org/hc2014/Bartoli-Paper.pdf&lt;br /&gt;
&lt;br /&gt;
== Hierarchical Clustering  ==&lt;br /&gt;
&lt;br /&gt;
Been tinkering with a JavaScript module to automatically cluster postings based on certain keywords in the topic/title or posting (e.g. Nasal, Canvas, 2D API, rendering): https://harthur.github.io/clusterfck/&lt;br /&gt;
&lt;br /&gt;
Note that in conjunction with processing article sections and/or whole articles, this could help automatically come up with matching postings for articles and vice versa.&lt;br /&gt;
&lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 18:11, 19 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Upcoming dependencies ==&lt;br /&gt;
&lt;br /&gt;
The script is now using [http://markitup.jaysalvat.com/home/ markitup] to create the template editor. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 10:18, 21 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
: I've [https://github.com/jsdelivr/jsdelivr/pull/11757 submitted a pull request] for the library to be distributed by jsDelivr. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 16:08, 21 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Code beautifier ? ==&lt;br /&gt;
&lt;br /&gt;
I still had, and have, pending changes that would need to go through the same beautifier you're using, or they'd be lost -  so for now, I have just overwritten your  beautified code, hope that you didn't do this manually (there really are tons of automated and configurable beautifiers out there). --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 15:59, 21 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
: Of course not - let me know when you've incorporated all changes so that I can beautify the script again. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 16:31, 21 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:: I have been using some web-based JavaScript syntax checking tools, too (e.g. www.jshint.com), so if it's a website, too - let's just share/document these tools here.--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 16:34, 21 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
::: I use [http://www.jslint.com JSLint] plus a bit of manual editing (if needed). -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 17:34, 21 May 2016 (EDT)&lt;/div&gt;</summary>
		<author><name>Elgaton</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=FlightGear_wiki_talk:Instant-Refs&amp;diff=98502</id>
		<title>FlightGear wiki talk:Instant-Refs</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=FlightGear_wiki_talk:Instant-Refs&amp;diff=98502"/>
		<updated>2016-05-21T20:32:02Z</updated>

		<summary type="html">&lt;p&gt;Elgaton: /* Code beautifier ? */ Reply&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== more sources ==&lt;br /&gt;
&lt;br /&gt;
at some point, we may also want to add support for other sources, such as:&lt;br /&gt;
* old forum URLs, i.e. not yet using the subdomain format (should be easy, it's just a different/additional URL after all)&lt;br /&gt;
* thread.gmane.org/gmane.games.flightgear.devel/&lt;br /&gt;
* jsbsim devel list&lt;br /&gt;
* github tickets&lt;br /&gt;
* the new SF.net issue tracker &lt;br /&gt;
* SF.net commit logs http://gitorious.org/fg/&lt;br /&gt;
* http://www.mail-archive.com/flightgear-devel@flightgear.org/ (until 2005)&lt;br /&gt;
* http://www.mail-archive.com/flightgear-devel@lists.sourceforge.net/maillist.html (until 10/2013)&lt;br /&gt;
&lt;br /&gt;
that should cover all important sources. And it would allow us to also use the same script to help populate [[FlightGear Newsletter]] &amp;amp; [[Changelog 3.2|changelogs]], but also [[Release plan/Lessons learned]]. So this could be a real time-saver. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 14:40, 1 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Automatic update of script and old quotes ==&lt;br /&gt;
Thanks for the heads-up. Now, that makes me wonder if I can adapt the script to automatically parse existing wiki articles and update cquotes there automatically by re-opening the URL and re-running the extraction logic :) BTW: That reminds me: I was going to investigate adopting the '''downloadURL''' attribute[http://stackoverflow.com/questions/15095055/why-isnt-my-greasemonkey-script-updating] so that scripts can auto-update --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 22:51, 11 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
:: if we should continue to see this widely used, having a good way to re-download and re-run the script on pages with existing cquotes would be a good way to automatically update quotes. For that, we would want to encode certain meta info in each template, e.g.:&lt;br /&gt;
* script version&lt;br /&gt;
* quoting date/time&lt;br /&gt;
* quote URL&lt;br /&gt;
* selection offsets &lt;br /&gt;
* quoting settings (format)&lt;br /&gt;
&lt;br /&gt;
We can hook into form submission to update arbitrary quotes/contents using this: http://commons.oreilly.com/wiki/index.php/Greasemonkey_Hacks/Developer_Tools#Intercept_and_Modify_Form_Submissions&lt;br /&gt;
&lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 07:19, 15 November 2015 (EST)&lt;br /&gt;
&lt;br /&gt;
=== Hosting ===&lt;br /&gt;
The script seems to be about to become sufficiently complex to deserve actual hosting:&lt;br /&gt;
* http://wiki.greasespot.net/User_Script_Hosting&lt;br /&gt;
* https://openuserjs.org/&lt;br /&gt;
&lt;br /&gt;
(that would allow updating the script automatically)&lt;br /&gt;
&lt;br /&gt;
: Hi, is there any progress being made on this? I think the best way to host it would be to put in in a SourceForge repository under the FlightGear project (I don't know if it allows direct downloads, though, and we would need to relicense the script because [https://opensource.org/faq#public-domain public domain licenses are not OSI-approved]); otherwise, I can submit it to [https://greasyfork.org/ GreasyFork] (OpenUserJS is unsuitable as [https://openuserjs.org/about/Terms-of-Service public domain licenses are not allowed]). -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 03:58, 1 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:: I don't think anybody has looked into this recently - however, relicensing should be a no-brainer, given that all the code is in the public domain anyway. I am not sure if it's worth the hassle to put up under sourceforge/FlightGear; we also need to keep in mind that this is not exactly the most popular &amp;quot;tool&amp;quot; around here. So, before this becomes even better accessible, it might be a good idea to comply with some of the requests made, e.g. by adding support for a different output mode (without using the FGCquote template, just the copied text, plus the ref part), so that quote-heavy pages don't look that obnoxious.&lt;br /&gt;
:: Regarding hosting in general, I still think it may be a good idea, but we would probably need to make sure that some requirements are met, e.g. having a revision history, and to provide other contributors with access-alternatively, we should maintain a copy of the script in the wiki, and add a note saying that changes to it will be reviewed/integrated with the hosted script by one of us (if you'd volunteer to help with that, I'd suggest to just go ahead and set up a public repository).&lt;br /&gt;
:: Admittedly, this is going to remain a fairly FG specific script, it would need quite a bit of work to become useful for other purposes (even though other OSS projects may be easy to support). --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 06:33, 1 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
::: OK, I think we can leave the script here and host it on GreasyFork (it allows public domain scripts) - I'll put the page on my watchlist to make sure I update the script there every time there's a version bump. Does that look good to you and the other contributors? -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 09:26, 1 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:::: Sounds good to me, given how the script has evolved over time, we've probably hit a natural limit already, i.e. being able to use multiple files easily, and update scripts automatically sounds like a useful thing to me. I don't know if greasyfork supports &amp;quot;teams&amp;quot; of contributors for better collaboration ? It might also be a good idea to generalize the script so that it supports arbitrary phpBB installations and mailing list archives other than just sourceforge (think gmane) - and maybe output formats other than just wikimedia markup, that way, the script may become more useful over time.--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 13:46, 1 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
::::: It doesn't as it only offers a user script downloading facility (source code repositories like GitHub and SourceForge are better suited for the kind of work you mention). I'll wait a bit in case Red Leader, Philosopher or bigstones have any objections/remarks, then I'll upload the script there. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 17:14, 1 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:: do they support extensions spread across multiple files ? That is something that would help us quite a bit cleaning up the current code, which has become a bit convoluted over time. Apart from that, nothing wrong with github et al - I am just not sure if they're suitable for automatically propagating updated changes.--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 10:12, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
::: No, not that I know of (generally speaking, all user scripts are made of a single .user.js file). We could &amp;quot;hack&amp;quot; it by splitting the current script in multiple files and requiring them from a main one as libraries via the &amp;lt;tt&amp;gt;@include&amp;lt;/tt&amp;gt; directive, but that would rule out most hosting solutions (many providers only allow GreaseMonkey scripts which include additional files only from a handful of trusted domains/CDNs, for safety reasons).&lt;br /&gt;
::: As for propagating changes on GitHub and other code repository, the update URL must remain constant throughout the lifetime of the script. I'm sure this can be done on GitHub by publishing updates not as releases (where the addresses change), but on GitHub Pages (a user script I use does exactly this); on SourceForge, the usual download hosting could do the trick, but I'd need to perform a test first. (I'd prefer SF to keep the script &amp;quot;inside&amp;quot; the FG project hierarchy, if possible). -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 10:50, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
: actually, user scripts can be compromised of multiple files, e.g. via the require directive [http://stackoverflow.com/questions/8695459/is-it-possible-to-split-greasemonkey-user-scripts-into-multiple-files]. Personally, I would like to make use of that - we are already using that to include jQuery stuff, and it would help us organize the script a little better. I am not oposed to seeing the script hosted as some part of FG/SF, but I just don't think it's going to be a very popular idea - so far, everything worked out without major hinderance, so I would rather use an independent hosting solution, or continue to use the wiki to ensure that the barrier to entry/contributing isn't raised, e.g. by going through merge requests etc. Major contributions to the script like those from bigstones or Red Leader were simply &amp;quot;dropped&amp;quot; here directly, so this seems to have worked out really well.--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 11:26, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:: I've checked the [https://greasyfork.org/it/help/external-scripts GreasyFork external script policy]: as long as all the files are hosted on/uploaded to GreasyFork, it's not a problem. (Also, sorry about the typo, I wrote &amp;lt;tt&amp;gt;@include&amp;lt;/tt&amp;gt; instead of &amp;lt;tt&amp;gt;@require&amp;lt;/tt&amp;gt; by mistake). I guess I can proceed with the upload now? -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 12:22, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
: sure, why not - it's in the public domain after all - feel free to make any changes to the script to have it auto-update. We can review everything once we have gathered a little more experience with this kind of scheme. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 12:27, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:: {{done}} - I'm updating the installation instructions in the main page. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 13:52, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
::: Script at: https://greasyfork.org/en/scripts/19331-instant-cquotes &lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 14:18, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:::: Regarding updates, bumping the version number is fine - I'll take the script at the wiki revision where the version is bumped and upload it. (Note that I will not perform any prior testing, so be extra careful - maybe I should add this in the note above the script?). -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 18:08, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:: sounds good, I will be sure to stop updating the version number without prior testing, we could also add some tests to the code to spot the more obvious mistakes - in fact, there is already an OpenLink helper that could be used to download a few postings and try to extract the corresponding fields, so that we would only bump the version number if that succeeds. BTW: Thanks for handling the hosting part, much appreciated ! --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 18:25, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Issues ==&lt;br /&gt;
=== too greedy non-greedy regexes ===&lt;br /&gt;
The problem described in the previous section regarding regexes that eat up half messages seems to be related to my  [http://blog.liip.ch/archive/2009/07/24/the-greedyness-of-non-greedy-regular-expressions.html misunderstanding of the non-greediness]. So, I managed to fix it for this one case, but this means that using .*? to match everything until you meet the following character (as I currently do pretty much everywhere) is dangerous and prone to failure. Any occurrence of that should be changed as I did in [http://wiki.flightgear.org/index.php?title=FlightGear_wiki:Instant-Cquotes&amp;amp;oldid=72839 this edit] and that's clearly cumbersome, not to say that it can still be incorrect: say I have&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;a someprop=&amp;quot;href&amp;quot; href=&amp;quot;http://www.link.org&amp;quot; ... &amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
If I want to mach anything between a and href, I use &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;[^(?:href)]*&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;, but that would match only up to the text inside someprop, so I'd have to check that it's not inside doublequotes... Well, I guess this is getting too complicated for handling it [http://blog.codinghorror.com/parsing-html-the-cthulhu-way/ the Chtulu way].&lt;br /&gt;
&lt;br /&gt;
So my approach would be: fix this whenever the problem comes up, but don't overdo because we're already moving in dangerous ground. Or, rewrite it all using ''only'' xpaths *sobs*.&lt;br /&gt;
--[[User:Bigstones|Bigstones]] ([[User talk:Bigstones|talk]]) 16:49, 17 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
=== regex vectors ===&lt;br /&gt;
&lt;br /&gt;
When testing things I realized that you are right: there are some scenarios where the regex may fail depending on how &amp;quot;complete&amp;quot; the selection is, because we obviously have hard-coded assumptions here. I'll see if it's feasible to also support vectors for regexes to extract the corresponding fields and try each regex in order to get a certain field, or if that doesn't make any sense... But quoting with/without author (anonymous quote) would be a valid test case here.--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 16:46, 16 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
: Probably going to look into this sooner or later because this could be a simple solution to also support PM quoting - without having to parse the actual URL, we'd just try different regexes in order and use the one that succeeds. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 16:46, 16 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
=== Syntaxhighlighting ===&lt;br /&gt;
Need to investigate what needs to be updated to support quoting code sections, as per [http://forum.flightgear.org/viewtopic.php?f=66&amp;amp;t=21855&amp;amp;p=212585#p212581] --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 22:33, 14 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
=== Postings that break our script for some reason ===&lt;br /&gt;
* http://forum.flightgear.org/viewtopic.php?f=19&amp;amp;t=23365&lt;br /&gt;
&lt;br /&gt;
== Misc notes ==&lt;br /&gt;
&lt;br /&gt;
=== Detecting failed XPaths === &lt;br /&gt;
you've got a point, we should probably check if xpath/regexes succeed or fail, and show a warning so that we know that the scripts needs to be updated because some xpath/regex may have changed. &lt;br /&gt;
&lt;br /&gt;
=== Paragraphs / br (trailing slash) ===&lt;br /&gt;
There are some minor issues now, i.e. newline2br will no longer contain the trailing forward slash, so there's probably some JavaScript/regex oddity involved here, maybe slashes just need to be escaped. Will be testing the code with a few different forum postings and check the resulting cquote&lt;br /&gt;
: {{done}}. That's because newline2br wasn't used at all in html mode. I added addNewlines which puts newlines after br's and list related tags, if there are more newlines to be added that should be the place.&lt;br /&gt;
: --[[User:Bigstones|Bigstones]] ([[User talk:Bigstones|talk]]) 14:03, 17 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
=== support/ignore highlighted keywords/smilies ===&lt;br /&gt;
see [[Understanding Forward Compatibility]] for examples&lt;br /&gt;
: {{done}} --[[User:Bigstones|Bigstones]] ([[User talk:Bigstones|talk]]) 15:13, 17 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Beyond just cquotes (newsletter/changelog) ==&lt;br /&gt;
&lt;br /&gt;
Gijs has recently revamped the newsletter template rather significantly, see: [[FlightGear_Newsletter_June_2014]], and [[User_talk:Gijs#06.2F2014_newsletter:_too_much_of_a_]] - basically, we could extend the script to support another output FORMAT to directly create markup for the newsletter/changelog. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 20:40, 30 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
== more styles/output formats ==&lt;br /&gt;
&lt;br /&gt;
looking at some of the cleanup done by Red Leader recently, we could also directly support other styles/output formats to directly provide a format that looks well enough without requiring tons of manual editing. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 11:11, 13 February 2015 (EST)&lt;br /&gt;
&lt;br /&gt;
== token matching for keywords/variables ==&lt;br /&gt;
&lt;br /&gt;
seems like it might make sense to match common keywords/acronyms and variables, such as e.g.:&lt;br /&gt;
* FG_ROOT =&amp;gt; [[$FG_ROOT]]&lt;br /&gt;
* FG_HOME =&amp;gt;  [[$FG_HOME]]&lt;br /&gt;
* FG_SRC =&amp;gt; [[$FG_SRC]]&lt;br /&gt;
&lt;br /&gt;
file names with a known prefix like $FG_ROOT could even be pattern-matched using git link: $FG_ROOT/Nasal/canvas/MapStructure.nas would become [[$FG_ROOT]]{{Git link|gitorious|fg/fgdata|master|Nasal/canvas/MapStructure.nass|text=/Nasal/canvas/MapStructure.nas}}&lt;br /&gt;
&lt;br /&gt;
Equally, we could match common property paths to use code tags, e.g.: /sim/rendering would become &amp;lt;code&amp;gt;/sim/rendering&amp;lt;/code&amp;gt;&lt;br /&gt;
Ultimately, it might be a good idea to get in touch with Johan_G, Gijs and Red Leader to see what kind of format they'd prefer, especially because this could then be directly used for creating newsletter contents. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 11:19, 13 February 2015 (EST)&lt;br /&gt;
&lt;br /&gt;
== matching repository references using git link template ==&lt;br /&gt;
&lt;br /&gt;
Most of us commonly refer to repository files using either the $FG_* references, or relative paths in the form of &amp;lt;code&amp;gt;src/Main/fg_init.cxx:line number&amp;lt;/code&amp;gt;, we could automatically convert such references using the git/repo link template, e.g.: &lt;br /&gt;
&lt;br /&gt;
{{FGCquote&lt;br /&gt;
  |Further investigation found that the launcher *is* trying to add this directory to fg-aircraft (src/GUI/QtLauncher.cxx:772), but that this doesn't work because this option is processed before the launcher is run (intentionally, to allow the launcher to find aircraft in fg-aircraft: '''src/Main/main.cxx:448''').&lt;br /&gt;
  |{{cite web |url=http://sourceforge.net/p/flightgear/mailman/message/33686356/&lt;br /&gt;
     |title=&amp;lt;nowiki&amp;gt;Re: [Flightgear-devel] Launcher issues on Linux&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
     |author=&amp;lt;nowiki&amp;gt;Rebecca N. Palmer&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
     |date=&amp;lt;nowiki&amp;gt;2015-04-01&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
   }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 12:48, 1 April 2015 (EDT)&lt;br /&gt;
&lt;br /&gt;
== chrome specific port ==&lt;br /&gt;
&lt;br /&gt;
Hi Red Leader, when/if you do come up with a chrome specific version of the script, I would suggest to refactor existing APIs accordingly, so that we can come up with a common library of general purpose/utility helpers, so that both scripts can co-exist and use a common/shared file (think all the extraction/transformation logic), by referencing an external .js/JavaScript file that will be maintained/updated and hosted separately. I think this could be accomplished easily using jsfiddle. So basically, I am suggesting to come up with a shared back-end for both versions of the script. Given the complexity we're reaching meanwhile, as well as the number of edits and contributors, it may also make sense to consider using github for this at some point. One of the main advantages being that we could easily distribute updates automatically to all people who've installed the script, without them having to do anything manually.--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 08:38, 23 June 2015 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Development resources ==&lt;br /&gt;
&lt;br /&gt;
* https://www.youtube.com/watch?v=xpXNDT0SxM0&lt;br /&gt;
* http://wiki.greasespot.net/GM_getResourceText&lt;br /&gt;
* http://stackoverflow.com/questions/14594346/create-a-config-or-options-page-for-a-greasemonkey-script&lt;br /&gt;
&lt;br /&gt;
== Future focus/development and priorities (De-quoting) ==&lt;br /&gt;
&lt;br /&gt;
Given that most people involved in maintaining the wiki don't seem to particularly appreciate the nature of articles consisting mainly of quotes, and that we don't seem to have any other good way to populate new articles quickly, I was thinking of changing the focus of the script to dynamically create articles using quotes (with proper refs), that would be merely copy-edited, i.e. using the process we are currently using to &amp;quot;de-quote&amp;quot; such articles by 1) categorizing related quotes, 2) coming up with headers/sub-headers, 3) re-writing/merging certain quotes, 4) attributing them - linking back to the quotes archives.&lt;br /&gt;
Should we decide to pursue this, the script would be turned into a &amp;quot;wizard&amp;quot; where we can topics and sub-topics (wiki headings) and then add arbitrary text using the existing approach, but without using cquotes - i.e. the focus would be on extracting relevant contents, distilling them down and adding plenty of refs, including a references section at the bottom. Some tokens/words could be changed dynamically, but some kind of proof-reading/copy-editing would still need to be done afterwards, because people tend to use first person speech in their announcements/postings, which we would need to convert to 3rd person semi-automagically. Thoughts/ideas ?--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 07:11, 15 November 2015 (EST)&lt;br /&gt;
&lt;br /&gt;
== changing and automating regex/xpath handling ==&lt;br /&gt;
{{See also|#Genetic_Expression_solver}}&lt;br /&gt;
&lt;br /&gt;
We have currently hard-coded handling of different websites, regexes and xpath expressions so that things are a  bit fragile at the moment, and once a website changes its style/template, our script would break immediately. However, we could change the way the script works by using a very simple NN (neural network) to come up with matching regex/xpath expressions automatically. The way this could work would be &amp;quot;supervised&amp;quot; training, where we would replace/adapt our existing CONFIG hash with a vector of URLs and contents to be extracted (date, time, title, posting). This kind of data would suffice entirely for a neural network to self-train itself and &amp;quot;learn&amp;quot; how to come up with regex/xpath expressions to extract the relevant contents, including not only hard-coded websites like sourceforge, but even completely different websites (think gmane) - because the &amp;quot;learning&amp;quot; routine would self-adapt by looking at how to get its contents, and never contain any hard-coded regex/xpath expressions anymore. The CONFIG hash would end up being a vector with &amp;quot;training data&amp;quot; for different websites to be supported. And whenever an expression fails, it could re-train itself accordingly.--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 13:33, 15 November 2015 (EST)&lt;br /&gt;
&lt;br /&gt;
== nested quotes and AJAX for thread titles ==&lt;br /&gt;
&lt;br /&gt;
{{FGCquote&lt;br /&gt;
|1= http://sourceforge.net/p/flightgear/mailman/message/33451055/&lt;br /&gt;
{{cquote|As we move forward with FlightGear development and future versions, we will be expanding the &amp;quot;in app&amp;quot; aircraft center. This dialog inside flightgear lets you select, download, and switch to any of the aircraft in the library.|Curt}}&lt;br /&gt;
|2= {{cite web&lt;br /&gt;
  | url    = http://forum.flightgear.org/viewtopic.php?p=259879#p259879&lt;br /&gt;
  | title  = &amp;lt;nowiki&amp;gt;Re: New Canvas GUI&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  | author = &amp;lt;nowiki&amp;gt;Hooray&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  | date   = Oct 7th, 2015&lt;br /&gt;
  }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== AJAX mode/testing ==&lt;br /&gt;
&lt;br /&gt;
We should probably add a dialog to store credentials that we can use for accessing the wiki, which would need to be shown after installing the script, i.e. first-time use&lt;br /&gt;
&lt;br /&gt;
* http://stackoverflow.com/questions/14594346/create-a-config-or-options-page-for-a-greasemonkey-script&lt;br /&gt;
* http://commons.oreilly.com/wiki/index.php/Greasemonkey_Hacks/Getting_Started#During_Installation&lt;br /&gt;
* https://www.safaribooksonline.com/library/view/greasemonkey-hacks/0596101651/ch01s06.html&lt;br /&gt;
&lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 12:59, 20 November 2015 (EST)&lt;br /&gt;
&lt;br /&gt;
== libraries ==&lt;br /&gt;
&lt;br /&gt;
Referring to the [[#Hosting]] section, and my comment on wanting to use additional libs (like jQuery), I am primarily thinking about using a wizard-framework (e.g. jQuery steps) and a framework for creating wikimedia editor plugins (actions):&lt;br /&gt;
&lt;br /&gt;
* http://mstratman.github.io/jQuery-Smart-Wizard/&lt;br /&gt;
* http://www.jquery-steps.com/&lt;br /&gt;
* http://www.jqueryrain.com/demo/jquery-step-form-wizard/&lt;br /&gt;
* https://www.mediawiki.org/wiki/Extension:WikiEditor&lt;br /&gt;
&lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 12:07, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== About dequoting the script's article ==&lt;br /&gt;
&lt;br /&gt;
Thanks for doing this, but I am frankly not sure if it's worth the effort - there are much more popular/important articles using tons of quotes than this one, and given the reputation of the script, having quotes in this article may actually be a useful thing to make the case for having quotes in the first place - thus, I would frankly not spend much time going through this particular article - in fact, I'd be very surprised if the greasyfork download stats showed more than 3-5 people actually downloading, and using, the script - so this is really just a niche tool, and we probably better spend our time doing other things, and reviewing other wiki articles, than the script's article - at the very least, I would suggest to retain the references to the original discussions revolving these quotes (just my 2c). --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 19:00, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
: {{done}} I've added back the quotes as references. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 02:53, 3 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Script configuration (persistence) ==&lt;br /&gt;
&lt;br /&gt;
* https://wiki.greasespot.net/GM_config&lt;br /&gt;
* https://github.com/sizzlemctwizzle/GM_config/wiki&lt;br /&gt;
* https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API&lt;br /&gt;
&lt;br /&gt;
== Work in progress ==&lt;br /&gt;
&lt;br /&gt;
We have now several more or less related development efforts going on, and the code is also growing because of that - so it seems to make sense to summarize what's been going on recently. In general, all changes were made in response to the collection of feature requests and ideas we have accumulated over time  - specifically, that means that the following roadmap is in the process of being implemented:&lt;br /&gt;
&lt;br /&gt;
* establish unit testing, and add a few self-tests, so that the script can be more easily tested, updated/reviewed in the future&lt;br /&gt;
* rework the script to more easily support other sources (think gmane)&lt;br /&gt;
* make it much easier to update modified xpath/regex expressions (i.e. provide a UI for that)&lt;br /&gt;
* support persistence for script-specific settings&lt;br /&gt;
* make it easier for people to port/maintain the script by encapsulating platform specifics&lt;br /&gt;
* support asynchronous fetching of postings (AJAX), e.g. to fetch posting titles, attachments etc&lt;br /&gt;
* prepare the groundwork for supporting template-based output formats (think newsletter, changelog, articles)&lt;br /&gt;
* review what's necessary to allow the script to update fgcquote-based quotes automagically&lt;br /&gt;
&lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 16:47, 4 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== External genetic/neural network libraries ==&lt;br /&gt;
While uploading the latest version of the script, I noticed that the Genetic and Synaptic libraries are hosted on sites not on [https://greasyfork.org/en/help/external-scripts the approved GreasyFork list]. Shall I ask them to host them? -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 13:28, 11 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
: Thanks for pointing that out, I missed that completely, because everything is working correctly here - but obviously, I rarely get to actually download/install the latest version via greasyfork. Those libs should be safe to be added to the list, i.e. they're fairly established/popular, lest I'd not be using them. For now, this is just an experiment anyway. The idea is to update the xpath/regex code to evolve if/when the underlying website (theme) changes. But if there is a problem, we could use other libs - the code is just used for testing ATM. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 13:41, 11 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
* https://github.com/subprotocol/genetic-js&lt;br /&gt;
* https://github.com/cazala/synaptic&lt;br /&gt;
&lt;br /&gt;
:: {{ongoing}} I have submitted the libraries to the JSDelivr CDN; once they are up, I'll change the source URLs in the script and update it on GreasyFork as well. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 18:32, 17 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
::: Hi Elgaton, thank you for taking care of this, it's very much appreciated ! --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 18:55, 17 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:::: You're welcome! My merge requests for the CDN were approved (this took a bit longer than expected because I had made a small mistake - I forgot to include a file required by the Genetic.js library). The libraries should be up in a day or two, at which point I'll update the URLs in the script and submit the new version to GreasyFork. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 02:59, 20 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
::::: {{done}} Everything should be fine now. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 09:16, 20 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:: Thank you for all the help with this, and also for updating the greasyfork info/screenshots ! --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 07:16, 21 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Genetic Expression solver ==&lt;br /&gt;
[[File:Instant-cquotes-genetic-regex-solving.png|thumb|Screenshot showing the instant cquotes script with integrated regex solving support using genetic algorithms.]]&lt;br /&gt;
&lt;br /&gt;
The genetic-js framework has been integrated, it is intended to help solve xpath/regex expressions procedurally using genetic algorithms/programming. &lt;br /&gt;
&lt;br /&gt;
The idea is to provide a set of desired outputs (needles), available input data (haystack), and use existing (possibly outdated) regex/xpath expressions to seed a pool with potential solutions for retrieving the desired output. For now, this is just proof-of-concept, i.e. just an experiment.&lt;br /&gt;
&lt;br /&gt;
For example, let's consider the typical format of a from header for any sourceforge posting:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var regexTests = [&lt;br /&gt;
  {haystack: &amp;quot;From: John Doe &amp;lt;John@do...&amp;gt; - 2020-07-02 17:36:03&amp;quot;, needle: &amp;quot;John Doe&amp;quot;}, &lt;br /&gt;
  {haystack: &amp;quot;From: Marc Twain &amp;lt;Marc@ta...&amp;gt; - 2010-01-03 07:36:03&amp;quot;, needle: &amp;quot;Marc Twain&amp;quot;},&lt;br /&gt;
  {haystack: &amp;quot;From: George W. Bush &amp;lt;GWB@wh...&amp;gt; - 2055-11-11 17:33:13&amp;quot;, needle: &amp;quot;George W. Bush&amp;quot;}&lt;br /&gt;
];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The basic idea is to run a fitness function and score regex expressions based on not throwing an exception (which makes them valid), and by checking if the desired tokens are part of the output string, and evolve (mutate/cross-over) the &amp;quot;fittest&amp;quot; expressions - i.e. those that satisfy at least /some/ of the heuristics.&lt;br /&gt;
&lt;br /&gt;
Some of the metrics that can be used by the fitness function to determine if an expression is &amp;quot;fit&amp;quot;, are:&lt;br /&gt;
* valid expression&lt;br /&gt;
* relative offset/excess bytes in matches string&lt;br /&gt;
* number of examples it can successfully extract&lt;br /&gt;
* length of the expression&lt;br /&gt;
* runtime of the expression&lt;br /&gt;
&lt;br /&gt;
The search space, and runtime, can be significantly reduced by looking at similarities between all examples and coming up with a subset string that contains all identical components (e.g. the &amp;lt;code&amp;gt;From:&amp;lt;/code&amp;gt; part in the author regex) and use that for seeding the initial generations.&lt;br /&gt;
&lt;br /&gt;
Ultimately, this would allow the script to self-update its regex/xpath expressions if/when the underlying website (themes) change, but it would also allow to add support for new websites, without ever manually adding the required xpath/regex expressions, i.e. all that is needed is a sufficiently large number of example datasets to obtain the author, date and title information, and a URL for the script to download the HTML markup of the posting in question:&lt;br /&gt;
&lt;br /&gt;
{{Note|The date field won't work as is, because it's actually post-processed using a transformation function, so we'd need to undo the transformation or use the actual date string instead}}&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt; // vector with tests to be executed for sanity checks (unit testing)&lt;br /&gt;
    tests: [&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://sourceforge.net/p/flightgear/mailman/message/35059454/',&lt;br /&gt;
        author: 'Erik Hofman',&lt;br /&gt;
        date: 'May 3rd, 2016', // NOTE: using the transformed date here &lt;br /&gt;
        title: 'Re: [Flightgear-devel] Auto altimeter setting at startup (?)'&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://sourceforge.net/p/flightgear/mailman/message/35059961/',&lt;br /&gt;
        author: 'Ludovic Brenta',&lt;br /&gt;
        date: 'May 3rd, 2016',&lt;br /&gt;
        title: 'Re: [Flightgear-devel] dual-control-tools and the limit on packet size'&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://sourceforge.net/p/flightgear/mailman/message/20014126/',&lt;br /&gt;
        author: 'Tim Moore',&lt;br /&gt;
        date: 'Aug 4th, 2008',&lt;br /&gt;
        title: 'Re: [Flightgear-devel] Cockpit displays (rendering, modelling)'&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://sourceforge.net/p/flightgear/mailman/message/23518343/',&lt;br /&gt;
        author: 'Tim Moore',&lt;br /&gt;
        date: 'Sep 10th, 2009',&lt;br /&gt;
        title: '[Flightgear-devel] Atmosphere patch from John Denker'&lt;br /&gt;
      } // add other tests below&lt;br /&gt;
&lt;br /&gt;
    ], // end of vector with self-tests&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note how this no longer contains any hard-coded xpath/regex expressions - instead, the script can refer to the website specific defaults, and try those first, and if they fail, use those to seed new generations and evolve them procedurally until all tests succeed.&lt;br /&gt;
&lt;br /&gt;
For a regex to be valid, it must work for all tests/examples.&lt;br /&gt;
&lt;br /&gt;
Once the regex solver is working correctly, the code can be further generalized to also evolve xpath expressions (NOTE: the DOMParser API is /not/ available to webworkers ...) and chain those two components together.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* http://regex.inginf.units.it/how.html&lt;br /&gt;
* http://www.i-programmer.info/programming/perl/9503-automatically-generating-regular-expressions-with-genetic-programming.html&lt;br /&gt;
* http://jkff.info/articles/ire/&lt;br /&gt;
* http://www.networkworld.com/article/2955126/software/genetic-programming-meets-regular-expressions.html&lt;br /&gt;
* https://handcraftsman.wordpress.com/2012/04/11/evolving-a-regular-expression-with-go/&lt;br /&gt;
* http://stackoverflow.com/questions/4880402/how-to-auto-generate-regex-from-given-list-of-strings&lt;br /&gt;
* http://regex.inginf.units.it/&lt;br /&gt;
* http://www.genetic-programming.org/hc2014/Bartoli-Paper.pdf&lt;br /&gt;
&lt;br /&gt;
== Hierarchical Clustering  ==&lt;br /&gt;
&lt;br /&gt;
Been tinkering with a JavaScript module to automatically cluster postings based on certain keywords in the topic/title or posting (e.g. Nasal, Canvas, 2D API, rendering): https://harthur.github.io/clusterfck/&lt;br /&gt;
&lt;br /&gt;
Note that in conjunction with processing article sections and/or whole articles, this could help automatically come up with matching postings for articles and vice versa.&lt;br /&gt;
&lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 18:11, 19 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Upcoming dependencies ==&lt;br /&gt;
&lt;br /&gt;
The script is now using [http://markitup.jaysalvat.com/home/ markitup] to create the template editor. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 10:18, 21 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
: I've [https://github.com/jsdelivr/jsdelivr/pull/11757 submitted a pull request] for the library to be distributed by jsDelivr. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 16:08, 21 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Code beautifier ? ==&lt;br /&gt;
&lt;br /&gt;
I still had, and have, pending changes that would need to go through the same beautifier you're using, or they'd be lost -  so for now, I have just overwritten your  beautified code, hope that you didn't do this manually (there really are tons of automated and configurable beautifiers out there). --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 15:59, 21 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
: Of course not - let me know when you've incorporated all changes so that I can beautify the script again. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 16:31, 21 May 2016 (EDT)&lt;/div&gt;</summary>
		<author><name>Elgaton</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Talk:FlightGear_Git:_splitting_fgdata&amp;diff=98501</id>
		<title>Talk:FlightGear Git: splitting fgdata</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Talk:FlightGear_Git:_splitting_fgdata&amp;diff=98501"/>
		<updated>2016-05-21T20:13:40Z</updated>

		<summary type="html">&lt;p&gt;Elgaton: Elgaton moved page Talk:FlightGear Git: splitting fgdata to Talk:FlightGear Git: splitting FGData: Capitalization fix&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Talk:FlightGear Git: splitting FGData]]&lt;/div&gt;</summary>
		<author><name>Elgaton</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Talk:FlightGear_Git:_splitting_FGData&amp;diff=98500</id>
		<title>Talk:FlightGear Git: splitting FGData</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Talk:FlightGear_Git:_splitting_FGData&amp;diff=98500"/>
		<updated>2016-05-21T20:13:40Z</updated>

		<summary type="html">&lt;p&gt;Elgaton: Elgaton moved page Talk:FlightGear Git: splitting fgdata to Talk:FlightGear Git: splitting FGData: Capitalization fix&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Moved some text that was clearly part of a plan that is currently not very likely to be continued into the discussion page:&lt;br /&gt;
&lt;br /&gt;
== Starting new aircraft ==&lt;br /&gt;
New aircraft should not be commited to fgdata. A separate repository should be created instead. Contact a FlightGear Aircraft admin to get your repository included in the FlightGear Aircraft project. You, as author, will get commit rights for that repository.&lt;br /&gt;
&lt;br /&gt;
The current fgdata developers will have access to every single aircraft repository. In order to maintain aircraft that no longer have an active author, fix global bugs etc. Other users can create merge requests to get their fixes/improvements commited.&lt;br /&gt;
&lt;br /&gt;
== Step 1: Split aircraft into separate repositories (DONE) ==&lt;br /&gt;
Aircraft are split into &amp;quot;private&amp;quot; repositories, under the [https://gitorious.org/flightgear-aircraft FlightGear Aircraft project]. Repositories for all aircraft in current fgdata have been created as of 17 October. Repository names equal directory-names (with the exceptions of dots (.) and capitals (ABC), as those are not supported by Gitorious.&lt;br /&gt;
&lt;br /&gt;
There are two workflows that both do the trick:&lt;br /&gt;
&lt;br /&gt;
=== Method 1 ===&lt;br /&gt;
'''Note:''' the split branch (&amp;lt;tt&amp;gt;737-300-split&amp;lt;/tt&amp;gt; in this example) must NOT exist beforehand.&lt;br /&gt;
&lt;br /&gt;
 cd $FG_ROOT &lt;br /&gt;
 git subtree split -P Aircraft/737-300 -b 737-300-split&lt;br /&gt;
 mkdir -p ../split-aircraft/737-300&lt;br /&gt;
 cd ../split-aircraft/737-300&lt;br /&gt;
 git init&lt;br /&gt;
 git fetch $FG_ROOT 737-300-split&lt;br /&gt;
 git checkout -b master FETCH_HEAD&lt;br /&gt;
 git push git@gitorious.org:flightgear-aircraft/737-300.git master&lt;br /&gt;
&lt;br /&gt;
=== Method 2 ===&lt;br /&gt;
(need to check this one)&lt;br /&gt;
 cd fgdata&lt;br /&gt;
 git clone --no-hardlinks /fgdata /737-300&lt;br /&gt;
 git filter-branch --subdirectory-filter Aircraft/737-300 HEAD -- --all&lt;br /&gt;
 git reset --hard&lt;br /&gt;
 rm -rf .git/refs/original/&lt;br /&gt;
 git reflog expire --expire=now --all&lt;br /&gt;
 git gc --aggressive --prune=now&lt;br /&gt;
&lt;br /&gt;
Then all aircraft should be pushed to their new repositories. A script will take care of that.&lt;br /&gt;
&lt;br /&gt;
== Step 2: Remove all aircraft from fgdata ==&lt;br /&gt;
A new fgdata repository without any aircraft is created, pushed to gitorious and tested.&lt;br /&gt;
&lt;br /&gt;
== Step 3: Write/update manuals ==&lt;br /&gt;
Since the aircraft development flow will be different, we should teach our developers how to use the new system.&lt;br /&gt;
&lt;br /&gt;
'''To be written:'''&lt;br /&gt;
* [[FlightGear Git: aircraft authors]]&lt;br /&gt;
&lt;br /&gt;
'''To be updated:'''&lt;br /&gt;
* [[FlightGear and Git]]&lt;br /&gt;
* [[FlightGear Git on Mac OS X]]&lt;br /&gt;
* [[FlightGear Git on Windows]]&lt;br /&gt;
&lt;br /&gt;
== Step 4: Switch fgdata ==&lt;br /&gt;
Once tests show that the new repository is working fine and no data has been lost, the repositories will be switched.&lt;br /&gt;
The exisiting repository is renamed, and the new repository takes its place and access to the new repository is setup.&lt;br /&gt;
The historic fgdata is kept but stays frozen, at least until we're sure everything is safe. It may also be a good idea to keep the existing repo, since it contains release branches - which are not part of the new repository and would be lost otherwise.&lt;br /&gt;
&lt;br /&gt;
== Step 5: Inform the crowd ==&lt;br /&gt;
Post an announcement at the mailing list, forum, Facebook (?) and in the [[FlightGear Newsletter October 2011|upcoming newsletter edition]]. Link to the respective wiki articles (see [[#Step 3: Write/update manuals|Step 3]]) that contain details on how to work with the new system.&lt;br /&gt;
&lt;br /&gt;
== Questions ==&lt;br /&gt;
* What to do with Aircraft/UIUC should it be placed like &amp;quot;one&amp;quot; aircraft in a aircraft-repository? Or each individual?&lt;br /&gt;
** An flightgear-aircraft/UIUC repo has been created, we can delete it if needed later on.&lt;br /&gt;
* Gitorious does not support dots in repository names.&lt;br /&gt;
** For now we just skipped dots, so Supermarine-S.6B has a repo called &amp;lt;tt&amp;gt;supermarine-s6b&amp;lt;/tt&amp;gt; (note that Gitorious also does not distinct capitals. This does not seem to be a problem though, since git clone uses the original directory name).&lt;br /&gt;
* What rights should aircraft authors get?&lt;br /&gt;
** Commit/review might be best. If they are granted admin rights, they can delete the repo and remove the fgdata-developers as collaborators. When they do the later, there's no way we can regain control over the repo. We won't even be able to delete it from the FlightGear Aircraft project.&lt;br /&gt;
* Should we support multiple licenses under the FlightGear Aircraft project?&lt;br /&gt;
** Possible, but then the Aircraft Downloadpage would maybe need an update. Better create one Place for GNU-GPL and one for other licences. &lt;br /&gt;
*How long should we test? FGData is increasing again as new aircraft are continuously added again. &lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[User:Durk|Durk]] 17:48, 16 November 2011 (EST)&lt;br /&gt;
&lt;br /&gt;
== Keeping the page though it is soon outdated ==&lt;br /&gt;
&lt;br /&gt;
As the split has begun and the aircraft have copied the aircraft to SourceForge (see [[FlightGear Newsletter September 2014#Aircraft moved to SVN]]), this page could soon be considered obsolete.&lt;br /&gt;
&lt;br /&gt;
As the split has been discussed for some time and is a bit of a watershed I feel that it could be a good idea to maybe add links to relevant developer mailing list treads and forum topics and keep this page for historical reference.&lt;br /&gt;
&lt;br /&gt;
I have added a messagebox template, {{tl|historical}}, for this and similar purposes (here filled in for this page):&lt;br /&gt;
{{historical&lt;br /&gt;
| reason = This split had been discussed for years and finally begun in September 2014. See [[FlightGear Newsletter September 2014#Aircraft moved to SVN]].&lt;br /&gt;
| talk   = Talk:FlightGear Git: splitting fgdata#Keeping the page though it is soon outdated&lt;br /&gt;
| date   = 27 December 2014&lt;br /&gt;
| nocat  = 1  &amp;lt;!-- As this is an example --&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
—[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 11:01, 27 December 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
: I am putting this awesome messagebox at the top of the article to avoid confusion! [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 16:40, 22 September 2015 (EDT)&lt;/div&gt;</summary>
		<author><name>Elgaton</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=FlightGear_Git:_splitting_fgdata&amp;diff=98499</id>
		<title>FlightGear Git: splitting fgdata</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=FlightGear_Git:_splitting_fgdata&amp;diff=98499"/>
		<updated>2016-05-21T20:13:40Z</updated>

		<summary type="html">&lt;p&gt;Elgaton: Elgaton moved page FlightGear Git: splitting fgdata to FlightGear Git: splitting FGData: Capitalization fix&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[FlightGear Git: splitting FGData]]&lt;/div&gt;</summary>
		<author><name>Elgaton</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=FlightGear_Git:_splitting_FGData&amp;diff=98498</id>
		<title>FlightGear Git: splitting FGData</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=FlightGear_Git:_splitting_FGData&amp;diff=98498"/>
		<updated>2016-05-21T20:13:40Z</updated>

		<summary type="html">&lt;p&gt;Elgaton: Elgaton moved page FlightGear Git: splitting fgdata to FlightGear Git: splitting FGData: Capitalization fix&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{historical&lt;br /&gt;
| reason = This split had been discussed for many years and finally begun in September 2014. See [[FlightGear Newsletter September 2014#Aircraft moved to SVN]].  The new repositories after the split are called [[FGData]] and [[FGAddon]].&lt;br /&gt;
| talk   = Talk:FlightGear Git: splitting fgdata#Keeping the page though it is soon outdated&lt;br /&gt;
| date   = 27 December 2014&lt;br /&gt;
| nocat  = 1  &amp;lt;!-- As this is an example --&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Project Issues}}&lt;br /&gt;
After much discussion on the mailing list, it was decided to put the existing attempt to split FGdata on hold until further notice. The main reason for postponing the split was that, while it was considered a well intended initiative, the end result of the splitting process itself left the FlightGear fgdata project in a less than desirable state. For this reason, before another splitting attempt is to be undertaken, the pro's and con's of each step should be carefully evaluated. This article discusses some of our options and will formulate a plan of approach that can be presented to -and discussed in further depth- on the developers mailing list. Several reasons have been put forth to split fgdata:&lt;br /&gt;
&lt;br /&gt;
== News / Status (03/2015) == &lt;br /&gt;
{{FGCquote&lt;br /&gt;
  |I am going to commence reducing FGDATA this weekend. The reasons for that&amp;lt;br/&amp;gt;&lt;br /&gt;
action have been discussed here and on the forum in epic detail, so I won't&amp;lt;br/&amp;gt;&lt;br /&gt;
repeat them.&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
The result will be a new and much smaller git repository and it will only&amp;lt;br/&amp;gt;&lt;br /&gt;
have the c172p and the ufo remaining.&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
To avoid any unnecessary extra work, I will temporarily remove all&amp;lt;br/&amp;gt;&lt;br /&gt;
contributors with write access except 2 or three admins on Friday afternoon&amp;lt;br/&amp;gt;&lt;br /&gt;
(Central European Time Zone).&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  |{{cite web |url=http://sourceforge.net/p/flightgear/mailman/message/33546900/&lt;br /&gt;
     |title=&amp;lt;nowiki&amp;gt;[Flightgear-devel] FGData size reduction&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
     |author=&amp;lt;nowiki&amp;gt;Torsten Dreyer&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
     |date=&amp;lt;nowiki&amp;gt;2015-03-05&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
   }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{FGCquote&lt;br /&gt;
  |Next, I'll do a initial commit of the base package aircraft to fgaddon/svn.&amp;lt;br/&amp;gt;&lt;br /&gt;
Following that, I create a new git repo for a smaller git fgdata and push&amp;lt;br/&amp;gt;&lt;br /&gt;
it to sourceforge.&amp;lt;br/&amp;gt;&lt;br /&gt;
Finally, we re-add contributors with push permission.&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
If anything goes wrong, the original fgdata will remain intact and can&amp;lt;br/&amp;gt;&lt;br /&gt;
serve as a fallback.&lt;br /&gt;
  |{{cite web |url=http://sourceforge.net/p/flightgear/mailman/message/33546900/&lt;br /&gt;
     |title=&amp;lt;nowiki&amp;gt;[Flightgear-devel] FGData size reduction&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
     |author=&amp;lt;nowiki&amp;gt;Torsten Dreyer&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
     |date=&amp;lt;nowiki&amp;gt;2015-03-05&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
   }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{FGCquote&lt;br /&gt;
  |Following a fairly lengthy discussion, here is what  we now intending to do with FGData:&lt;br /&gt;
* create a new FGData Git repo, with aircraft stripped out, hosted by Gitorious&lt;br /&gt;
* Move the Models/ files in this repo under Scenery/ and make it as clear as possible that they should not be touched by anyone other than Martin&lt;br /&gt;
  |{{cite web |url=http://sourceforge.net/p/flightgear/mailman/message/33548331/&lt;br /&gt;
     |title=&amp;lt;nowiki&amp;gt;Re: [Flightgear-devel] FGData size reduction&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
     |author=&amp;lt;nowiki&amp;gt;James Turner&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
     |date=&amp;lt;nowiki&amp;gt;2015-03-05&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
   }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Reasons to split fgdata ==&lt;br /&gt;
=== Advantages ===&lt;br /&gt;
** Aircraft authors can get commit access to their own aircraft, without granting them global fgdata access.&lt;br /&gt;
** When pulling fgdata, one won't have to download several gigs of aircraft data. People will have to pull the base package, but any additional aircraft will be optional.&lt;br /&gt;
** It will be easier for aircraft authors to check the history of their aircraft.&lt;br /&gt;
** Commiting will go faster, because Git will no longer have to check those thousands of files to see whether they were edited. NOTE: Can't reproduce even on really old, slow (7.2k SATA) disks.&lt;br /&gt;
** fgdata size decreases from 5,6 GB to 1 GB (see statistics below).&lt;br /&gt;
&lt;br /&gt;
=== Disadvantages ===&lt;br /&gt;
It should also be noted, however, that a split is not without potential problems:&lt;br /&gt;
&lt;br /&gt;
** It will be harder to keep a local up to date copy of all aircraft. No more &amp;quot;git pull&amp;quot; to fetch all the latest updates.&lt;br /&gt;
*** Might be fixed by using Git submodules.&amp;lt;ref&amp;gt;[http://book.git-scm.com/5_submodules.html Git Community Book: Submoduldes]&amp;lt;/ref&amp;gt;&lt;br /&gt;
** How to deal with licences? Until now there was a COPYING file in fgdata. When aircraft are split in separate repositories, they'll likely need to include a license reference themselves.&lt;br /&gt;
** Need a concept for release management, maintaining version numbers, release branches, release tags et. al.&lt;br /&gt;
** Quite a few unmaintained aircraft got adopted after one of the developers accidentially tripped over them. Need a plan how this would be supposed to work with split aircraft repositories, otherwise the project would axe one of the substantial principles which contributed to its success.&lt;br /&gt;
*** One of the main reasons for running a community owned (aircraft or source) repository, and the reason why people have &amp;quot;donated&amp;quot; (aircraft or sources) to the common repository, is to guarantee that any contributed work lives on - for as long as the (FG) project itself exists. Private repositories, even hangars run by a small number of people, are likely to become unmaintained and even lost eventually, since people's interests and hobbies change over time. Few (FG) contributors are active for more than 5-10 years. Hence, a common and well maintained community repository is essential to every open source project.  &lt;br /&gt;
** Need an idea about how to subsitute the the previous &amp;quot;starter&amp;quot; package which was offered via HTTP for those who'd like to have the entire repository.&lt;br /&gt;
&lt;br /&gt;
One of the most prominent reasons brought forth in favor of splitting fgdata is related to the relatively large size of the initial clone of the git repository, the relatively slow download size of gitorious, and the observation that interrupted downloads cannot be resumed. Before discussing possible alternatives to this problem, a few observations should be made with respect to the actual size of the downloaded git package:&lt;br /&gt;
&lt;br /&gt;
=== Statistics ===&lt;br /&gt;
To obtain proper GIT repository size statistics, make sure to only check the size of the &amp;quot;.git&amp;quot; folder - which contains the history that belongs to the archive and needs to be downloaded. Once you check out a branch as a &amp;quot;working copy&amp;quot; locally, the total size of your actual file system folder increases (likely doubles), since the check-out creates a working ''copy'' of all files by ''extracting'' data from the ''compressed'' archive.&lt;br /&gt;
* Size of original fgdata GIT repository: 5.6GB&lt;br /&gt;
* Size of fgdata core GIT repository without aircraft: 1GB&lt;br /&gt;
* Total size of all aircraft repositories: 3.1GB&lt;br /&gt;
* Number of aircraft: 385&lt;br /&gt;
&lt;br /&gt;
It should be noted that interrupted downloads are a potential problem; however there are a number of viable workarounds for these:&lt;br /&gt;
* Download an initial clone using a more robust download system, such as a bittorrent&lt;br /&gt;
* Download a snapshot without full project history.&lt;br /&gt;
* Clone the repository from a faster mirror, such as the mapserver.&lt;br /&gt;
&lt;br /&gt;
It should further be noticed that git's merging and update algoritms are sufficiently efficient to deal with our ever increasing repository, so no immediate problems are to be expected in this area. Given these considerations, it appears that there are sufficient alternatives to circumvent the initial clone problem, and that the size of the git repository as such poses no immediate problem. That said, there are a number of additional reasons that make it desireable to split the fgdata repository in smaller, more manageable chunks.&lt;br /&gt;
&lt;br /&gt;
== Options ==&lt;br /&gt;
Splitting off the aircraft directory from the rest is a logical first step, and the main question is how to proceed with this. There are a number of possible options: &lt;br /&gt;
* Split off all aircraft and keep them all in a single, but separate repository. &lt;br /&gt;
* Move each aircraft to its own repository&lt;br /&gt;
* Organize aircraft by logical units. &lt;br /&gt;
Here are the advantages and disadvantages of each option:&lt;br /&gt;
&lt;br /&gt;
=== Single repository ===&lt;br /&gt;
* '''Advantages'''&lt;br /&gt;
** The current fgdata-developers team can access any single aircraft, for easy/quick fixes. For example when something is found to be wrong and copied among several aircraft (which happens due to copy&amp;amp;paste). Or when something about the sim itself changes and aircraft msut be adapted to run on an upcoming release.&lt;br /&gt;
** When an aircraft developers decides to leave, the aircraft can easily be taken over by other developers.&lt;br /&gt;
** It allows us to use [http://flightgear-bugs.googlecode.com the bug tracker] for aircraft. Most developers won't clone aircraft repos from all kind of places, just to help fixing bugs.&lt;br /&gt;
* '''Disadvantages'''&lt;br /&gt;
** Authors won't be able to choose their own license.&lt;br /&gt;
** The aircraft/ directory makes up the largest part of the current repository. A single aircraft repository would make contributing to the base package easier, but it won't have much effect on aircraft developers.&lt;br /&gt;
&lt;br /&gt;
=== Per-aircraft repository, single project ===&lt;br /&gt;
Each aircraft would get a repository under a &amp;quot;FGAircraft&amp;quot; project at Gitorious.&lt;br /&gt;
* '''Advantages'''&lt;br /&gt;
** The current fgdata-developers team can access any single aircraft, for easy/quick fixes. For example when something is found to be wrong and copied among several aircraft (which happens due to copy&amp;amp;paste). Or when something about the sim itself changes and aircraft msut be adapted to run on an upcoming release.&lt;br /&gt;
** When an aircraft developers decides to leave, the repo can easily be taken over by other developers. If the author set up his own repository, we'd have to create a new repository (and thus change all references/links).&lt;br /&gt;
** It allows us to use [http://flightgear-bugs.googlecode.com the bug tracker] for aircraft. Most developers won't clone aircraft repos from all kind of places, just to help fixing bugs.&lt;br /&gt;
** Authors can choose their own license.&lt;br /&gt;
*** The FlightGear Aircraft project can be set to &amp;quot;License: Other/Multiple&amp;quot;. This allows (in theory, we first need to agree on this) any aircraft author to add whatever license file to his/her aircraft and still put it under the project.&lt;br /&gt;
*** However, the use of a ''common'' license for all ''community aircraft'' has many advantages and has also contributed to the success of the FG project (new aircraft can be easily based on existing aircraft, can copy elements from other aircraft without triggering a complicated mixed license situation), and specifically the GPL has many advantages for the FG project (see [[Changing the FlightGear License]] for details why FG wants to stick to the GPL). Authors preferring an other license can of course already (and continue to) do so - except that their aircraft is not in the community repository.&lt;br /&gt;
&lt;br /&gt;
=== Per-aircraft project ===&lt;br /&gt;
* '''Advantages'''&lt;br /&gt;
** Each aircraft developer can get admin rights to his or her own project.&lt;br /&gt;
* '''Disadvantages'''&lt;br /&gt;
** It will become increasingly difficult to maintain abandoned aircraft, or conduct maintanance&lt;br /&gt;
** With over 500 individual repositories it will become increasingly difficult to keep track of new developments. &lt;br /&gt;
&lt;br /&gt;
=== Organizing aircraft by logical units ===&lt;br /&gt;
* '''Advantages'''&lt;br /&gt;
** Logical ordering units remain manageble both in terms of the number of them as well as their size&lt;br /&gt;
* '''Disadvantages'''&lt;br /&gt;
** It is difficult to come up with a good set of criteria to define the aircraft categories.&lt;br /&gt;
&lt;br /&gt;
== Considerations ==&lt;br /&gt;
Given these considerations, it can be concluded that it is desirable to separate the aircraft from the main repository. It should also be pointed out that seperating out the aircraft, and moving them all into a single repository is the sole action addressing the most urgent reason for the split, namely giving the opportunity to be more liberal in granting aircraft developers commit rights, without having to consider the integrity of the base package as such. It should furthermore be noticed that while it is technically possible to remove an entire subdirectory from a project without losing its history, it is undesirable to do so. Every split done in this manner would force every user to reclone the entire repository in question. Additionally, it is considerably more difficult to combine repositories again once they have been split. Therefore, we should be cautious in performing split operations. For this reason, the most feasible action appears to be to just separate the aircraft directory from fgdata and move this in it's entirety to a new subproject. There it can live until a new and agreed upon classification scheme for separate repositories has been developed. &lt;br /&gt;
&lt;br /&gt;
Finally, the following considerations should be taken into account. &lt;br /&gt;
* FlightGear's release distributions are steadily increasing in size. With the proposed fgdata split, we should consider removing all aircraft, except the default cessna 172p from the base package. All others can simply be downloaded from the website. Considering that the c172p is and integral part of FlightGear, it should remain the ONLY aircraft that remains in the base package, and wich is is not moved to the new fgaircraft repository.&lt;br /&gt;
* It should be emphasized that GIT is a distributed revision control system, and that our current use of git is insufficient.Aircraft developers should be encouraged to set up their own personal clone on gitorious, and we should encourage aircraft developers to post more merge requests.&lt;br /&gt;
* As more and more people gain commit rights, some rules and guidelines are in order. We currently have a largely unwritten code of conduct that has proven to work well. With new people entering the scene, it will become necessary to put them in writing however.&lt;br /&gt;
&lt;br /&gt;
== A new plan for splitting fgdata ==&lt;br /&gt;
&lt;br /&gt;
# Create a new git repository: fgaircraft. This repository will -for the time being- contain all current and new FlightGear aircraft except the default c172p.&lt;br /&gt;
# Provide images of the git repository, to alleviate the initial clone problem. Preferably, this should be done using bittorrent, or another interruptable download source, so that people with limited bandwidth, can monitor their data consumption more flexibly. &lt;br /&gt;
# After a few days of testing, remove all aircraft from the main fgdata repository.&lt;br /&gt;
# Formalize the status of the new aircraft repositories by formalizing our existing, but unwritten, code of conduct and granting new aircraft authors who agree to this code of conduct commit rights. &lt;br /&gt;
# Because the new system can allow us to grant a potentially large number of aircraft developers commit access, we deem it desireabe to formulate an explicit set of rules with regard to the contributor's rights and obligations. It should be noted that the following rules are not really new, but merely formalizations of our existing code of conduct. By explicitly formulating them, our main goal is to avoid misunderstanding, and to provide clear guidelines in the unlikely event of misuse of commit rights. &lt;br /&gt;
# Post these rule on a relatively prominent location on the main FlightGear.org website. &lt;br /&gt;
# Formulate and discuss plans for further separation into logical categories.&lt;br /&gt;
# Once a consensus has been reached further split operations can be conducted. &lt;br /&gt;
&lt;br /&gt;
The rules describing the rights and obligations of committers are as follows:&lt;br /&gt;
# Authors who obtain commit rights to fgaircraft retain the rights to handle their own work.&lt;br /&gt;
# The FlightGear fgaircraft administrators are allowed to update aircraft files, but only&lt;br /&gt;
## to enable the use of new FlightGear features (such as adding a necessary include file or set a few property switches),&lt;br /&gt;
## to fix small and obvious bugs (such as fixing a misspelled property or file name), or&lt;br /&gt;
## to apply changes necessary to keep aircraft compatible with an upcoming FlightGear release.&lt;br /&gt;
# The FlightGear fgaircraft repository maintainers reserve the right to revoke commit access of an individual committer. They can only exercise their right after consensus has been reached among the maintainers, and only in cases of&lt;br /&gt;
## misuse of commit rights by the offending developer, or&lt;br /&gt;
## prolonged inactivity of the committer (more than a year of inactivity)&lt;br /&gt;
# Aircraft that have not been maintained by the prime committer for a prolonged period of time are considered to have been abandoned and may be assigned to a different committer. The obvious exception to this rule is formed by aircraft that have a high level of completeness that are maintained by committers who are still very active in other areas of FlightGear's development. &lt;br /&gt;
# Commit rights will be given after the authors have shown a reasonable level of competence in both aircraft development and GIT usage. While the aircraft developer is still in the process of obtaining the required skills, he or she can seek a mentor who will handle any merge requests.&lt;br /&gt;
# If the aircraft developer is uncomfortable in working with GIT he or she can also opt to choose a &amp;quot;mentor&amp;quot; who will handle the merge requests for them.&lt;br /&gt;
# In addition to these rules, anybody contributing to the FlightGear project is encouraged to work with personal clones and submit merge requests.&lt;br /&gt;
&lt;br /&gt;
=== Comments on the new plan ===&lt;br /&gt;
&lt;br /&gt;
(HHS comments)&lt;br /&gt;
That sounds like the situation we already have - the only difference: the aircraft are just splitted from FGData, and the maintainer of an Aircraft-project can get the rights to commit without any magic.&lt;br /&gt;
But with that there are lot of rules with exceptions. From my daily real life job I do know, that many rules with exceptions may make things more complicated and provoke discussions and conflicts.&lt;br /&gt;
So my question is: How can we see that &amp;quot;a reasonable level of competence in both aircraft development and GIT usage&amp;quot; is there? Does he has to be checked? Which level of competence is needed for making an aircraft?&lt;br /&gt;
&lt;br /&gt;
(some answers from TorstenD)&lt;br /&gt;
I'd define &amp;quot;reasonable level of competence&amp;quot; for GIT as &amp;quot;be able be familiar with the basic everyday GIT workflow&amp;quot;. If [https://www.kernel.org/pub/software/scm/git/docs/everyday.html everyday git] is understandable, I'd say OK.&lt;br /&gt;
And for aircraft development: Be able to stay in your sandbox, don't mess with other's files, be able to reuse existing (common) files, create reasonable file sizes, accept naming conventions etc. Most important: nobody is perfect, but be able to fix what you broke ;-)&lt;br /&gt;
&lt;br /&gt;
--[[User:ThorstenB|ThorstenB]] 17:57, 11 December 2011 (EST): It's a huge improvement to split aircraft from the main fgdata repo. Any change to an aircraft will only affect a single aircraft. But changes to the rest of fgdata (the central Nasal, Shader, GUI directories etc) can have a massive impact: on all other aircraft, on the simulator core, or on the design/direction/structure of core parts. So, it's good to have these things separated. And I think we can allow a lot more people direct commit access once aircraft are separated - even if they all share a repo. I don't think we would see many (or any) cases of authors messing with other people's work.&lt;br /&gt;
And I think the rules are fine and simple enough - actually almost &amp;quot;common sense&amp;quot; when working in a collaborative environment. &lt;br /&gt;
&lt;br /&gt;
--[[User:Durk|Durk]] 05:02, 12 December 2011 (EST) I would also like to mention that we don't consider the initial split to be the final stage. Additional splits are possible, but we need to carefully evaluate how we should do that. Once we do have a decent plan we can continue with phase b) of the operation. I will add that to the plan later.&lt;br /&gt;
&lt;br /&gt;
--[[User:Durk|Durk]] 05:22, 12 December 2011 (EST) Oh, and before I forget: James Turner is working on providing the infrastructure for aircraft meta-data. Once this in place, we would be much more flexible in splitting, but I would be cautious to not step beyond the initial stage before James is finished with that. &lt;br /&gt;
&lt;br /&gt;
(hvengel comments) &lt;br /&gt;
Having well defined rules it a good thing.  Some (perhaps many) of the aircraft devs have little or no experience with normal software development work flows and they will need well defined rules to help them do the right thing.  Reading through the proposed rules I don't see too much room for things to be incorrectly used.  However because the level of experience with software work flows will be all over the place (IE. some aircraft devs are also experienced software developers/engineers and some have absolutely no experience with this type of thing) the rules should be a simple and as clear and complete as possible.  Nothing should be open to interpretation. &lt;br /&gt;
&lt;br /&gt;
I don't see the concern over determining GIT and/or aircraft development competence to be a significant issue.  I am sure that there are a significant number of aircraft devs who are currently using merge requests who would be given commit rights right from the get go.  Newer aircraft devs can work with a mentor with commit rights while they are learning GIT and aircraft development and the mentor can determine when they are ready for commit rights.  However I think having a documented process for this might be a good idea. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
(HHS comments)&lt;br /&gt;
It is good to see that the existing rules are finally formalized, so we get a clear guideline. &lt;br /&gt;
It is also good to see that people should be more encouraged to submit merge requests. But this also means that those with commit rights should be more encouraged to review those merge requests and commit them!&lt;br /&gt;
&lt;br /&gt;
--[[User:T3r|T3r]] 15:06, 11 December 2011 (EST): Absolutely - however: as most commiters are as lazy as I am, they do not regularly check for merge requests. Picking your most trustworthy commiter from the list and asking him to handle the requests for you is probably a good idea. Reminders by PM are always welcome.&lt;br /&gt;
&lt;br /&gt;
--[[User:Durk|Durk]] 05:02, 12 December 2011 (EST) Which is actually why we introduced the notion of a mentor. The primary purpose is that more one-to-one work relations between committers and contributers will be established. This will certainly benefit the overall workflow. &lt;br /&gt;
&lt;br /&gt;
—[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 17:32, 24 September 2012 (EDT) The UFO should probably have the same status as proposed for the C172, but I do not know weather it resides with the aircraft or already with the rest of FlightGear.&lt;br /&gt;
&lt;br /&gt;
== New Splitting Concept ==&lt;br /&gt;
see [[FGAddon]] for new concept&lt;br /&gt;
&lt;br /&gt;
{{Appendix}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Developer Plans]]&lt;/div&gt;</summary>
		<author><name>Elgaton</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=FlightGear_wiki_talk:Instant-Refs&amp;diff=98497</id>
		<title>FlightGear wiki talk:Instant-Refs</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=FlightGear_wiki_talk:Instant-Refs&amp;diff=98497"/>
		<updated>2016-05-21T20:09:17Z</updated>

		<summary type="html">&lt;p&gt;Elgaton: /* Upcoming dependencies */ Merge request submitted to jsDelivr&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== more sources ==&lt;br /&gt;
&lt;br /&gt;
at some point, we may also want to add support for other sources, such as:&lt;br /&gt;
* old forum URLs, i.e. not yet using the subdomain format (should be easy, it's just a different/additional URL after all)&lt;br /&gt;
* thread.gmane.org/gmane.games.flightgear.devel/&lt;br /&gt;
* jsbsim devel list&lt;br /&gt;
* github tickets&lt;br /&gt;
* the new SF.net issue tracker &lt;br /&gt;
* SF.net commit logs http://gitorious.org/fg/&lt;br /&gt;
* http://www.mail-archive.com/flightgear-devel@flightgear.org/ (until 2005)&lt;br /&gt;
* http://www.mail-archive.com/flightgear-devel@lists.sourceforge.net/maillist.html (until 10/2013)&lt;br /&gt;
&lt;br /&gt;
that should cover all important sources. And it would allow us to also use the same script to help populate [[FlightGear Newsletter]] &amp;amp; [[Changelog 3.2|changelogs]], but also [[Release plan/Lessons learned]]. So this could be a real time-saver. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 14:40, 1 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Automatic update of script and old quotes ==&lt;br /&gt;
Thanks for the heads-up. Now, that makes me wonder if I can adapt the script to automatically parse existing wiki articles and update cquotes there automatically by re-opening the URL and re-running the extraction logic :) BTW: That reminds me: I was going to investigate adopting the '''downloadURL''' attribute[http://stackoverflow.com/questions/15095055/why-isnt-my-greasemonkey-script-updating] so that scripts can auto-update --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 22:51, 11 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
:: if we should continue to see this widely used, having a good way to re-download and re-run the script on pages with existing cquotes would be a good way to automatically update quotes. For that, we would want to encode certain meta info in each template, e.g.:&lt;br /&gt;
* script version&lt;br /&gt;
* quoting date/time&lt;br /&gt;
* quote URL&lt;br /&gt;
* selection offsets &lt;br /&gt;
* quoting settings (format)&lt;br /&gt;
&lt;br /&gt;
We can hook into form submission to update arbitrary quotes/contents using this: http://commons.oreilly.com/wiki/index.php/Greasemonkey_Hacks/Developer_Tools#Intercept_and_Modify_Form_Submissions&lt;br /&gt;
&lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 07:19, 15 November 2015 (EST)&lt;br /&gt;
&lt;br /&gt;
=== Hosting ===&lt;br /&gt;
The script seems to be about to become sufficiently complex to deserve actual hosting:&lt;br /&gt;
* http://wiki.greasespot.net/User_Script_Hosting&lt;br /&gt;
* https://openuserjs.org/&lt;br /&gt;
&lt;br /&gt;
(that would allow updating the script automatically)&lt;br /&gt;
&lt;br /&gt;
: Hi, is there any progress being made on this? I think the best way to host it would be to put in in a SourceForge repository under the FlightGear project (I don't know if it allows direct downloads, though, and we would need to relicense the script because [https://opensource.org/faq#public-domain public domain licenses are not OSI-approved]); otherwise, I can submit it to [https://greasyfork.org/ GreasyFork] (OpenUserJS is unsuitable as [https://openuserjs.org/about/Terms-of-Service public domain licenses are not allowed]). -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 03:58, 1 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:: I don't think anybody has looked into this recently - however, relicensing should be a no-brainer, given that all the code is in the public domain anyway. I am not sure if it's worth the hassle to put up under sourceforge/FlightGear; we also need to keep in mind that this is not exactly the most popular &amp;quot;tool&amp;quot; around here. So, before this becomes even better accessible, it might be a good idea to comply with some of the requests made, e.g. by adding support for a different output mode (without using the FGCquote template, just the copied text, plus the ref part), so that quote-heavy pages don't look that obnoxious.&lt;br /&gt;
:: Regarding hosting in general, I still think it may be a good idea, but we would probably need to make sure that some requirements are met, e.g. having a revision history, and to provide other contributors with access-alternatively, we should maintain a copy of the script in the wiki, and add a note saying that changes to it will be reviewed/integrated with the hosted script by one of us (if you'd volunteer to help with that, I'd suggest to just go ahead and set up a public repository).&lt;br /&gt;
:: Admittedly, this is going to remain a fairly FG specific script, it would need quite a bit of work to become useful for other purposes (even though other OSS projects may be easy to support). --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 06:33, 1 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
::: OK, I think we can leave the script here and host it on GreasyFork (it allows public domain scripts) - I'll put the page on my watchlist to make sure I update the script there every time there's a version bump. Does that look good to you and the other contributors? -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 09:26, 1 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:::: Sounds good to me, given how the script has evolved over time, we've probably hit a natural limit already, i.e. being able to use multiple files easily, and update scripts automatically sounds like a useful thing to me. I don't know if greasyfork supports &amp;quot;teams&amp;quot; of contributors for better collaboration ? It might also be a good idea to generalize the script so that it supports arbitrary phpBB installations and mailing list archives other than just sourceforge (think gmane) - and maybe output formats other than just wikimedia markup, that way, the script may become more useful over time.--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 13:46, 1 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
::::: It doesn't as it only offers a user script downloading facility (source code repositories like GitHub and SourceForge are better suited for the kind of work you mention). I'll wait a bit in case Red Leader, Philosopher or bigstones have any objections/remarks, then I'll upload the script there. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 17:14, 1 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:: do they support extensions spread across multiple files ? That is something that would help us quite a bit cleaning up the current code, which has become a bit convoluted over time. Apart from that, nothing wrong with github et al - I am just not sure if they're suitable for automatically propagating updated changes.--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 10:12, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
::: No, not that I know of (generally speaking, all user scripts are made of a single .user.js file). We could &amp;quot;hack&amp;quot; it by splitting the current script in multiple files and requiring them from a main one as libraries via the &amp;lt;tt&amp;gt;@include&amp;lt;/tt&amp;gt; directive, but that would rule out most hosting solutions (many providers only allow GreaseMonkey scripts which include additional files only from a handful of trusted domains/CDNs, for safety reasons).&lt;br /&gt;
::: As for propagating changes on GitHub and other code repository, the update URL must remain constant throughout the lifetime of the script. I'm sure this can be done on GitHub by publishing updates not as releases (where the addresses change), but on GitHub Pages (a user script I use does exactly this); on SourceForge, the usual download hosting could do the trick, but I'd need to perform a test first. (I'd prefer SF to keep the script &amp;quot;inside&amp;quot; the FG project hierarchy, if possible). -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 10:50, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
: actually, user scripts can be compromised of multiple files, e.g. via the require directive [http://stackoverflow.com/questions/8695459/is-it-possible-to-split-greasemonkey-user-scripts-into-multiple-files]. Personally, I would like to make use of that - we are already using that to include jQuery stuff, and it would help us organize the script a little better. I am not oposed to seeing the script hosted as some part of FG/SF, but I just don't think it's going to be a very popular idea - so far, everything worked out without major hinderance, so I would rather use an independent hosting solution, or continue to use the wiki to ensure that the barrier to entry/contributing isn't raised, e.g. by going through merge requests etc. Major contributions to the script like those from bigstones or Red Leader were simply &amp;quot;dropped&amp;quot; here directly, so this seems to have worked out really well.--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 11:26, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:: I've checked the [https://greasyfork.org/it/help/external-scripts GreasyFork external script policy]: as long as all the files are hosted on/uploaded to GreasyFork, it's not a problem. (Also, sorry about the typo, I wrote &amp;lt;tt&amp;gt;@include&amp;lt;/tt&amp;gt; instead of &amp;lt;tt&amp;gt;@require&amp;lt;/tt&amp;gt; by mistake). I guess I can proceed with the upload now? -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 12:22, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
: sure, why not - it's in the public domain after all - feel free to make any changes to the script to have it auto-update. We can review everything once we have gathered a little more experience with this kind of scheme. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 12:27, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:: {{done}} - I'm updating the installation instructions in the main page. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 13:52, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
::: Script at: https://greasyfork.org/en/scripts/19331-instant-cquotes &lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 14:18, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:::: Regarding updates, bumping the version number is fine - I'll take the script at the wiki revision where the version is bumped and upload it. (Note that I will not perform any prior testing, so be extra careful - maybe I should add this in the note above the script?). -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 18:08, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:: sounds good, I will be sure to stop updating the version number without prior testing, we could also add some tests to the code to spot the more obvious mistakes - in fact, there is already an OpenLink helper that could be used to download a few postings and try to extract the corresponding fields, so that we would only bump the version number if that succeeds. BTW: Thanks for handling the hosting part, much appreciated ! --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 18:25, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Issues ==&lt;br /&gt;
=== too greedy non-greedy regexes ===&lt;br /&gt;
The problem described in the previous section regarding regexes that eat up half messages seems to be related to my  [http://blog.liip.ch/archive/2009/07/24/the-greedyness-of-non-greedy-regular-expressions.html misunderstanding of the non-greediness]. So, I managed to fix it for this one case, but this means that using .*? to match everything until you meet the following character (as I currently do pretty much everywhere) is dangerous and prone to failure. Any occurrence of that should be changed as I did in [http://wiki.flightgear.org/index.php?title=FlightGear_wiki:Instant-Cquotes&amp;amp;oldid=72839 this edit] and that's clearly cumbersome, not to say that it can still be incorrect: say I have&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;a someprop=&amp;quot;href&amp;quot; href=&amp;quot;http://www.link.org&amp;quot; ... &amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
If I want to mach anything between a and href, I use &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;[^(?:href)]*&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;, but that would match only up to the text inside someprop, so I'd have to check that it's not inside doublequotes... Well, I guess this is getting too complicated for handling it [http://blog.codinghorror.com/parsing-html-the-cthulhu-way/ the Chtulu way].&lt;br /&gt;
&lt;br /&gt;
So my approach would be: fix this whenever the problem comes up, but don't overdo because we're already moving in dangerous ground. Or, rewrite it all using ''only'' xpaths *sobs*.&lt;br /&gt;
--[[User:Bigstones|Bigstones]] ([[User talk:Bigstones|talk]]) 16:49, 17 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
=== regex vectors ===&lt;br /&gt;
&lt;br /&gt;
When testing things I realized that you are right: there are some scenarios where the regex may fail depending on how &amp;quot;complete&amp;quot; the selection is, because we obviously have hard-coded assumptions here. I'll see if it's feasible to also support vectors for regexes to extract the corresponding fields and try each regex in order to get a certain field, or if that doesn't make any sense... But quoting with/without author (anonymous quote) would be a valid test case here.--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 16:46, 16 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
: Probably going to look into this sooner or later because this could be a simple solution to also support PM quoting - without having to parse the actual URL, we'd just try different regexes in order and use the one that succeeds. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 16:46, 16 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
=== Syntaxhighlighting ===&lt;br /&gt;
Need to investigate what needs to be updated to support quoting code sections, as per [http://forum.flightgear.org/viewtopic.php?f=66&amp;amp;t=21855&amp;amp;p=212585#p212581] --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 22:33, 14 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
=== Postings that break our script for some reason ===&lt;br /&gt;
* http://forum.flightgear.org/viewtopic.php?f=19&amp;amp;t=23365&lt;br /&gt;
&lt;br /&gt;
== Misc notes ==&lt;br /&gt;
&lt;br /&gt;
=== Detecting failed XPaths === &lt;br /&gt;
you've got a point, we should probably check if xpath/regexes succeed or fail, and show a warning so that we know that the scripts needs to be updated because some xpath/regex may have changed. &lt;br /&gt;
&lt;br /&gt;
=== Paragraphs / br (trailing slash) ===&lt;br /&gt;
There are some minor issues now, i.e. newline2br will no longer contain the trailing forward slash, so there's probably some JavaScript/regex oddity involved here, maybe slashes just need to be escaped. Will be testing the code with a few different forum postings and check the resulting cquote&lt;br /&gt;
: {{done}}. That's because newline2br wasn't used at all in html mode. I added addNewlines which puts newlines after br's and list related tags, if there are more newlines to be added that should be the place.&lt;br /&gt;
: --[[User:Bigstones|Bigstones]] ([[User talk:Bigstones|talk]]) 14:03, 17 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
=== support/ignore highlighted keywords/smilies ===&lt;br /&gt;
see [[Understanding Forward Compatibility]] for examples&lt;br /&gt;
: {{done}} --[[User:Bigstones|Bigstones]] ([[User talk:Bigstones|talk]]) 15:13, 17 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Beyond just cquotes (newsletter/changelog) ==&lt;br /&gt;
&lt;br /&gt;
Gijs has recently revamped the newsletter template rather significantly, see: [[FlightGear_Newsletter_June_2014]], and [[User_talk:Gijs#06.2F2014_newsletter:_too_much_of_a_]] - basically, we could extend the script to support another output FORMAT to directly create markup for the newsletter/changelog. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 20:40, 30 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
== more styles/output formats ==&lt;br /&gt;
&lt;br /&gt;
looking at some of the cleanup done by Red Leader recently, we could also directly support other styles/output formats to directly provide a format that looks well enough without requiring tons of manual editing. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 11:11, 13 February 2015 (EST)&lt;br /&gt;
&lt;br /&gt;
== token matching for keywords/variables ==&lt;br /&gt;
&lt;br /&gt;
seems like it might make sense to match common keywords/acronyms and variables, such as e.g.:&lt;br /&gt;
* FG_ROOT =&amp;gt; [[$FG_ROOT]]&lt;br /&gt;
* FG_HOME =&amp;gt;  [[$FG_HOME]]&lt;br /&gt;
* FG_SRC =&amp;gt; [[$FG_SRC]]&lt;br /&gt;
&lt;br /&gt;
file names with a known prefix like $FG_ROOT could even be pattern-matched using git link: $FG_ROOT/Nasal/canvas/MapStructure.nas would become [[$FG_ROOT]]{{Git link|gitorious|fg/fgdata|master|Nasal/canvas/MapStructure.nass|text=/Nasal/canvas/MapStructure.nas}}&lt;br /&gt;
&lt;br /&gt;
Equally, we could match common property paths to use code tags, e.g.: /sim/rendering would become &amp;lt;code&amp;gt;/sim/rendering&amp;lt;/code&amp;gt;&lt;br /&gt;
Ultimately, it might be a good idea to get in touch with Johan_G, Gijs and Red Leader to see what kind of format they'd prefer, especially because this could then be directly used for creating newsletter contents. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 11:19, 13 February 2015 (EST)&lt;br /&gt;
&lt;br /&gt;
== matching repository references using git link template ==&lt;br /&gt;
&lt;br /&gt;
Most of us commonly refer to repository files using either the $FG_* references, or relative paths in the form of &amp;lt;code&amp;gt;src/Main/fg_init.cxx:line number&amp;lt;/code&amp;gt;, we could automatically convert such references using the git/repo link template, e.g.: &lt;br /&gt;
&lt;br /&gt;
{{FGCquote&lt;br /&gt;
  |Further investigation found that the launcher *is* trying to add this directory to fg-aircraft (src/GUI/QtLauncher.cxx:772), but that this doesn't work because this option is processed before the launcher is run (intentionally, to allow the launcher to find aircraft in fg-aircraft: '''src/Main/main.cxx:448''').&lt;br /&gt;
  |{{cite web |url=http://sourceforge.net/p/flightgear/mailman/message/33686356/&lt;br /&gt;
     |title=&amp;lt;nowiki&amp;gt;Re: [Flightgear-devel] Launcher issues on Linux&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
     |author=&amp;lt;nowiki&amp;gt;Rebecca N. Palmer&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
     |date=&amp;lt;nowiki&amp;gt;2015-04-01&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
   }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 12:48, 1 April 2015 (EDT)&lt;br /&gt;
&lt;br /&gt;
== chrome specific port ==&lt;br /&gt;
&lt;br /&gt;
Hi Red Leader, when/if you do come up with a chrome specific version of the script, I would suggest to refactor existing APIs accordingly, so that we can come up with a common library of general purpose/utility helpers, so that both scripts can co-exist and use a common/shared file (think all the extraction/transformation logic), by referencing an external .js/JavaScript file that will be maintained/updated and hosted separately. I think this could be accomplished easily using jsfiddle. So basically, I am suggesting to come up with a shared back-end for both versions of the script. Given the complexity we're reaching meanwhile, as well as the number of edits and contributors, it may also make sense to consider using github for this at some point. One of the main advantages being that we could easily distribute updates automatically to all people who've installed the script, without them having to do anything manually.--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 08:38, 23 June 2015 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Development resources ==&lt;br /&gt;
&lt;br /&gt;
* https://www.youtube.com/watch?v=xpXNDT0SxM0&lt;br /&gt;
* http://wiki.greasespot.net/GM_getResourceText&lt;br /&gt;
* http://stackoverflow.com/questions/14594346/create-a-config-or-options-page-for-a-greasemonkey-script&lt;br /&gt;
&lt;br /&gt;
== Future focus/development and priorities (De-quoting) ==&lt;br /&gt;
&lt;br /&gt;
Given that most people involved in maintaining the wiki don't seem to particularly appreciate the nature of articles consisting mainly of quotes, and that we don't seem to have any other good way to populate new articles quickly, I was thinking of changing the focus of the script to dynamically create articles using quotes (with proper refs), that would be merely copy-edited, i.e. using the process we are currently using to &amp;quot;de-quote&amp;quot; such articles by 1) categorizing related quotes, 2) coming up with headers/sub-headers, 3) re-writing/merging certain quotes, 4) attributing them - linking back to the quotes archives.&lt;br /&gt;
Should we decide to pursue this, the script would be turned into a &amp;quot;wizard&amp;quot; where we can topics and sub-topics (wiki headings) and then add arbitrary text using the existing approach, but without using cquotes - i.e. the focus would be on extracting relevant contents, distilling them down and adding plenty of refs, including a references section at the bottom. Some tokens/words could be changed dynamically, but some kind of proof-reading/copy-editing would still need to be done afterwards, because people tend to use first person speech in their announcements/postings, which we would need to convert to 3rd person semi-automagically. Thoughts/ideas ?--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 07:11, 15 November 2015 (EST)&lt;br /&gt;
&lt;br /&gt;
== changing and automating regex/xpath handling ==&lt;br /&gt;
{{See also|#Genetic_Expression_solver}}&lt;br /&gt;
&lt;br /&gt;
We have currently hard-coded handling of different websites, regexes and xpath expressions so that things are a  bit fragile at the moment, and once a website changes its style/template, our script would break immediately. However, we could change the way the script works by using a very simple NN (neural network) to come up with matching regex/xpath expressions automatically. The way this could work would be &amp;quot;supervised&amp;quot; training, where we would replace/adapt our existing CONFIG hash with a vector of URLs and contents to be extracted (date, time, title, posting). This kind of data would suffice entirely for a neural network to self-train itself and &amp;quot;learn&amp;quot; how to come up with regex/xpath expressions to extract the relevant contents, including not only hard-coded websites like sourceforge, but even completely different websites (think gmane) - because the &amp;quot;learning&amp;quot; routine would self-adapt by looking at how to get its contents, and never contain any hard-coded regex/xpath expressions anymore. The CONFIG hash would end up being a vector with &amp;quot;training data&amp;quot; for different websites to be supported. And whenever an expression fails, it could re-train itself accordingly.--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 13:33, 15 November 2015 (EST)&lt;br /&gt;
&lt;br /&gt;
== nested quotes and AJAX for thread titles ==&lt;br /&gt;
&lt;br /&gt;
{{FGCquote&lt;br /&gt;
|1= http://sourceforge.net/p/flightgear/mailman/message/33451055/&lt;br /&gt;
{{cquote|As we move forward with FlightGear development and future versions, we will be expanding the &amp;quot;in app&amp;quot; aircraft center. This dialog inside flightgear lets you select, download, and switch to any of the aircraft in the library.|Curt}}&lt;br /&gt;
|2= {{cite web&lt;br /&gt;
  | url    = http://forum.flightgear.org/viewtopic.php?p=259879#p259879&lt;br /&gt;
  | title  = &amp;lt;nowiki&amp;gt;Re: New Canvas GUI&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  | author = &amp;lt;nowiki&amp;gt;Hooray&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  | date   = Oct 7th, 2015&lt;br /&gt;
  }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== AJAX mode/testing ==&lt;br /&gt;
&lt;br /&gt;
We should probably add a dialog to store credentials that we can use for accessing the wiki, which would need to be shown after installing the script, i.e. first-time use&lt;br /&gt;
&lt;br /&gt;
* http://stackoverflow.com/questions/14594346/create-a-config-or-options-page-for-a-greasemonkey-script&lt;br /&gt;
* http://commons.oreilly.com/wiki/index.php/Greasemonkey_Hacks/Getting_Started#During_Installation&lt;br /&gt;
* https://www.safaribooksonline.com/library/view/greasemonkey-hacks/0596101651/ch01s06.html&lt;br /&gt;
&lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 12:59, 20 November 2015 (EST)&lt;br /&gt;
&lt;br /&gt;
== libraries ==&lt;br /&gt;
&lt;br /&gt;
Referring to the [[#Hosting]] section, and my comment on wanting to use additional libs (like jQuery), I am primarily thinking about using a wizard-framework (e.g. jQuery steps) and a framework for creating wikimedia editor plugins (actions):&lt;br /&gt;
&lt;br /&gt;
* http://mstratman.github.io/jQuery-Smart-Wizard/&lt;br /&gt;
* http://www.jquery-steps.com/&lt;br /&gt;
* http://www.jqueryrain.com/demo/jquery-step-form-wizard/&lt;br /&gt;
* https://www.mediawiki.org/wiki/Extension:WikiEditor&lt;br /&gt;
&lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 12:07, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== About dequoting the script's article ==&lt;br /&gt;
&lt;br /&gt;
Thanks for doing this, but I am frankly not sure if it's worth the effort - there are much more popular/important articles using tons of quotes than this one, and given the reputation of the script, having quotes in this article may actually be a useful thing to make the case for having quotes in the first place - thus, I would frankly not spend much time going through this particular article - in fact, I'd be very surprised if the greasyfork download stats showed more than 3-5 people actually downloading, and using, the script - so this is really just a niche tool, and we probably better spend our time doing other things, and reviewing other wiki articles, than the script's article - at the very least, I would suggest to retain the references to the original discussions revolving these quotes (just my 2c). --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 19:00, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
: {{done}} I've added back the quotes as references. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 02:53, 3 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Script configuration (persistence) ==&lt;br /&gt;
&lt;br /&gt;
* https://wiki.greasespot.net/GM_config&lt;br /&gt;
* https://github.com/sizzlemctwizzle/GM_config/wiki&lt;br /&gt;
* https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API&lt;br /&gt;
&lt;br /&gt;
== Work in progress ==&lt;br /&gt;
&lt;br /&gt;
We have now several more or less related development efforts going on, and the code is also growing because of that - so it seems to make sense to summarize what's been going on recently. In general, all changes were made in response to the collection of feature requests and ideas we have accumulated over time  - specifically, that means that the following roadmap is in the process of being implemented:&lt;br /&gt;
&lt;br /&gt;
* establish unit testing, and add a few self-tests, so that the script can be more easily tested, updated/reviewed in the future&lt;br /&gt;
* rework the script to more easily support other sources (think gmane)&lt;br /&gt;
* make it much easier to update modified xpath/regex expressions (i.e. provide a UI for that)&lt;br /&gt;
* support persistence for script-specific settings&lt;br /&gt;
* make it easier for people to port/maintain the script by encapsulating platform specifics&lt;br /&gt;
* support asynchronous fetching of postings (AJAX), e.g. to fetch posting titles, attachments etc&lt;br /&gt;
* prepare the groundwork for supporting template-based output formats (think newsletter, changelog, articles)&lt;br /&gt;
* review what's necessary to allow the script to update fgcquote-based quotes automagically&lt;br /&gt;
&lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 16:47, 4 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== External genetic/neural network libraries ==&lt;br /&gt;
While uploading the latest version of the script, I noticed that the Genetic and Synaptic libraries are hosted on sites not on [https://greasyfork.org/en/help/external-scripts the approved GreasyFork list]. Shall I ask them to host them? -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 13:28, 11 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
: Thanks for pointing that out, I missed that completely, because everything is working correctly here - but obviously, I rarely get to actually download/install the latest version via greasyfork. Those libs should be safe to be added to the list, i.e. they're fairly established/popular, lest I'd not be using them. For now, this is just an experiment anyway. The idea is to update the xpath/regex code to evolve if/when the underlying website (theme) changes. But if there is a problem, we could use other libs - the code is just used for testing ATM. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 13:41, 11 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
* https://github.com/subprotocol/genetic-js&lt;br /&gt;
* https://github.com/cazala/synaptic&lt;br /&gt;
&lt;br /&gt;
:: {{ongoing}} I have submitted the libraries to the JSDelivr CDN; once they are up, I'll change the source URLs in the script and update it on GreasyFork as well. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 18:32, 17 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
::: Hi Elgaton, thank you for taking care of this, it's very much appreciated ! --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 18:55, 17 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:::: You're welcome! My merge requests for the CDN were approved (this took a bit longer than expected because I had made a small mistake - I forgot to include a file required by the Genetic.js library). The libraries should be up in a day or two, at which point I'll update the URLs in the script and submit the new version to GreasyFork. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 02:59, 20 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
::::: {{done}} Everything should be fine now. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 09:16, 20 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:: Thank you for all the help with this, and also for updating the greasyfork info/screenshots ! --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 07:16, 21 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Genetic Expression solver ==&lt;br /&gt;
[[File:Instant-cquotes-genetic-regex-solving.png|thumb|Screenshot showing the instant cquotes script with integrated regex solving support using genetic algorithms.]]&lt;br /&gt;
&lt;br /&gt;
The genetic-js framework has been integrated, it is intended to help solve xpath/regex expressions procedurally using genetic algorithms/programming. &lt;br /&gt;
&lt;br /&gt;
The idea is to provide a set of desired outputs (needles), available input data (haystack), and use existing (possibly outdated) regex/xpath expressions to seed a pool with potential solutions for retrieving the desired output. For now, this is just proof-of-concept, i.e. just an experiment.&lt;br /&gt;
&lt;br /&gt;
For example, let's consider the typical format of a from header for any sourceforge posting:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var regexTests = [&lt;br /&gt;
  {haystack: &amp;quot;From: John Doe &amp;lt;John@do...&amp;gt; - 2020-07-02 17:36:03&amp;quot;, needle: &amp;quot;John Doe&amp;quot;}, &lt;br /&gt;
  {haystack: &amp;quot;From: Marc Twain &amp;lt;Marc@ta...&amp;gt; - 2010-01-03 07:36:03&amp;quot;, needle: &amp;quot;Marc Twain&amp;quot;},&lt;br /&gt;
  {haystack: &amp;quot;From: George W. Bush &amp;lt;GWB@wh...&amp;gt; - 2055-11-11 17:33:13&amp;quot;, needle: &amp;quot;George W. Bush&amp;quot;}&lt;br /&gt;
];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The basic idea is to run a fitness function and score regex expressions based on not throwing an exception (which makes them valid), and by checking if the desired tokens are part of the output string, and evolve (mutate/cross-over) the &amp;quot;fittest&amp;quot; expressions - i.e. those that satisfy at least /some/ of the heuristics.&lt;br /&gt;
&lt;br /&gt;
Some of the metrics that can be used by the fitness function to determine if an expression is &amp;quot;fit&amp;quot;, are:&lt;br /&gt;
* valid expression&lt;br /&gt;
* relative offset/excess bytes in matches string&lt;br /&gt;
* number of examples it can successfully extract&lt;br /&gt;
* length of the expression&lt;br /&gt;
* runtime of the expression&lt;br /&gt;
&lt;br /&gt;
The search space, and runtime, can be significantly reduced by looking at similarities between all examples and coming up with a subset string that contains all identical components (e.g. the &amp;lt;code&amp;gt;From:&amp;lt;/code&amp;gt; part in the author regex) and use that for seeding the initial generations.&lt;br /&gt;
&lt;br /&gt;
Ultimately, this would allow the script to self-update its regex/xpath expressions if/when the underlying website (themes) change, but it would also allow to add support for new websites, without ever manually adding the required xpath/regex expressions, i.e. all that is needed is a sufficiently large number of example datasets to obtain the author, date and title information, and a URL for the script to download the HTML markup of the posting in question:&lt;br /&gt;
&lt;br /&gt;
{{Note|The date field won't work as is, because it's actually post-processed using a transformation function, so we'd need to undo the transformation or use the actual date string instead}}&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt; // vector with tests to be executed for sanity checks (unit testing)&lt;br /&gt;
    tests: [&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://sourceforge.net/p/flightgear/mailman/message/35059454/',&lt;br /&gt;
        author: 'Erik Hofman',&lt;br /&gt;
        date: 'May 3rd, 2016', // NOTE: using the transformed date here &lt;br /&gt;
        title: 'Re: [Flightgear-devel] Auto altimeter setting at startup (?)'&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://sourceforge.net/p/flightgear/mailman/message/35059961/',&lt;br /&gt;
        author: 'Ludovic Brenta',&lt;br /&gt;
        date: 'May 3rd, 2016',&lt;br /&gt;
        title: 'Re: [Flightgear-devel] dual-control-tools and the limit on packet size'&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://sourceforge.net/p/flightgear/mailman/message/20014126/',&lt;br /&gt;
        author: 'Tim Moore',&lt;br /&gt;
        date: 'Aug 4th, 2008',&lt;br /&gt;
        title: 'Re: [Flightgear-devel] Cockpit displays (rendering, modelling)'&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://sourceforge.net/p/flightgear/mailman/message/23518343/',&lt;br /&gt;
        author: 'Tim Moore',&lt;br /&gt;
        date: 'Sep 10th, 2009',&lt;br /&gt;
        title: '[Flightgear-devel] Atmosphere patch from John Denker'&lt;br /&gt;
      } // add other tests below&lt;br /&gt;
&lt;br /&gt;
    ], // end of vector with self-tests&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note how this no longer contains any hard-coded xpath/regex expressions - instead, the script can refer to the website specific defaults, and try those first, and if they fail, use those to seed new generations and evolve them procedurally until all tests succeed.&lt;br /&gt;
&lt;br /&gt;
For a regex to be valid, it must work for all tests/examples.&lt;br /&gt;
&lt;br /&gt;
Once the regex solver is working correctly, the code can be further generalized to also evolve xpath expressions (NOTE: the DOMParser API is /not/ available to webworkers ...) and chain those two components together.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* http://regex.inginf.units.it/how.html&lt;br /&gt;
* http://www.i-programmer.info/programming/perl/9503-automatically-generating-regular-expressions-with-genetic-programming.html&lt;br /&gt;
* http://jkff.info/articles/ire/&lt;br /&gt;
* http://www.networkworld.com/article/2955126/software/genetic-programming-meets-regular-expressions.html&lt;br /&gt;
* https://handcraftsman.wordpress.com/2012/04/11/evolving-a-regular-expression-with-go/&lt;br /&gt;
* http://stackoverflow.com/questions/4880402/how-to-auto-generate-regex-from-given-list-of-strings&lt;br /&gt;
* http://regex.inginf.units.it/&lt;br /&gt;
* http://www.genetic-programming.org/hc2014/Bartoli-Paper.pdf&lt;br /&gt;
&lt;br /&gt;
== Hierarchical Clustering  ==&lt;br /&gt;
&lt;br /&gt;
Been tinkering with a JavaScript module to automatically cluster postings based on certain keywords in the topic/title or posting (e.g. Nasal, Canvas, 2D API, rendering): https://harthur.github.io/clusterfck/&lt;br /&gt;
&lt;br /&gt;
Note that in conjunction with processing article sections and/or whole articles, this could help automatically come up with matching postings for articles and vice versa.&lt;br /&gt;
&lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 18:11, 19 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Upcoming dependencies ==&lt;br /&gt;
&lt;br /&gt;
The script is now using [http://markitup.jaysalvat.com/home/ markitup] to create the template editor. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 10:18, 21 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
: I've [https://github.com/jsdelivr/jsdelivr/pull/11757 submitted a pull request] for the library to be distributed by jsDelivr. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 16:08, 21 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Code beautifier ? ==&lt;br /&gt;
&lt;br /&gt;
I still had, and have, pending changes that would need to go through the same beautifier you're using, or they'd be lost -  so for now, I have just overwritten your  beautified code, hope that you didn't do this manually (there really are tons of automated and configurable beautifiers out there). --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 15:59, 21 May 2016 (EDT)&lt;/div&gt;</summary>
		<author><name>Elgaton</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Talk:FlightGear_Git&amp;diff=98470</id>
		<title>Talk:FlightGear Git</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Talk:FlightGear_Git&amp;diff=98470"/>
		<updated>2016-05-21T12:01:49Z</updated>

		<summary type="html">&lt;p&gt;Elgaton: /* Repository link templates */ Good idea, not sure on MacLauncher though&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Questions =&lt;br /&gt;
&lt;br /&gt;
== forum posting ==&lt;br /&gt;
Feel free to add or link to this: http://flightgear.org/forums/viewtopic.php?f=22&amp;amp;t=8270&amp;amp;p=93371#p93371&lt;br /&gt;
--[[User:Hooray|Hooray]] 20:31, 1 December 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
== mob access ==&lt;br /&gt;
If this experiment is meant to become a community experience, for both developers and users, how about enabling mob access, too [http://repo.or.cz/mob.html]? There are often people that are neither core developers, nor aspire to become one, but who are technical users who'd like to more easily submit patches.&lt;br /&gt;
While most long-term FlightGear users know about the fact that &amp;quot;FlightGear life&amp;quot; takes places on the mailing lists, many others often just end up sharing patches via the forums, sf.net patch trackers or even via IRC.&lt;br /&gt;
So, this would be an extremely easy way for potential contributors to more easily share local modifications with fellow users, without having any effect on any of the trusted main branches or organizational burden on the project lead, so it would sort of become a &amp;quot;sandbox&amp;quot; environment with &amp;quot;wild&amp;quot; code. Core developers could more easily keep track of patches submitted this way, too.--[[User:MILSTD|MILSTD]] 07:29, 4 February 2009 (EST)&lt;br /&gt;
&lt;br /&gt;
The mob branch idea is intriguing, but it is so easy for anyone to set up their own forked flightgear repositories, especially on repo.or.cz, that I don't think it's necessary to enable the mob branch. It's really more useful to be able to say &amp;quot;pull the foo branch in my repository&amp;quot; than &amp;quot;pull my cool commit out of the mob branch.&amp;quot;--[[User:Timoore|Timoore]] 05:24, 5 February 2009 (EST)&lt;br /&gt;
&lt;br /&gt;
== Repository link templates ==&lt;br /&gt;
&lt;br /&gt;
Hi Elgaton, I was wondering if you think it is worth creating [[:Category:Repository link templates|repository link templates]] for the Windows-3rd-party, FGCom, terrafs, and MacLauncher git repositories for use in the table?  I haven't seen any need anywhere else in the wiki for these yet.&lt;br /&gt;
&lt;br /&gt;
[[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 12:01, 20 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
: ''Yes'' for the Windows-3rd-party/FGCom/TerraFS repositories; I'm ''not so sure'' for the MacLauncher one (the code has not seen an update in years). -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 08:01, 21 May 2016 (EDT)&lt;/div&gt;</summary>
		<author><name>Elgaton</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=FlightGear_wiki_talk:Instant-Refs&amp;diff=98427</id>
		<title>FlightGear wiki talk:Instant-Refs</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=FlightGear_wiki_talk:Instant-Refs&amp;diff=98427"/>
		<updated>2016-05-20T13:16:14Z</updated>

		<summary type="html">&lt;p&gt;Elgaton: /* External genetic/neural network libraries */ Scripts uploaded to CDN&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== more sources ==&lt;br /&gt;
&lt;br /&gt;
at some point, we may also want to add support for other sources, such as:&lt;br /&gt;
* old forum URLs, i.e. not yet using the subdomain format (should be easy, it's just a different/additional URL after all)&lt;br /&gt;
* thread.gmane.org/gmane.games.flightgear.devel/&lt;br /&gt;
* jsbsim devel list&lt;br /&gt;
* github tickets&lt;br /&gt;
* the new SF.net issue tracker &lt;br /&gt;
* SF.net commit logs http://gitorious.org/fg/&lt;br /&gt;
* http://www.mail-archive.com/flightgear-devel@flightgear.org/ (until 2005)&lt;br /&gt;
* http://www.mail-archive.com/flightgear-devel@lists.sourceforge.net/maillist.html (until 10/2013)&lt;br /&gt;
&lt;br /&gt;
that should cover all important sources. And it would allow us to also use the same script to help populate [[FlightGear Newsletter]] &amp;amp; [[Changelog 3.2|changelogs]], but also [[Release plan/Lessons learned]]. So this could be a real time-saver. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 14:40, 1 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Automatic update of script and old quotes ==&lt;br /&gt;
Thanks for the heads-up. Now, that makes me wonder if I can adapt the script to automatically parse existing wiki articles and update cquotes there automatically by re-opening the URL and re-running the extraction logic :) BTW: That reminds me: I was going to investigate adopting the '''downloadURL''' attribute[http://stackoverflow.com/questions/15095055/why-isnt-my-greasemonkey-script-updating] so that scripts can auto-update --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 22:51, 11 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
:: if we should continue to see this widely used, having a good way to re-download and re-run the script on pages with existing cquotes would be a good way to automatically update quotes. For that, we would want to encode certain meta info in each template, e.g.:&lt;br /&gt;
* script version&lt;br /&gt;
* quoting date/time&lt;br /&gt;
* quote URL&lt;br /&gt;
* selection offsets &lt;br /&gt;
* quoting settings (format)&lt;br /&gt;
&lt;br /&gt;
We can hook into form submission to update arbitrary quotes/contents using this: http://commons.oreilly.com/wiki/index.php/Greasemonkey_Hacks/Developer_Tools#Intercept_and_Modify_Form_Submissions&lt;br /&gt;
&lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 07:19, 15 November 2015 (EST)&lt;br /&gt;
&lt;br /&gt;
=== Hosting ===&lt;br /&gt;
The script seems to be about to become sufficiently complex to deserve actual hosting:&lt;br /&gt;
* http://wiki.greasespot.net/User_Script_Hosting&lt;br /&gt;
* https://openuserjs.org/&lt;br /&gt;
&lt;br /&gt;
(that would allow updating the script automatically)&lt;br /&gt;
&lt;br /&gt;
: Hi, is there any progress being made on this? I think the best way to host it would be to put in in a SourceForge repository under the FlightGear project (I don't know if it allows direct downloads, though, and we would need to relicense the script because [https://opensource.org/faq#public-domain public domain licenses are not OSI-approved]); otherwise, I can submit it to [https://greasyfork.org/ GreasyFork] (OpenUserJS is unsuitable as [https://openuserjs.org/about/Terms-of-Service public domain licenses are not allowed]). -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 03:58, 1 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:: I don't think anybody has looked into this recently - however, relicensing should be a no-brainer, given that all the code is in the public domain anyway. I am not sure if it's worth the hassle to put up under sourceforge/FlightGear; we also need to keep in mind that this is not exactly the most popular &amp;quot;tool&amp;quot; around here. So, before this becomes even better accessible, it might be a good idea to comply with some of the requests made, e.g. by adding support for a different output mode (without using the FGCquote template, just the copied text, plus the ref part), so that quote-heavy pages don't look that obnoxious.&lt;br /&gt;
:: Regarding hosting in general, I still think it may be a good idea, but we would probably need to make sure that some requirements are met, e.g. having a revision history, and to provide other contributors with access-alternatively, we should maintain a copy of the script in the wiki, and add a note saying that changes to it will be reviewed/integrated with the hosted script by one of us (if you'd volunteer to help with that, I'd suggest to just go ahead and set up a public repository).&lt;br /&gt;
:: Admittedly, this is going to remain a fairly FG specific script, it would need quite a bit of work to become useful for other purposes (even though other OSS projects may be easy to support). --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 06:33, 1 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
::: OK, I think we can leave the script here and host it on GreasyFork (it allows public domain scripts) - I'll put the page on my watchlist to make sure I update the script there every time there's a version bump. Does that look good to you and the other contributors? -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 09:26, 1 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:::: Sounds good to me, given how the script has evolved over time, we've probably hit a natural limit already, i.e. being able to use multiple files easily, and update scripts automatically sounds like a useful thing to me. I don't know if greasyfork supports &amp;quot;teams&amp;quot; of contributors for better collaboration ? It might also be a good idea to generalize the script so that it supports arbitrary phpBB installations and mailing list archives other than just sourceforge (think gmane) - and maybe output formats other than just wikimedia markup, that way, the script may become more useful over time.--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 13:46, 1 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
::::: It doesn't as it only offers a user script downloading facility (source code repositories like GitHub and SourceForge are better suited for the kind of work you mention). I'll wait a bit in case Red Leader, Philosopher or bigstones have any objections/remarks, then I'll upload the script there. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 17:14, 1 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:: do they support extensions spread across multiple files ? That is something that would help us quite a bit cleaning up the current code, which has become a bit convoluted over time. Apart from that, nothing wrong with github et al - I am just not sure if they're suitable for automatically propagating updated changes.--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 10:12, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
::: No, not that I know of (generally speaking, all user scripts are made of a single .user.js file). We could &amp;quot;hack&amp;quot; it by splitting the current script in multiple files and requiring them from a main one as libraries via the &amp;lt;tt&amp;gt;@include&amp;lt;/tt&amp;gt; directive, but that would rule out most hosting solutions (many providers only allow GreaseMonkey scripts which include additional files only from a handful of trusted domains/CDNs, for safety reasons).&lt;br /&gt;
::: As for propagating changes on GitHub and other code repository, the update URL must remain constant throughout the lifetime of the script. I'm sure this can be done on GitHub by publishing updates not as releases (where the addresses change), but on GitHub Pages (a user script I use does exactly this); on SourceForge, the usual download hosting could do the trick, but I'd need to perform a test first. (I'd prefer SF to keep the script &amp;quot;inside&amp;quot; the FG project hierarchy, if possible). -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 10:50, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
: actually, user scripts can be compromised of multiple files, e.g. via the require directive [http://stackoverflow.com/questions/8695459/is-it-possible-to-split-greasemonkey-user-scripts-into-multiple-files]. Personally, I would like to make use of that - we are already using that to include jQuery stuff, and it would help us organize the script a little better. I am not oposed to seeing the script hosted as some part of FG/SF, but I just don't think it's going to be a very popular idea - so far, everything worked out without major hinderance, so I would rather use an independent hosting solution, or continue to use the wiki to ensure that the barrier to entry/contributing isn't raised, e.g. by going through merge requests etc. Major contributions to the script like those from bigstones or Red Leader were simply &amp;quot;dropped&amp;quot; here directly, so this seems to have worked out really well.--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 11:26, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:: I've checked the [https://greasyfork.org/it/help/external-scripts GreasyFork external script policy]: as long as all the files are hosted on/uploaded to GreasyFork, it's not a problem. (Also, sorry about the typo, I wrote &amp;lt;tt&amp;gt;@include&amp;lt;/tt&amp;gt; instead of &amp;lt;tt&amp;gt;@require&amp;lt;/tt&amp;gt; by mistake). I guess I can proceed with the upload now? -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 12:22, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
: sure, why not - it's in the public domain after all - feel free to make any changes to the script to have it auto-update. We can review everything once we have gathered a little more experience with this kind of scheme. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 12:27, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:: {{done}} - I'm updating the installation instructions in the main page. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 13:52, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
::: Script at: https://greasyfork.org/en/scripts/19331-instant-cquotes &lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 14:18, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:::: Regarding updates, bumping the version number is fine - I'll take the script at the wiki revision where the version is bumped and upload it. (Note that I will not perform any prior testing, so be extra careful - maybe I should add this in the note above the script?). -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 18:08, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:: sounds good, I will be sure to stop updating the version number without prior testing, we could also add some tests to the code to spot the more obvious mistakes - in fact, there is already an OpenLink helper that could be used to download a few postings and try to extract the corresponding fields, so that we would only bump the version number if that succeeds. BTW: Thanks for handling the hosting part, much appreciated ! --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 18:25, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Issues ==&lt;br /&gt;
=== too greedy non-greedy regexes ===&lt;br /&gt;
The problem described in the previous section regarding regexes that eat up half messages seems to be related to my  [http://blog.liip.ch/archive/2009/07/24/the-greedyness-of-non-greedy-regular-expressions.html misunderstanding of the non-greediness]. So, I managed to fix it for this one case, but this means that using .*? to match everything until you meet the following character (as I currently do pretty much everywhere) is dangerous and prone to failure. Any occurrence of that should be changed as I did in [http://wiki.flightgear.org/index.php?title=FlightGear_wiki:Instant-Cquotes&amp;amp;oldid=72839 this edit] and that's clearly cumbersome, not to say that it can still be incorrect: say I have&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;a someprop=&amp;quot;href&amp;quot; href=&amp;quot;http://www.link.org&amp;quot; ... &amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
If I want to mach anything between a and href, I use &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;[^(?:href)]*&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;, but that would match only up to the text inside someprop, so I'd have to check that it's not inside doublequotes... Well, I guess this is getting too complicated for handling it [http://blog.codinghorror.com/parsing-html-the-cthulhu-way/ the Chtulu way].&lt;br /&gt;
&lt;br /&gt;
So my approach would be: fix this whenever the problem comes up, but don't overdo because we're already moving in dangerous ground. Or, rewrite it all using ''only'' xpaths *sobs*.&lt;br /&gt;
--[[User:Bigstones|Bigstones]] ([[User talk:Bigstones|talk]]) 16:49, 17 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
=== regex vectors ===&lt;br /&gt;
&lt;br /&gt;
When testing things I realized that you are right: there are some scenarios where the regex may fail depending on how &amp;quot;complete&amp;quot; the selection is, because we obviously have hard-coded assumptions here. I'll see if it's feasible to also support vectors for regexes to extract the corresponding fields and try each regex in order to get a certain field, or if that doesn't make any sense... But quoting with/without author (anonymous quote) would be a valid test case here.--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 16:46, 16 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
: Probably going to look into this sooner or later because this could be a simple solution to also support PM quoting - without having to parse the actual URL, we'd just try different regexes in order and use the one that succeeds. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 16:46, 16 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
=== Syntaxhighlighting ===&lt;br /&gt;
Need to investigate what needs to be updated to support quoting code sections, as per [http://forum.flightgear.org/viewtopic.php?f=66&amp;amp;t=21855&amp;amp;p=212585#p212581] --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 22:33, 14 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
=== Postings that break our script for some reason ===&lt;br /&gt;
* http://forum.flightgear.org/viewtopic.php?f=19&amp;amp;t=23365&lt;br /&gt;
&lt;br /&gt;
== Misc notes ==&lt;br /&gt;
&lt;br /&gt;
=== Detecting failed XPaths === &lt;br /&gt;
you've got a point, we should probably check if xpath/regexes succeed or fail, and show a warning so that we know that the scripts needs to be updated because some xpath/regex may have changed. &lt;br /&gt;
&lt;br /&gt;
=== Paragraphs / br (trailing slash) ===&lt;br /&gt;
There are some minor issues now, i.e. newline2br will no longer contain the trailing forward slash, so there's probably some JavaScript/regex oddity involved here, maybe slashes just need to be escaped. Will be testing the code with a few different forum postings and check the resulting cquote&lt;br /&gt;
: {{done}}. That's because newline2br wasn't used at all in html mode. I added addNewlines which puts newlines after br's and list related tags, if there are more newlines to be added that should be the place.&lt;br /&gt;
: --[[User:Bigstones|Bigstones]] ([[User talk:Bigstones|talk]]) 14:03, 17 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
=== support/ignore highlighted keywords/smilies ===&lt;br /&gt;
see [[Understanding Forward Compatibility]] for examples&lt;br /&gt;
: {{done}} --[[User:Bigstones|Bigstones]] ([[User talk:Bigstones|talk]]) 15:13, 17 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Beyond just cquotes (newsletter/changelog) ==&lt;br /&gt;
&lt;br /&gt;
Gijs has recently revamped the newsletter template rather significantly, see: [[FlightGear_Newsletter_June_2014]], and [[User_talk:Gijs#06.2F2014_newsletter:_too_much_of_a_]] - basically, we could extend the script to support another output FORMAT to directly create markup for the newsletter/changelog. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 20:40, 30 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
== more styles/output formats ==&lt;br /&gt;
&lt;br /&gt;
looking at some of the cleanup done by Red Leader recently, we could also directly support other styles/output formats to directly provide a format that looks well enough without requiring tons of manual editing. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 11:11, 13 February 2015 (EST)&lt;br /&gt;
&lt;br /&gt;
== token matching for keywords/variables ==&lt;br /&gt;
&lt;br /&gt;
seems like it might make sense to match common keywords/acronyms and variables, such as e.g.:&lt;br /&gt;
* FG_ROOT =&amp;gt; [[$FG_ROOT]]&lt;br /&gt;
* FG_HOME =&amp;gt;  [[$FG_HOME]]&lt;br /&gt;
* FG_SRC =&amp;gt; [[$FG_SRC]]&lt;br /&gt;
&lt;br /&gt;
file names with a known prefix like $FG_ROOT could even be pattern-matched using git link: $FG_ROOT/Nasal/canvas/MapStructure.nas would become [[$FG_ROOT]]{{Git link|gitorious|fg/fgdata|master|Nasal/canvas/MapStructure.nass|text=/Nasal/canvas/MapStructure.nas}}&lt;br /&gt;
&lt;br /&gt;
Equally, we could match common property paths to use code tags, e.g.: /sim/rendering would become &amp;lt;code&amp;gt;/sim/rendering&amp;lt;/code&amp;gt;&lt;br /&gt;
Ultimately, it might be a good idea to get in touch with Johan_G, Gijs and Red Leader to see what kind of format they'd prefer, especially because this could then be directly used for creating newsletter contents. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 11:19, 13 February 2015 (EST)&lt;br /&gt;
&lt;br /&gt;
== matching repository references using git link template ==&lt;br /&gt;
&lt;br /&gt;
Most of us commonly refer to repository files using either the $FG_* references, or relative paths in the form of &amp;lt;code&amp;gt;src/Main/fg_init.cxx:line number&amp;lt;/code&amp;gt;, we could automatically convert such references using the git/repo link template, e.g.: &lt;br /&gt;
&lt;br /&gt;
{{FGCquote&lt;br /&gt;
  |Further investigation found that the launcher *is* trying to add this directory to fg-aircraft (src/GUI/QtLauncher.cxx:772), but that this doesn't work because this option is processed before the launcher is run (intentionally, to allow the launcher to find aircraft in fg-aircraft: '''src/Main/main.cxx:448''').&lt;br /&gt;
  |{{cite web |url=http://sourceforge.net/p/flightgear/mailman/message/33686356/&lt;br /&gt;
     |title=&amp;lt;nowiki&amp;gt;Re: [Flightgear-devel] Launcher issues on Linux&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
     |author=&amp;lt;nowiki&amp;gt;Rebecca N. Palmer&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
     |date=&amp;lt;nowiki&amp;gt;2015-04-01&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
   }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 12:48, 1 April 2015 (EDT)&lt;br /&gt;
&lt;br /&gt;
== chrome specific port ==&lt;br /&gt;
&lt;br /&gt;
Hi Red Leader, when/if you do come up with a chrome specific version of the script, I would suggest to refactor existing APIs accordingly, so that we can come up with a common library of general purpose/utility helpers, so that both scripts can co-exist and use a common/shared file (think all the extraction/transformation logic), by referencing an external .js/JavaScript file that will be maintained/updated and hosted separately. I think this could be accomplished easily using jsfiddle. So basically, I am suggesting to come up with a shared back-end for both versions of the script. Given the complexity we're reaching meanwhile, as well as the number of edits and contributors, it may also make sense to consider using github for this at some point. One of the main advantages being that we could easily distribute updates automatically to all people who've installed the script, without them having to do anything manually.--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 08:38, 23 June 2015 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Development resources ==&lt;br /&gt;
&lt;br /&gt;
* https://www.youtube.com/watch?v=xpXNDT0SxM0&lt;br /&gt;
* http://wiki.greasespot.net/GM_getResourceText&lt;br /&gt;
* http://stackoverflow.com/questions/14594346/create-a-config-or-options-page-for-a-greasemonkey-script&lt;br /&gt;
&lt;br /&gt;
== Future focus/development and priorities (De-quoting) ==&lt;br /&gt;
&lt;br /&gt;
Given that most people involved in maintaining the wiki don't seem to particularly appreciate the nature of articles consisting mainly of quotes, and that we don't seem to have any other good way to populate new articles quickly, I was thinking of changing the focus of the script to dynamically create articles using quotes (with proper refs), that would be merely copy-edited, i.e. using the process we are currently using to &amp;quot;de-quote&amp;quot; such articles by 1) categorizing related quotes, 2) coming up with headers/sub-headers, 3) re-writing/merging certain quotes, 4) attributing them - linking back to the quotes archives.&lt;br /&gt;
Should we decide to pursue this, the script would be turned into a &amp;quot;wizard&amp;quot; where we can topics and sub-topics (wiki headings) and then add arbitrary text using the existing approach, but without using cquotes - i.e. the focus would be on extracting relevant contents, distilling them down and adding plenty of refs, including a references section at the bottom. Some tokens/words could be changed dynamically, but some kind of proof-reading/copy-editing would still need to be done afterwards, because people tend to use first person speech in their announcements/postings, which we would need to convert to 3rd person semi-automagically. Thoughts/ideas ?--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 07:11, 15 November 2015 (EST)&lt;br /&gt;
&lt;br /&gt;
== changing and automating regex/xpath handling ==&lt;br /&gt;
{{See also|#Genetic_Expression_solver}}&lt;br /&gt;
&lt;br /&gt;
We have currently hard-coded handling of different websites, regexes and xpath expressions so that things are a  bit fragile at the moment, and once a website changes its style/template, our script would break immediately. However, we could change the way the script works by using a very simple NN (neural network) to come up with matching regex/xpath expressions automatically. The way this could work would be &amp;quot;supervised&amp;quot; training, where we would replace/adapt our existing CONFIG hash with a vector of URLs and contents to be extracted (date, time, title, posting). This kind of data would suffice entirely for a neural network to self-train itself and &amp;quot;learn&amp;quot; how to come up with regex/xpath expressions to extract the relevant contents, including not only hard-coded websites like sourceforge, but even completely different websites (think gmane) - because the &amp;quot;learning&amp;quot; routine would self-adapt by looking at how to get its contents, and never contain any hard-coded regex/xpath expressions anymore. The CONFIG hash would end up being a vector with &amp;quot;training data&amp;quot; for different websites to be supported. And whenever an expression fails, it could re-train itself accordingly.--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 13:33, 15 November 2015 (EST)&lt;br /&gt;
&lt;br /&gt;
== nested quotes and AJAX for thread titles ==&lt;br /&gt;
&lt;br /&gt;
{{FGCquote&lt;br /&gt;
|1= http://sourceforge.net/p/flightgear/mailman/message/33451055/&lt;br /&gt;
{{cquote|As we move forward with FlightGear development and future versions, we will be expanding the &amp;quot;in app&amp;quot; aircraft center. This dialog inside flightgear lets you select, download, and switch to any of the aircraft in the library.|Curt}}&lt;br /&gt;
|2= {{cite web&lt;br /&gt;
  | url    = http://forum.flightgear.org/viewtopic.php?p=259879#p259879&lt;br /&gt;
  | title  = &amp;lt;nowiki&amp;gt;Re: New Canvas GUI&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  | author = &amp;lt;nowiki&amp;gt;Hooray&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  | date   = Oct 7th, 2015&lt;br /&gt;
  }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== AJAX mode/testing ==&lt;br /&gt;
&lt;br /&gt;
We should probably add a dialog to store credentials that we can use for accessing the wiki, which would need to be shown after installing the script, i.e. first-time use&lt;br /&gt;
&lt;br /&gt;
* http://stackoverflow.com/questions/14594346/create-a-config-or-options-page-for-a-greasemonkey-script&lt;br /&gt;
* http://commons.oreilly.com/wiki/index.php/Greasemonkey_Hacks/Getting_Started#During_Installation&lt;br /&gt;
* https://www.safaribooksonline.com/library/view/greasemonkey-hacks/0596101651/ch01s06.html&lt;br /&gt;
&lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 12:59, 20 November 2015 (EST)&lt;br /&gt;
&lt;br /&gt;
== libraries ==&lt;br /&gt;
&lt;br /&gt;
Referring to the [[#Hosting]] section, and my comment on wanting to use additional libs (like jQuery), I am primarily thinking about using a wizard-framework (e.g. jQuery steps) and a framework for creating wikimedia editor plugins (actions):&lt;br /&gt;
&lt;br /&gt;
* http://mstratman.github.io/jQuery-Smart-Wizard/&lt;br /&gt;
* http://www.jquery-steps.com/&lt;br /&gt;
* http://www.jqueryrain.com/demo/jquery-step-form-wizard/&lt;br /&gt;
* https://www.mediawiki.org/wiki/Extension:WikiEditor&lt;br /&gt;
&lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 12:07, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== About dequoting the script's article ==&lt;br /&gt;
&lt;br /&gt;
Thanks for doing this, but I am frankly not sure if it's worth the effort - there are much more popular/important articles using tons of quotes than this one, and given the reputation of the script, having quotes in this article may actually be a useful thing to make the case for having quotes in the first place - thus, I would frankly not spend much time going through this particular article - in fact, I'd be very surprised if the greasyfork download stats showed more than 3-5 people actually downloading, and using, the script - so this is really just a niche tool, and we probably better spend our time doing other things, and reviewing other wiki articles, than the script's article - at the very least, I would suggest to retain the references to the original discussions revolving these quotes (just my 2c). --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 19:00, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
: {{done}} I've added back the quotes as references. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 02:53, 3 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Script configuration (persistence) ==&lt;br /&gt;
&lt;br /&gt;
* https://wiki.greasespot.net/GM_config&lt;br /&gt;
* https://github.com/sizzlemctwizzle/GM_config/wiki&lt;br /&gt;
* https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API&lt;br /&gt;
&lt;br /&gt;
== Work in progress ==&lt;br /&gt;
&lt;br /&gt;
We have now several more or less related development efforts going on, and the code is also growing because of that - so it seems to make sense to summarize what's been going on recently. In general, all changes were made in response to the collection of feature requests and ideas we have accumulated over time  - specifically, that means that the following roadmap is in the process of being implemented:&lt;br /&gt;
&lt;br /&gt;
* establish unit testing, and add a few self-tests, so that the script can be more easily tested, updated/reviewed in the future&lt;br /&gt;
* rework the script to more easily support other sources (think gmane)&lt;br /&gt;
* make it much easier to update modified xpath/regex expressions (i.e. provide a UI for that)&lt;br /&gt;
* support persistence for script-specific settings&lt;br /&gt;
* make it easier for people to port/maintain the script by encapsulating platform specifics&lt;br /&gt;
* support asynchronous fetching of postings (AJAX), e.g. to fetch posting titles, attachments etc&lt;br /&gt;
* prepare the groundwork for supporting template-based output formats (think newsletter, changelog, articles)&lt;br /&gt;
* review what's necessary to allow the script to update fgcquote-based quotes automagically&lt;br /&gt;
&lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 16:47, 4 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== External genetic/neural network libraries ==&lt;br /&gt;
While uploading the latest version of the script, I noticed that the Genetic and Synaptic libraries are hosted on sites not on [https://greasyfork.org/en/help/external-scripts the approved GreasyFork list]. Shall I ask them to host them? -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 13:28, 11 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
: Thanks for pointing that out, I missed that completely, because everything is working correctly here - but obviously, I rarely get to actually download/install the latest version via greasyfork. Those libs should be safe to be added to the list, i.e. they're fairly established/popular, lest I'd not be using them. For now, this is just an experiment anyway. The idea is to update the xpath/regex code to evolve if/when the underlying website (theme) changes. But if there is a problem, we could use other libs - the code is just used for testing ATM. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 13:41, 11 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
* https://github.com/subprotocol/genetic-js&lt;br /&gt;
* https://github.com/cazala/synaptic&lt;br /&gt;
&lt;br /&gt;
:: {{ongoing}} I have submitted the libraries to the JSDelivr CDN; once they are up, I'll change the source URLs in the script and update it on GreasyFork as well. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 18:32, 17 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
::: Hi Elgaton, thank you for taking care of this, it's very much appreciated ! --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 18:55, 17 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:::: You're welcome! My merge requests for the CDN were approved (this took a bit longer than expected because I had made a small mistake - I forgot to include a file required by the Genetic.js library). The libraries should be up in a day or two, at which point I'll update the URLs in the script and submit the new version to GreasyFork. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 02:59, 20 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
::::: {{done}} Everything should be fine now. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 09:16, 20 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Genetic Expression solver ==&lt;br /&gt;
[[File:Instant-cquotes-genetic-regex-solving.png|thumb|Screenshot showing the instant cquotes script with integrated regex solving support using genetic algorithms.]]&lt;br /&gt;
&lt;br /&gt;
The genetic-js framework has been integrated, it is intended to help solve xpath/regex expressions procedurally using genetic algorithms/programming. &lt;br /&gt;
&lt;br /&gt;
The idea is to provide a set of desired outputs (needles), available input data (haystack), and use existing (possibly outdated) regex/xpath expressions to seed a pool with potential solutions for retrieving the desired output. For now, this is just proof-of-concept, i.e. just an experiment.&lt;br /&gt;
&lt;br /&gt;
For example, let's consider the typical format of a from header for any sourceforge posting:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var regexTests = [&lt;br /&gt;
  {haystack: &amp;quot;From: John Doe &amp;lt;John@do...&amp;gt; - 2020-07-02 17:36:03&amp;quot;, needle: &amp;quot;John Doe&amp;quot;}, &lt;br /&gt;
  {haystack: &amp;quot;From: Marc Twain &amp;lt;Marc@ta...&amp;gt; - 2010-01-03 07:36:03&amp;quot;, needle: &amp;quot;Marc Twain&amp;quot;},&lt;br /&gt;
  {haystack: &amp;quot;From: George W. Bush &amp;lt;GWB@wh...&amp;gt; - 2055-11-11 17:33:13&amp;quot;, needle: &amp;quot;George W. Bush&amp;quot;}&lt;br /&gt;
];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The basic idea is to run a fitness function and score regex expressions based on not throwing an exception (which makes them valid), and by checking if the desired tokens are part of the output string, and evolve (mutate/cross-over) the &amp;quot;fittest&amp;quot; expressions - i.e. those that satisfy at least /some/ of the heuristics.&lt;br /&gt;
&lt;br /&gt;
Some of the metrics that can be used by the fitness function to determine if an expression is &amp;quot;fit&amp;quot;, are:&lt;br /&gt;
* valid expression&lt;br /&gt;
* relative offset/excess bytes in matches string&lt;br /&gt;
* number of examples it can successfully extract&lt;br /&gt;
* length of the expression&lt;br /&gt;
* runtime of the expression&lt;br /&gt;
&lt;br /&gt;
The search space, and runtime, can be significantly reduced by looking at similarities between all examples and coming up with a subset string that contains all identical components (e.g. the &amp;lt;code&amp;gt;From:&amp;lt;/code&amp;gt; part in the author regex) and use that for seeding the initial generations.&lt;br /&gt;
&lt;br /&gt;
Ultimately, this would allow the script to self-update its regex/xpath expressions if/when the underlying website (themes) change, but it would also allow to add support for new websites, without ever manually adding the required xpath/regex expressions, i.e. all that is needed is a sufficiently large number of example datasets to obtain the author, date and title information, and a URL for the script to download the HTML markup of the posting in question:&lt;br /&gt;
&lt;br /&gt;
{{Note|The date field won't work as is, because it's actually post-processed using a transformation function, so we'd need to undo the transformation or use the actual date string instead}}&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt; // vector with tests to be executed for sanity checks (unit testing)&lt;br /&gt;
    tests: [&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://sourceforge.net/p/flightgear/mailman/message/35059454/',&lt;br /&gt;
        author: 'Erik Hofman',&lt;br /&gt;
        date: 'May 3rd, 2016', // NOTE: using the transformed date here &lt;br /&gt;
        title: 'Re: [Flightgear-devel] Auto altimeter setting at startup (?)'&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://sourceforge.net/p/flightgear/mailman/message/35059961/',&lt;br /&gt;
        author: 'Ludovic Brenta',&lt;br /&gt;
        date: 'May 3rd, 2016',&lt;br /&gt;
        title: 'Re: [Flightgear-devel] dual-control-tools and the limit on packet size'&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://sourceforge.net/p/flightgear/mailman/message/20014126/',&lt;br /&gt;
        author: 'Tim Moore',&lt;br /&gt;
        date: 'Aug 4th, 2008',&lt;br /&gt;
        title: 'Re: [Flightgear-devel] Cockpit displays (rendering, modelling)'&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://sourceforge.net/p/flightgear/mailman/message/23518343/',&lt;br /&gt;
        author: 'Tim Moore',&lt;br /&gt;
        date: 'Sep 10th, 2009',&lt;br /&gt;
        title: '[Flightgear-devel] Atmosphere patch from John Denker'&lt;br /&gt;
      } // add other tests below&lt;br /&gt;
&lt;br /&gt;
    ], // end of vector with self-tests&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note how this no longer contains any hard-coded xpath/regex expressions - instead, the script can refer to the website specific defaults, and try those first, and if they fail, use those to seed new generations and evolve them procedurally until all tests succeed.&lt;br /&gt;
&lt;br /&gt;
For a regex to be valid, it must work for all tests/examples.&lt;br /&gt;
&lt;br /&gt;
Once the regex solver is working correctly, the code can be further generalized to also evolve xpath expressions (NOTE: the DOMParser API is /not/ available to webworkers ...) and chain those two components together.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* http://regex.inginf.units.it/how.html&lt;br /&gt;
* http://www.i-programmer.info/programming/perl/9503-automatically-generating-regular-expressions-with-genetic-programming.html&lt;br /&gt;
* http://jkff.info/articles/ire/&lt;br /&gt;
* http://www.networkworld.com/article/2955126/software/genetic-programming-meets-regular-expressions.html&lt;br /&gt;
* https://handcraftsman.wordpress.com/2012/04/11/evolving-a-regular-expression-with-go/&lt;br /&gt;
* http://stackoverflow.com/questions/4880402/how-to-auto-generate-regex-from-given-list-of-strings&lt;br /&gt;
* http://regex.inginf.units.it/&lt;br /&gt;
* http://www.genetic-programming.org/hc2014/Bartoli-Paper.pdf&lt;br /&gt;
&lt;br /&gt;
== Hierarchical Clustering  ==&lt;br /&gt;
&lt;br /&gt;
Been tinkering with a JavaScript module to automatically cluster postings based on certain keywords in the topic/title or posting (e.g. Nasal, Canvas, 2D API, rendering): https://harthur.github.io/clusterfck/&lt;br /&gt;
&lt;br /&gt;
Note that in conjunction with processing article sections and/or whole articles, this could help automatically come up with matching postings for articles and vice versa.&lt;br /&gt;
&lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 18:11, 19 May 2016 (EDT)&lt;/div&gt;</summary>
		<author><name>Elgaton</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=FlightGear_wiki:Instant-Refs&amp;diff=98426</id>
		<title>FlightGear wiki:Instant-Refs</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=FlightGear_wiki:Instant-Refs&amp;diff=98426"/>
		<updated>2016-05-20T13:12:39Z</updated>

		<summary type="html">&lt;p&gt;Elgaton: /* The script */ The date should be bumped as well&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Quotes-logo-200x200.png|thumb]]&lt;br /&gt;
[[File:Instant-cquotes-firefox.png|thumb|Instant-Cquotes script in Firefox]]&lt;br /&gt;
&lt;br /&gt;
[[File:Ref-only-quotes.png|thumb|Instant-Cquotes screenshot prototyping runtime format selection]]&lt;br /&gt;
&lt;br /&gt;
The '''Instant-Cquotes''' script is a browser addon (user script) implemented in JavaScript in order to convert excerpts (created via copy&amp;amp;paste) from FlightGear forum or [[mailing list]] postings into MediaWiki markup/quotes to be used on the FlightGear wiki. It is supported by Firefox, Google Chrome/Chromium, Opera and Safari. It is being developed and maintained by a group of volunteers involved in maintaining the wiki and in trying to provide more up-to-date information to end-users who may not be as involved in the various FlightGear-related communication channels.&lt;br /&gt;
&lt;br /&gt;
== Background and motivation ==&lt;br /&gt;
FlightGear's development is, at best, &amp;quot;self-coordinated&amp;quot;, meaning that contributors discuss ideas and make proposals to contribute in a certain fashion and then team up to implement certain features and building blocks, often just temporarily.&lt;br /&gt;
&lt;br /&gt;
Unfortunately, due to a lack of development manpower, many ideas are not implemented immediately; it is, thus, important to know their pros and cons, as well as who originally proposed them and/or might help with their implementation, even after a long time, preferably with links to the original discussions so that new contributors can decide whether to get involved in some effort or not. The project documentation, however, is in great need of improvement&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
| url    = http://sourceforge.net/p/flightgear/mailman/message/15444440/&lt;br /&gt;
| title  = &amp;lt;nowiki&amp;gt;[Flightgear-devel] development process (was:  chaos...)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| author = &amp;lt;nowiki&amp;gt;John Denker&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| date   = Jul 16th, 2007&lt;br /&gt;
| added   = Jul 16th, 2007&lt;br /&gt;
| script_version = 0.23&lt;br /&gt;
}}&amp;lt;/ref&amp;gt; and usually significantly lacking behind:&amp;lt;ref name=&amp;quot;OlsonStateThingsFG&amp;quot;&amp;gt;{{cite web&lt;br /&gt;
| url    = http://sourceforge.net/p/flightgear/mailman/message/27861667/&lt;br /&gt;
| title  = &amp;lt;nowiki&amp;gt;Re: [Flightgear-devel] The state of things in Flight Gear&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| author = &amp;lt;nowiki&amp;gt;Curtis Olson&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| date   = Jul 27th, 2011&lt;br /&gt;
| added   = Jul 27th, 2011&lt;br /&gt;
| script_version = 0.23&lt;br /&gt;
}}&amp;lt;/ref&amp;gt; many core developers update it seldomly, if not anymore, as it takes time to write it, as well as an understanding of the inner workings of a complex system such as FlightGear. Furthermore, this task might not be attractive due to its short term impact on the project,&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
| url    = http://sourceforge.net/p/flightgear/mailman/message/27861562/&lt;br /&gt;
| title  = &amp;lt;nowiki&amp;gt;Re: [Flightgear-devel] The state of things in Flight Gear&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| author = &amp;lt;nowiki&amp;gt;Hal V. Engel&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| date   = Jul 27th, 2011&lt;br /&gt;
| added   = Jul 27th, 2011&lt;br /&gt;
| script_version = 0.23&lt;br /&gt;
}}&amp;lt;/ref&amp;gt; and it is overwhelming to think about creating documentation that would address the needs of many different kinds of contributors with different backgrounds, experience levels and goals.&amp;lt;ref name=&amp;quot;OlsonStateThingsFG&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Forum and mailing lists discussions have therefore become the only up-to-date (albeit difficult to filter)&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
| url    = http://forum.flightgear.org/viewtopic.php?p=280058#p280058&lt;br /&gt;
| title  = &amp;lt;nowiki&amp;gt;Re: quoting on the wiki&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| author = &amp;lt;nowiki&amp;gt;Thorsten&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| date   = Mar 21st, 2016&lt;br /&gt;
| added   = Mar 21st, 2016&lt;br /&gt;
| script_version = 0.25&lt;br /&gt;
}}&amp;lt;/ref&amp;gt; source of information about recent development progress; this makes it tricky to know what is going on, what needs fixing, what were the decisions taken by the developers.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
| url    = https://www.mail-archive.com/flightgear-devel%40lists.sourceforge.net/msg17198.html&lt;br /&gt;
| title  = &amp;lt;nowiki&amp;gt;[Flightgear-devel] Project tracking&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| author = &amp;lt;nowiki&amp;gt;James Turner&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| date   = Mon, 28 Jul 2008 10:06:05 -0700&lt;br /&gt;
}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The aim of the Instant-Cquotes script is to help wiki editors to copy relevant excerpts from such sources, formatting them as proper [[Template:Cquote|quotations]], and bootstrap new articles collecting them until a dedicated rewrite is made. It can also be used to reuse announcements to update the changelogs, [[Next newsletter|newsletter]] or the [[Release plan/Lessons learned]] page.&lt;br /&gt;
&lt;br /&gt;
After being away from the wiki system for some time it becomes more of an effort to re-learn how to start a new file and figure out how to format it , with what headings, etc. Sometimes it is almost too much to do the original write up of the original post and all the work of that layout and effort to have to also duplicate it in a wiki article. If I was a little more current and affluent with the wiki editor, I might not be so hesitant to create the work there instead of the forum.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=284698#p284698 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Breaking down NLCD raster image &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; wlbragg &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  May 9th, 2016 &lt;br /&gt;
  |added  =  May 9th, 2016 &lt;br /&gt;
  |script_version = 0.38 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In a few cases, such collections of quotes helped not only create bootstrap new articles, but even actual features.&lt;br /&gt;
&lt;br /&gt;
In other cases, quotes have been used to update documentation of features (e.g. [[Rembrandt]]) whose maintainers may not be actively involved in FlightGear, to help document discussions that are taking place in the meantime, and provide some background information for people interested in the corresponding feature.&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
# Install a user script manager. On Firefox, you can use [https://addons.mozilla.org/en-US/firefox/addon/greasemonkey/ Greasemonkey]; on Chrome/Chromium, Opera or Safari, you can use [https://tampermonkey.net/ Tampermonkey] (download links: [https://tampermonkey.net/index.php?ext=dhdg&amp;amp;browser=chrome Chrome/Chromium], [https://tampermonkey.net/index.php?ext=dhdg&amp;amp;browser=opera Opera], [https://tampermonkey.net/index.php?ext=dhdg&amp;amp;browser=safari Safari]).&lt;br /&gt;
# Visit [https://greasyfork.org/en/scripts/19331-instant-cquotes the Instant-Cquotes page on GreasyFork] and click on {{button|Install this script}} (green button). If Greasemonkey/Tampermonkey prompts you to confirm the installation, agree to do so.&lt;br /&gt;
&lt;br /&gt;
[[File:Howto-install-instant-cquotes.png|thumb|Click the green button to install the script]]&lt;br /&gt;
&lt;br /&gt;
=== Manual installation ===&lt;br /&gt;
{{note|This will install the most recent development version of the script, which might contain bugs. Also, GreaseMonkey/TamperMonkey will not update it automatically whenever a new version is released.}}&lt;br /&gt;
&lt;br /&gt;
* '''Firefox'''&lt;br /&gt;
# Install Greasemonkey.&lt;br /&gt;
# Save [[#The Script|the script]] below as &amp;lt;code&amp;gt;instant_cquotes.user.js&amp;lt;/code&amp;gt;, then drag-and-drop it into Firefox.&lt;br /&gt;
[[File:Greasemonkey-setup-on-firefox.png|thumb|Screenshot showing the Greasemonkey setup dialog (on Firefox)]]&lt;br /&gt;
&lt;br /&gt;
* '''Chrome/Chromium''', '''Opera''', or '''Safari'''&lt;br /&gt;
# Install Tampermonkey.&lt;br /&gt;
# Navigate to '''Add a new Script'''.&lt;br /&gt;
# Copy and paste [[#The Script|the script]] below into the editing window.&lt;br /&gt;
# Click the {{button|Save}} button (just above the {{button|Search}} button).&lt;br /&gt;
&lt;br /&gt;
=== Mobile installation ===&lt;br /&gt;
As of May 2016, there is no separate version available for mobile use. Your best chance is installing a userscript addon on Android, like one of those:&lt;br /&gt;
* [https://play.google.com/store/apps/details?id=net.biniok.tampermonkey Tampermonkey (Google Play Store)]&lt;br /&gt;
* [http://oilcan.jsharkey.org/ OilCan: Greasemonkey on steroids for Android]&lt;br /&gt;
&lt;br /&gt;
For installation instructions, refer to [https://openuserjs.org/about/Tampermonkey-for-Android Tampermonkey for Android] or [http://www.blogtechnika.com/how-to-access-greasemonkey-scripts-on-android-phones/ How To Access Greasemonkey Scripts on Android Phones].&lt;br /&gt;
&lt;br /&gt;
Testing/feedback would obviously be appreciated - if in doubt, feel free to just edit the wiki page to add your findings/questions.&lt;br /&gt;
&lt;br /&gt;
=== Configuration ===&lt;br /&gt;
[[File:User-script-menu.png|thumb|GreaseMonkey menu shown in FireFox with instanct cquotes menu items]]&lt;br /&gt;
&lt;br /&gt;
[[File:Config-dialog-instant-cquotes.png|thumb|The configuration dialog for the Instant-Cquotes script]]&lt;br /&gt;
&lt;br /&gt;
As of version 0.30, a dedicated configuration dialog is in the process of being added, so that certain script features can be dynamically configured, without having to edit the script. For now, this is merely a placeholder that provides a checkbox to easily enable/disable the debug mode. In the future, we are hoping to also expose other features this way.&lt;br /&gt;
&lt;br /&gt;
== Usage ==&lt;br /&gt;
[[File:Updated-cquotes-script-by-redleader.png|thumb|Instant-Cquotes script, with updates contributed by Red Leader]]&lt;br /&gt;
&lt;br /&gt;
[[File:New-cquotes.png|thumb|Screenshot showing Instant-Cquotes 0.30 at work]]&lt;br /&gt;
&lt;br /&gt;
# Go to some [[mailing list]] archive URL, for example [http://sourceforge.net/p/flightgear/mailman/message/32400727/] or any forum message, such as {{forumref|title=Re: Get objects to show up on Map/Radar|t=23299|label=p212558|f=71}}.&lt;br /&gt;
# Select the relevant portion of text.&lt;br /&gt;
# When you release the mouse button, a box will appear containing the converted text (for now, mainly properly-referenced quotes for the wiki).&lt;br /&gt;
# The text will be automatically selected and copied to the clipboard.&lt;br /&gt;
# Paste the text into the desired wiki page.&lt;br /&gt;
&lt;br /&gt;
For example, by selecting part of the forum post in the link above you can get the following quotation:&lt;br /&gt;
&lt;br /&gt;
{{FGCquote&lt;br /&gt;
|1= The upcoming FlightGear version (3.2) will contain a canvas-based map dialog, including a modular &amp;quot;plugin&amp;quot; system for creating custom map layers and charts with roughly ~50 lines of code, most of it boilerplate. &lt;br /&gt;
This is entirely XML/Nasal based (scripted) - symbols can be pretty much anything, raster or vector images (png or svg), but even animated. Styling can be customied, too.&lt;br /&gt;
For more info, I suggest to check out:&lt;br /&gt;
[[MapStructure#Porting the map dialog]]&lt;br /&gt;
&lt;br /&gt;
[[File:MapStructureDialog.png|250px]]&lt;br /&gt;
|2= {{cite web&lt;br /&gt;
  | url    = http://forum.flightgear.org/viewtopic.php?p=212558#p212558&lt;br /&gt;
  | title  = &amp;lt;nowiki&amp;gt;Re: Get objects to show up on Map/Radar&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  | author = &amp;lt;nowiki&amp;gt;Hooray&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  | date   = Jun 14th, 2014&lt;br /&gt;
  }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== On quoting ===&lt;br /&gt;
{{Main article|FlightGear wiki:Quoting Guidelines}}&lt;br /&gt;
&lt;br /&gt;
Using the Instant-Cquotes script is a good way to bootstrap and write some preliminary notes; however, while quotes might be useful to understand how undocumented subsystems and features work and are definitely better than nothing, they are not meant to replace proper, structured and well-written wiki articles.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
| url    = http://forum.flightgear.org/viewtopic.php?p=282800#p282800&lt;br /&gt;
| title  = &amp;lt;nowiki&amp;gt;Re: What is the QT launcher?&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| author = &amp;lt;nowiki&amp;gt;bugman&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| date   = Apr 17th, 2016&lt;br /&gt;
| added   = Apr 17th, 2016&lt;br /&gt;
| script_version = 0.25&lt;br /&gt;
}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One way to convert pages bootstrapped using quotes is to extract relevant information from them and keep citations only as references; in case important details are missing, they can be asked for on the [[Mailing lists|mailing lists]] (on the forum, the chance to get a complete answer might be lower).&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
| url    = http://sourceforge.net/p/flightgear/mailman/message/34954385/&lt;br /&gt;
| title  = &amp;lt;nowiki&amp;gt;Re: [Flightgear-devel] Wiki Quotes&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| author = &amp;lt;nowiki&amp;gt;James Turner&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| date   = Mar 21st, 2016&lt;br /&gt;
| added   = Mar 21st, 2016&lt;br /&gt;
| script_version = 0.25&lt;br /&gt;
}}&amp;lt;/ref&amp;gt; Another option might be moving the quotes to the Talk page for each entry, which would preserve the sources without clogging up the articles.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
| url    = http://sourceforge.net/p/flightgear/mailman/message/34948989/&lt;br /&gt;
| title  = &amp;lt;nowiki&amp;gt;Re: [Flightgear-devel] Wiki Quotes&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| author = &amp;lt;nowiki&amp;gt;Stuart Buchanan&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| date   = Mar 19th, 2016&lt;br /&gt;
| added   = Mar 19th, 2016&lt;br /&gt;
| script_version = 0.25&lt;br /&gt;
}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As a matter of fact, the whole paragraph above was assembled using this approach; to see for yourself, look up the references at the end of this page. For another example, see [[TerraSync#News]].&lt;br /&gt;
&lt;br /&gt;
== Development ==&lt;br /&gt;
{{Note|A Chrome/Chromium-specific extension that will not need Tampermonkey installed is under development.}}&lt;br /&gt;
&lt;br /&gt;
=== Resources ===&lt;br /&gt;
* https://www.mediawiki.org/wiki/API:Changing_wiki_content&lt;br /&gt;
* https://www.mediawiki.org/wiki/API:Edit&lt;br /&gt;
&lt;br /&gt;
=== Adding sources ===&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
{{WIP}}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
Adding a new source is pretty straightforward if you understand how xpath and regexes work - basically, you only need an archive (e.g. gmane), and then determine the xpath of each relevant field, as well as the regular expression to process the extracted fields (optional).&lt;br /&gt;
&lt;br /&gt;
The basic steps are these:&lt;br /&gt;
# open the user script in an editor&lt;br /&gt;
# navigate to the meta header of the user script&lt;br /&gt;
# add a new URL to the top of the script, e.g. by copying/adapting an existing line like this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// @match       https://sourceforge.net/p/flightgear/mailman/*&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once copied, add the new URL:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// @match       http://thread.gmane.org/gmane.games.flightgear.devel/*&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next, you need to navigate to the configuration hash to add a new website to it. &lt;br /&gt;
&lt;br /&gt;
Again, it makes sense to simply take an existing configuration hash and adapt it as needed (ignore/omit the tests vector for now by keeping it empty):&lt;br /&gt;
&lt;br /&gt;
{{Caution|the following example may meanwhile be outdated, so be sure to look at the actual code instead}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  'Sourceforge Mailing list': {&lt;br /&gt;
    enabled: true,&lt;br /&gt;
    type: 'archive',&lt;br /&gt;
    event: 'document.onmouseup', // when to invoke the event handler&lt;br /&gt;
    event_handler: instantCquote, // the event handler to be invoked&lt;br /&gt;
    url_reg: '^(http|https)://sourceforge.net/p/flightgear/mailman/.*/',&lt;br /&gt;
    content: {&lt;br /&gt;
      xpath: 'tbody/tr[2]/td/pre/text()',&lt;br /&gt;
      selection: getSelectedText,&lt;br /&gt;
      idStyle: /msg[0-9]{8}/,&lt;br /&gt;
      parentTag: [&lt;br /&gt;
        'tagName',&lt;br /&gt;
        'PRE'&lt;br /&gt;
      ],&lt;br /&gt;
    transform: [] // vector with transformation callbacks&lt;br /&gt;
    }, // content recipe&lt;br /&gt;
    // vector with tests to be executed for sanity checks (unit testing)&lt;br /&gt;
    tests: [&lt;br /&gt;
    ], // end of vector with self-tests&lt;br /&gt;
    // regex/xpath and transformations for extracting various required fields&lt;br /&gt;
    author: {&lt;br /&gt;
      xpath: 'tbody/tr[1]/td/div/small/text()',&lt;br /&gt;
      transform: [extract(/From: (.*) &amp;lt;.*@.*&amp;gt;/)]&lt;br /&gt;
    },&lt;br /&gt;
    title: {&lt;br /&gt;
      xpath: 'tbody/tr[1]/td/div/div[1]/b/a/text()'&lt;br /&gt;
      transform: []&lt;br /&gt;
    },&lt;br /&gt;
    date: {&lt;br /&gt;
      xpath: 'tbody/tr[1]/td/div/small/text()',&lt;br /&gt;
      transform: [extract(/- (.*-.*-.*) /)]&lt;br /&gt;
    },&lt;br /&gt;
    url: {&lt;br /&gt;
      xpath: 'tbody/tr[1]/td/div/div[1]/b/a/@href',&lt;br /&gt;
      transform: [prepend('https://sourceforge.net')]&lt;br /&gt;
    }&lt;br /&gt;
  }, // end of mailing list profile&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, we need to review/adapt the profile according to the new archive we'd like to see supported. &lt;br /&gt;
&lt;br /&gt;
for starters, that means:&lt;br /&gt;
* changing the name of the profile, e.g. to read gmane (instead of sourceforge)&lt;br /&gt;
* change the '''url_reg''' field to the gmane URL (this can be a regular expression)&lt;br /&gt;
&lt;br /&gt;
Next, it makes sense to use an [https://addons.mozilla.org/de/firefox/addon/xpath-checker/ XPath checker], so that we can look up the xpath expression for various HTML elements, and add those to the configuration hash above.&lt;br /&gt;
&lt;br /&gt;
For testing purposes, you will probably go to the setup dialog and enable the DEBUG mode, and use your browser's console to see what is going on.&lt;br /&gt;
&lt;br /&gt;
=== Getting involved ===&lt;br /&gt;
While having some experience with JavaScript/HTML and jQuery will definitely be useful, JavaScript is close enough to FlightGear scripting ([[Nasal]]), so that people can get involved pretty easily. &lt;br /&gt;
&lt;br /&gt;
Most maintenance work will typically involve reviewing/maintaining a few configuration hashes, that contain meta information for each supported archive (mailing list/forum).&lt;br /&gt;
&lt;br /&gt;
Usually, each hash contains a combination of xpath/regex expressions to look up the relevant information, as well as vector of optional transformations that are applied (in order) to convert contents to a different format (e.g. dates).&lt;br /&gt;
&lt;br /&gt;
In addition, there is growing library of utility functions, a handful wrappers for useful stuff, for example:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;Host.dbLog(message_string)&amp;lt;/code&amp;gt; - log a message to the console if the DEBUG flag is set&lt;br /&gt;
* &amp;lt;code&amp;gt;Host.download(url, callback, method='GET')&amp;lt;/code&amp;gt; - will download the URL and pass the downloaded content to the callback specified&lt;br /&gt;
* &amp;lt;code&amp;gt;Host.downloadPosting(url, callback)&amp;lt;/code&amp;gt; - will download the posting URL and pass the extracted and transformed author/content and date fields in a hash to the callback specified, the URL must be one supported in the CONFIG hash (i.e. forum/sourceforge for now)&lt;br /&gt;
* &amp;lt;code&amp;gt;Host.make_doc(string, type=&amp;quot;text/html&amp;quot;)&amp;lt;/code&amp;gt; - will turn a string/blob into a DOM that can be queried&lt;br /&gt;
* &amp;lt;code&amp;gt;Host.eval_xpath(document, xpath_expression, type=XPathResult.STRING_TYPE)&amp;lt;/code&amp;gt; - will apply the xpath expression to the document specified, returning the requested type (defaulted to string) &lt;br /&gt;
* &amp;lt;code&amp;gt;Host.set_persistent(key,value)&amp;lt;/code&amp;gt;  - stores a key/value pair&lt;br /&gt;
* &amp;lt;code&amp;gt;Host.get_persistent(key,default_value)&amp;lt;/code&amp;gt; - retrieves a values using the key specified, falling back to the default value&lt;br /&gt;
&lt;br /&gt;
=== Porting ===&lt;br /&gt;
[[File:Instant-cquote-firefox-addon-mode.png|thumb|Prototyping a dedicated instant-cquote mode for use as a firefox addon]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Porting the script to support other browsers/script engines is greatly appreciated. Typically, this should be pretty self-contained, because all main APIs are intended to be encapsulated in a so called &amp;quot;Environment&amp;quot; hash, where APIs that are specific to a particular browser/script engine should be provided with a wrapper. As of mid 2016, most APIs are now kept inside such an Environment hash (look at the GreaseMonkey hash for reference/details), so that it is now even possible to turn the script into a standalone FireFox addon without having to change much of the underlying code.&lt;br /&gt;
&lt;br /&gt;
=== Self checks (unit testing) ===&lt;br /&gt;
For regression testing purposes, there's a dedicated &amp;quot;self check&amp;quot; dialog that will be extended over time. For now it will download a few profile/website specific postings using a vector called &amp;quot;tests&amp;quot; and then log the posting's title, author and date to the console.&lt;br /&gt;
&lt;br /&gt;
The next step will be  actually showing that information in the dialog itself - there's a separate helper function to accomplish that, so that the corresponding div layer can be updated with the results.&lt;br /&gt;
&lt;br /&gt;
[[File:Sanity-check-cquotes-dialog.png|thumb|automatically executed sanity checks]]&lt;br /&gt;
&lt;br /&gt;
=== Debug mode ===&lt;br /&gt;
[[File:Instant-cquotes-debug-mode.png|thumb|Instant-Cquotes debug mode]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== AJAX (live page editing) ===&lt;br /&gt;
{{WIP}}&lt;br /&gt;
&lt;br /&gt;
* http://wiki.flightgear.org/api.php&lt;br /&gt;
* http://wiki.flightgear.org/api.php?action=parse&amp;amp;page=Frequently%20asked%20questions&amp;amp;prop=sections&lt;br /&gt;
&lt;br /&gt;
For now, the setup dialog will try to obtain a login token for the wiki and show a message if successful.&lt;br /&gt;
&lt;br /&gt;
In addition, the profile/website hash also contains a new wiki entry for the FlightGear wiki, whose '''event_handler''' callback will be invoked once the FG wiki is visited - the console/log will show a greeting, so that is where other code can be added - e.g. to help clean up/rewrite FGCquote-based articles automatically etc.&lt;br /&gt;
&lt;br /&gt;
There is a vector of &amp;quot;modes&amp;quot;, whose members are a hash containing trigger/handler fields, linked to two callbacks - the trigger callback can be used to check some condition, while the handler will be invoked if the trigger returns true.&lt;br /&gt;
&lt;br /&gt;
This can be used to support an arbitrary number of modes, whose triggers are evaluated during page load - all triggers that return true, will have their handlers invoked, which is how the following snippet works to rewrite/augment wiki edit handles:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;gt;&lt;br /&gt;
 'FlightGear.wiki': {&lt;br /&gt;
    type: 'wiki',&lt;br /&gt;
    enabled: false,&lt;br /&gt;
    event: 'document.onmouseup', // when to invoke the event handler&lt;br /&gt;
    event_handler: function () {&lt;br /&gt;
      console.log('FlightGear wiki handler active (waiting to be populated)');&lt;br /&gt;
      // this is where the logic for a wiki mode can be added over time (for now, it's a NOP)&lt;br /&gt;
    &lt;br /&gt;
    //for each supported mode, invoke the trigger and call the corresponding handler&lt;br /&gt;
    [].forEach.call(CONFIG['FlightGear.wiki'].modes, function(mode) {&lt;br /&gt;
      //dbLog(&amp;quot;Checking trigger:&amp;quot;+mode.name);&lt;br /&gt;
      if(mode.trigger) {&lt;br /&gt;
        mode.handler();&lt;br /&gt;
      }&lt;br /&gt;
    });&lt;br /&gt;
      &lt;br /&gt;
    }, // the event handler to be invoked&lt;br /&gt;
    url_reg: '^(http|https)://wiki.flightgear.org', // ignore for now: not currently used by the wiki mode&lt;br /&gt;
    &lt;br /&gt;
    modes: [&lt;br /&gt;
      { name:'process-editSections',&lt;br /&gt;
        trigger: function() {return true;}, // match URL regex - return true for always match&lt;br /&gt;
       &lt;br /&gt;
        // the code implementing the mode&lt;br /&gt;
        handler: function() {&lt;br /&gt;
                &lt;br /&gt;
    var editSections = document.getElementsByClassName('mw-editsection');&lt;br /&gt;
    console.log('FlightGear wiki article, number of edit sections: '+editSections.length);&lt;br /&gt;
   &lt;br /&gt;
    // for now, just rewrite edit sections and add a note to them&lt;br /&gt;
   &lt;br /&gt;
     [].forEach.call(editSections, function (sec) {&lt;br /&gt;
       sec.appendChild(&lt;br /&gt;
         document.createTextNode(' (instant-cquotes is lurking) ')&lt;br /&gt;
       );&lt;br /&gt;
     }); //forEach section&lt;br /&gt;
        } // handler&lt;br /&gt;
       &lt;br /&gt;
       &lt;br /&gt;
      } // process-editSections&lt;br /&gt;
      // TODO: add other wiki modes below &lt;br /&gt;
      &lt;br /&gt;
    ] // modes&lt;br /&gt;
    &lt;br /&gt;
  }, // end of wiki profile&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See [[User:Red Leader/Sandbox/AJAX test]]&lt;br /&gt;
&lt;br /&gt;
* https://www.mediawiki.org/wiki/API:Changing_wiki_content&lt;br /&gt;
* https://www.mediawiki.org/wiki/Extension:VisualEditor&lt;br /&gt;
* https://en.wikipedia.org/wiki/Wikipedia:Creating_a_bot&lt;br /&gt;
&lt;br /&gt;
=== Mobile edition ===&lt;br /&gt;
{{Note|As of 02/2016, Hooray is contemplating to make this available as an addon for Android phones.}}&lt;br /&gt;
&lt;br /&gt;
=== Issues/limitations ===&lt;br /&gt;
==== Bugs ====&lt;br /&gt;
* It's eating characters, apparently related to regex/xpath handling - e.g. words like &amp;quot;analyzing&amp;quot; are turned into &amp;quot;analying&amp;quot; [http://forum.flightgear.org/viewtopic.php?f=6&amp;amp;t=28378&amp;amp;p=270735&amp;amp;hilit=analyzing#p270735]&lt;br /&gt;
==== Non working URLs ====&lt;br /&gt;
* image matching/extraction: http://forum.flightgear.org/viewtopic.php?p=276221#p276221&lt;br /&gt;
* http://sourceforge.net/p/flightgear/mailman/message/34754961/&lt;br /&gt;
* http://forum.flightgear.org/viewtopic.php?f=18&amp;amp;t=27054&amp;amp;start=90#p273972 → selecting from “As promised, two sample installation sessions on Linux” to “That's it.” towards the end of the message causes Iceweasel (Firefox) 44.0.2 to display a dialog box reading “A script on this page may be busy, or it may have stopped responding. You can stop the script now, open the script in the debugger, or let the script continue.” The line below reads “Script: chrome://greasemonkey-modules/...quotes/instant_cquotes.user.js:544”. Choosing ''Continue'' doesn't help: the same message reappears a few seconds afterwards.&lt;br /&gt;
&lt;br /&gt;
=== Feature requests &amp;amp; ideas ===&lt;br /&gt;
* try to recognize list items [https://sourceforge.net/p/flightgear/mailman/message/35095319/] (heuristics: look for colon/asterisk, dashes and CR/LF)&lt;br /&gt;
* should add [[Template:News]] to the article dropdown for announcements [http://wiki.flightgear.org/index.php?title=Template:News&amp;amp;oldid=98266]&lt;br /&gt;
* add a mode that will download screenshots from forum postings and automatically upload/categorize them, see [[Birds]]&lt;br /&gt;
* split the article dropdown into sections, and also populate it with the user's watchlist [https://www.mediawiki.org/wiki/API:Watchlist] {{Progressbar|60}}&lt;br /&gt;
* mailing list templates, listed at [http://wiki.flightgear.org/Template_talk:Project_infrastructure#Related_mailing_list_templates]&lt;br /&gt;
* expose the cquote/ref markup via the UI so that it can be edited/customized and treated like a template {{Done}} (0.36+)&lt;br /&gt;
* identify common/repeated links and automatically create [[Template:Project infrastructure|link/infrastructure templates]] and use those (should be straightforward using the AJAX mode) [http://wiki.flightgear.org/index.php?title=Mailing_lists&amp;amp;curid=2038&amp;amp;diff=97876&amp;amp;oldid=85252]&lt;br /&gt;
* add a devel/maintainer mode where it will return the xpath for a selection [http://stackoverflow.com/questions/361130/get-selected-text-and-selected-nodes-on-a-page] [http://stackoverflow.com/questions/12485334/get-surrounding-dom-node-of-selection]&lt;br /&gt;
* move openlink,dblog helpers to Environment hash {{Done}}&lt;br /&gt;
* identify CLI arguments like --aircraft=c172p and wrap them in between code tags &amp;lt;code&amp;gt;--aircraft=c172p&amp;lt;/code&amp;gt; [https://sourceforge.net/p/flightgear/mailman/message/35063277/] (note that we can simply download [https://sourceforge.net/p/flightgear/fgdata/ci/next/tree/options.xml options.xml] via openlink() and use that, which is kinda of neat...) {{Progressbar|60}} (see downloadOptionsXML() in the code)&lt;br /&gt;
* introduce &amp;quot;layouts&amp;quot; (templates) for different purposes: newsletter, changelog, wiki article, [[The Manual]] (LaTex)  ? {{Progressbar|40}}&lt;br /&gt;
* use wikipedia template if possible [https://sourceforge.net/p/flightgear/mailman/message/35057670/]&lt;br /&gt;
* the new '''tests''' vector could also contain vectors for tests to test the extract/transform* utilities, see Environment.APITests {{Progressbar|50}}&lt;br /&gt;
* move environment specific APIs (browser, script host etc) into some kind of Environment hash to encapsulate things (Red Leader was working on a pure Chrome-only version at some point IIRC) {{Progressbar|80}}&lt;br /&gt;
* encode script settings in created markup, for future processing/updating of quotes&lt;br /&gt;
* look up &amp;lt;code&amp;gt;[x]&amp;lt;/code&amp;gt; references and replace with the corresponding link (titled) [https://sourceforge.net/p/flightgear/mailman/message/35055331/] [https://sourceforge.net/p/flightgear/mailman/message/35062598/]&lt;br /&gt;
** convert footnotes into Abbr templates [http://article.gmane.org/gmane.games.flightgear.devel/78971]&lt;br /&gt;
* support named refs for combining identical refs [http://wiki.flightgear.org/index.php?title=FlightGear_Qt_launcher&amp;amp;curid=13693&amp;amp;diff=97562&amp;amp;oldid=97551]&lt;br /&gt;
* adopt [[Template:Forumref]]&lt;br /&gt;
* implement a less obnoxious quoting mode, without quotes, where only the ref part would be added, e.g. see the example at [[Graphics Card Profiles]] (it's still 99% quotes, but much less annoying) {{Done}}&lt;br /&gt;
* attachment support: identify attachments and link to them: [https://sourceforge.net/p/flightgear/mailman/message/11683451/] [https://sourceforge.net/p/flightgear/mailman/message/23906620/] [https://sourceforge.net/p/flightgear/mailman/message/35059842/] [https://sourceforge.net/p/flightgear/mailman/message/35067087/]&lt;br /&gt;
* bulletin points: if there is a colon (:) followed by at least two dashes (-), split up everything after the colon to turn each dash into an asterisk (wiki markup for bulletin points), followed by a newline [http://sourceforge.net/p/flightgear/mailman/message/34760165/]   &lt;br /&gt;
* generic URL/template matching, e.g. for for sourceforge commit IDs&lt;br /&gt;
* make filters/conversions configurable via checkboxes (nowiki, wrap in alert/note boxes)&lt;br /&gt;
* make syntax highlighting configurable (language, mode) ?&lt;br /&gt;
* consider using something like the Roles template to turn contributor names into tooltips where contributor roles are shown (core dev, fgdata committer etc)&lt;br /&gt;
* introduce support for tag clouds to help categorize/classify related quotes&lt;br /&gt;
* consider making transformations optional/configurable using check boxes in the jQuery dialog&lt;br /&gt;
* add new input method, for quotes that need to be updated/converted (added script version specifically for this purpose), should also add extraction/processing date&lt;br /&gt;
* investigate why not all mailing list archives/postings are supported correctly: http://sourceforge.net/p/flightgear/mailman/message/8090479/ (problem traced to &amp;lt;code&amp;gt;getPostID()&amp;lt;/code&amp;gt;)&lt;br /&gt;
* explore having a ref-only mode without using cquotes, i.e. just copy/paste quotes with proper ref tags and a references section, to rewrite the whole thing (possibly with templates for different purposes, e.g. newsletter/changelog) {{Done}}&lt;br /&gt;
* should use Template:Forumref (category:link templates)&lt;br /&gt;
* should be updated to use the new repo/flightgear file templates created by Johan &amp;amp; RedLeader {{Not done}}&lt;br /&gt;
* resolve links to forum threads to look up the title for the topic/posting, so that the posting's title can be used for those links, instead of just the URL - we can probably do that by making an AJAX call to open URLs asynchronously and extract the title for the thread/posting to come up with something like &amp;lt;code&amp;gt;[http://forum.flightgear.org/viewtopic.php?f=4&amp;amp;t=24421 A call to developers-Lockheed -L188 Electra]&amp;lt;/code&amp;gt; ([http://forum.flightgear.org/viewtopic.php?f=4&amp;amp;t=26562&amp;amp;p=247325&amp;amp;hilit=links#p247347]) {{Progressbar|50}}&lt;br /&gt;
* convert quoted bug tracker URLs to use the issue template on the wiki {{not done}}&lt;br /&gt;
* do regex/xpath validation, and display any errors (e.g. template/theme changes on the forum would currently break the script) {{Progressbar|60}}&lt;br /&gt;
* increased focus on supporting different output formats, maybe using a simple [http://www.jquery-steps.com/ jQuery based wizard] (wiki, forum, newsletter, changelog) {{Not done}}&lt;br /&gt;
* token matching for keywords/acronyms to link to the corresponding wiki articles (e.g. Nasal, Canvas, FG_ROOT, FG_HOME etc) {{Not done}}&lt;br /&gt;
* Add support for [http://sourceforge.net/p/flightgear/codetickets/ tickets], merge requests comments and [http://www.fguk.eu/index.php/forum/index FGUK forum]. (also see [[FlightGear wiki talk:Instant-Cquotes#more sources]])&lt;br /&gt;
* GET-encoded SID arguments should be stripped from forum URLs. {{Not done}}&lt;br /&gt;
* Links to repositories should be converted to use wiki templates. {{Not done}}&lt;br /&gt;
* The {{Abbr|regexes|regular expressions}} used may fail if the HTML DOM of the source changes (e.g., phpBB/theme update)&lt;br /&gt;
** Show a warning when that's the case. {{Progressbar|70}} (see the self-check dialog)&lt;br /&gt;
** Try multiple regexes in order. {{Progressbar|30}} (see the self-check dialog)&lt;br /&gt;
* Use the script to update previously created Cquotes automatically&lt;br /&gt;
** Instead of using the &amp;lt;code&amp;gt;getSelection()&amp;lt;/code&amp;gt; helper, we could register a match for &amp;lt;tt&amp;gt;wiki.flightgear.org&amp;lt;/tt&amp;gt; with &amp;lt;code&amp;gt;action=edit&amp;lt;/code&amp;gt; set, so that we can directly process all text of an edited page, using AJAX calls to open the URL in the background. {{Progressbar|40}} (see the self-check dialog, available via the greasemonkey menu)&lt;br /&gt;
** See [https://www.mediawiki.org/wiki/API:Edit#Editing_via_Ajax MW:API:Edit § Editing via Ajax]&lt;br /&gt;
&lt;br /&gt;
=== Changelog ===&lt;br /&gt;
{{Note|Contributors are invited to document their changes here, please also add your wiki handle so that others can more easily get in touch.}}&lt;br /&gt;
&lt;br /&gt;
* first stab at implementing unit tests by adding a vector with URLS to be downloaded and fields to be matched (WIP), shown in a jQuery dialog&lt;br /&gt;
* support for persistent settings and a jQuery setup dialog with persistence&lt;br /&gt;
* hosting is moved, to allow auto-updates [http://www.greasespot.net/2012/02/automatic-script-updates-come-to.html] [https://wiki.greasespot.net/Metadata_Block#.40updateURL] [http://stackoverflow.com/questions/15095055/why-isnt-my-greasemonkey-script-updating]&lt;br /&gt;
* changed to ref-only quotes for now, not using the FGCquote template anymore, due to its obnoxious appearance on quote-heavy pages (should probably become a runtime option instead)&lt;br /&gt;
* updated to use https for forum postings&lt;br /&gt;
* add version info to each created quote, i.e. for future updates&lt;br /&gt;
* add helper for opening websites asynchronously using AJAX (also via GM helper API)&lt;br /&gt;
* display version number in output dialog&lt;br /&gt;
* begin using the GreaseMonkey API for setting clipboard content&lt;br /&gt;
&lt;br /&gt;
== The script ==&lt;br /&gt;
&amp;lt;gallery mode=packed widths=230px heights=230px&amp;gt;&lt;br /&gt;
Instant-cquotes-revamped.png|Instant cquotes: Revamped user interface exposes script internals to make the script better configurable at runtime&lt;br /&gt;
Instant-cquotes-template-editor.png|Instant cquotes now features a simple built-in template editor with support for variable substitution, so that wiki templates can be more easily customized&lt;br /&gt;
Instant-cquotes-with-wikimedia-API-integration.png|Screenshot showing instant-cquotes with wikimedia API integration to fetch articles/sections and populate dropdown menus accordingly&lt;br /&gt;
Instant-cquotes-on-steroids-with-watchlist-support.png|Screenshot showing the JQuery-mode of the instant cquotes script with built-in support for fetching a user's wiki/watchlist to edit/update articles in a semi-automated fashion&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
{{PD-author|FlightGear contributors}}&lt;br /&gt;
&lt;br /&gt;
{{Note|Anybody interested in contributing to the code is invited to directly edit this wiki article. From 05/2016, the script is hosted on GreasyFork to allow automatic updates. If you'd like to see your changes applied, please bump the version number and the date and [[User:Elgaton|Elgaton]] will upload it in the state it was when the version number was bumped. ''Make sure to perform thorough testing'' before the bump to prevent unexpected breakage; it is generally a good idea to validate your changes using an online syntax checker, e.g.:&lt;br /&gt;
* http://jshint.com/ &lt;br /&gt;
* http://esprima.org/demo/validate.html&lt;br /&gt;
* http://codebeautify.org/jsvalidate&lt;br /&gt;
&amp;lt;p/&amp;gt;Thank you!}}&lt;br /&gt;
&lt;br /&gt;
Changes that should be mentioned in the changelog, should be added below (and moved to the [[#Changelog]] section subsequently:&lt;br /&gt;
&lt;br /&gt;
* preparations for adding support to download fgdata related files like options.xml to automatically regex known CLI commands&lt;br /&gt;
* preparatory work for adding a speech-rewrite engine to assist in converting 1st person speech to 3rd person&lt;br /&gt;
* framework for encapsulating userscript specifics in an environment hash to provide better updating/porting support&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;// ==UserScript==&lt;br /&gt;
// @name        Instant-Cquotes&lt;br /&gt;
// @name:it     Instant-Cquotes&lt;br /&gt;
// @license     public domain&lt;br /&gt;
// @version     0.39&lt;br /&gt;
// @date        2016-05-20&lt;br /&gt;
// @description Automatically converts selected FlightGear mailing list and forum quotes into post-processed MediaWiki markup (i.e. cquotes).&lt;br /&gt;
// @description:it Converte automaticamente citazioni dalla mailing list e dal forum di FlightGear in marcatori MediaWiki (cquote).&lt;br /&gt;
// @author      Hooray, bigstones, Philosopher, Red Leader &amp;amp; Elgaton (2013-2016)&lt;br /&gt;
// @supportURL  http://wiki.flightgear.org/FlightGear_wiki:Instant-Cquotes&lt;br /&gt;
// @icon        http://wiki.flightgear.org/images/2/25/Quotes-logo-200x200.png&lt;br /&gt;
// @match       https://sourceforge.net/p/flightgear/mailman/*&lt;br /&gt;
// @match       http://sourceforge.net/p/flightgear/mailman/*&lt;br /&gt;
// @match       https://forum.flightgear.org/*&lt;br /&gt;
// @match       http://wiki.flightgear.org/*&lt;br /&gt;
// @namespace   http://wiki.flightgear.org/FlightGear_wiki:Instant-Cquotes&lt;br /&gt;
// @run-at      document-start&lt;br /&gt;
// @require     https://code.jquery.com/jquery-1.10.2.js&lt;br /&gt;
// @require     https://code.jquery.com/ui/1.11.4/jquery-ui.js&lt;br /&gt;
// @require     https://cdn.jsdelivr.net/genetic.js/0.1.14/genetic.js&lt;br /&gt;
// @require     https://cdn.jsdelivr.net/synaptic/1.0.4/synaptic.min.js&lt;br /&gt;
// @resource    jQUI_CSS https://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css&lt;br /&gt;
// @resource    myLogo http://wiki.flightgear.org/images/2/25/Quotes-logo-200x200.png&lt;br /&gt;
// @grant       GM_registerMenuCommand&lt;br /&gt;
// @grant       GM_setValue&lt;br /&gt;
// @grant       GM_getValue&lt;br /&gt;
// @grant       GM_addStyle&lt;br /&gt;
// @grant       GM_getResourceText&lt;br /&gt;
// @grant       GM_getResourceURL&lt;br /&gt;
// @grant       GM_setClipboard&lt;br /&gt;
// @grant       GM_xmlhttpRequest&lt;br /&gt;
// @noframes&lt;br /&gt;
// ==/UserScript==&lt;br /&gt;
&lt;br /&gt;
// This work has been released into the public domain by their authors. This&lt;br /&gt;
// applies worldwide.&lt;br /&gt;
// In some countries this may not be legally possible; if so:&lt;br /&gt;
// The authors grant anyone the right to use this work for any purpose, without&lt;br /&gt;
// any conditions, unless such conditions are required by law.&lt;br /&gt;
&lt;br /&gt;
// This script has a number of dependencies that are implicitly satisfied when&lt;br /&gt;
// run as a user script via GreaseMonkey/TamperMonkey; however, these need to&lt;br /&gt;
// be explicitly handled when using a different mode (e.g. Firefox/Android):&lt;br /&gt;
//&lt;br /&gt;
// - jQuery - user interface (REQUIRED)&lt;br /&gt;
// - genetic-js - genetic programming (OPTIONAL/EXPERIMENTAL)&lt;br /&gt;
// - synaptic - neural networks (OPTIONAL/EXPERIMENTAL)&lt;br /&gt;
&lt;br /&gt;
/* Here are some TODOs&lt;br /&gt;
 * - support RSS feeds http://dir.gmane.org/gmane.games.flightgear.devel/&lt;br /&gt;
 * - move event handling/processing to the CONFIG hash&lt;br /&gt;
 * - use try/catch more widely&lt;br /&gt;
 * - wrap function calls in try/call for better debugging/diagnostics&lt;br /&gt;
 * - add helpers for [].forEach.call, map, apply and call&lt;br /&gt;
 * - replace for/in, for/of, let statements for better compatibility (dont require ES6)&lt;br /&gt;
 * - for the same reason, replace use of functions with default params&lt;br /&gt;
 * - isolate UI (e.g. JQUERY) code in UserInterface hash&lt;br /&gt;
 * - expose regex/transformations via the UI&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
/*jslint&lt;br /&gt;
    devel&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
'use strict';&lt;br /&gt;
&lt;br /&gt;
// prevent conflicts with jQuery used on webpages:&lt;br /&gt;
// https://wiki.greasespot.net/Third-Party_Libraries#jQuery&lt;br /&gt;
// http://stackoverflow.com/a/5014220&lt;br /&gt;
// TODO: move to GreaseMonkey/UI host&lt;br /&gt;
this.$ = this.jQuery = jQuery.noConflict(true);&lt;br /&gt;
&lt;br /&gt;
// this hash is just intended to help isolate UI specifics so that we don't&lt;br /&gt;
// need to maintain/port tons of code&lt;br /&gt;
var UserInterface = {&lt;br /&gt;
    get: function () {&lt;br /&gt;
        return UserInterface.DEFAULT;&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
    CONSOLE: {&lt;br /&gt;
    }, // CONSOLE (shell, mainly useful for testing)&lt;br /&gt;
&lt;br /&gt;
    DEFAULT: {&lt;br /&gt;
        alert: function (msg) {&lt;br /&gt;
            return window.alert(msg);&lt;br /&gt;
        },&lt;br /&gt;
        prompt: function (msg) {&lt;br /&gt;
            return window.prompt(msg);&lt;br /&gt;
        },&lt;br /&gt;
        confirm: function (msg) {&lt;br /&gt;
            return window.confirm(msg);&lt;br /&gt;
        },&lt;br /&gt;
        dialog: null,&lt;br /&gt;
        selection: null,&lt;br /&gt;
        populateWatchlist: function () {&lt;br /&gt;
        },&lt;br /&gt;
        populateEditSections: function () {&lt;br /&gt;
        }&lt;br /&gt;
    }, // default UI mapping (Browser/User script)&lt;br /&gt;
&lt;br /&gt;
    JQUERY: {&lt;br /&gt;
    } // JQUERY&lt;br /&gt;
}; // UserInterface&lt;br /&gt;
&lt;br /&gt;
var UI = UserInterface.get(); // DEFAULT for now&lt;br /&gt;
&lt;br /&gt;
// This hash is intended to help encapsulate platform specifics (browser/&lt;br /&gt;
// scripting host). Ideally, all APIs that are platform specific should be&lt;br /&gt;
// kept here. This should make it much easier to update/port and maintain the&lt;br /&gt;
// script in the future.&lt;br /&gt;
var Environment = {&lt;br /&gt;
    getHost: function (xpi = false) {&lt;br /&gt;
&lt;br /&gt;
        if (xpi) {&lt;br /&gt;
            Environment.scriptEngine = 'firefox addon';&lt;br /&gt;
            console.log('in firefox xpi/addon mode');&lt;br /&gt;
            return Environment.FirefoxAddon; // HACK for testing the xpi mode (firefox addon)&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // This will determine the script engine in use: http://stackoverflow.com/questions/27487828/how-to-detect-if-a-userscript-is-installed-from-the-chrome-store&lt;br /&gt;
        if (typeof (GM_info) === 'undefined') {&lt;br /&gt;
            Environment.scriptEngine =&lt;br /&gt;
                &amp;quot;plain Chrome (Or Opera, or scriptish, or Safari, or rarer)&amp;quot;;&lt;br /&gt;
            // See http://stackoverflow.com/a/2401861/331508 for optional browser sniffing code.&lt;br /&gt;
        } else {&lt;br /&gt;
            Environment.scriptEngine = GM_info.scriptHandler ||&lt;br /&gt;
                &amp;quot;Greasemonkey&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        console.log('Instant cquotes is running on ' + Environment.scriptEngine +&lt;br /&gt;
            '.');&lt;br /&gt;
&lt;br /&gt;
        // console.log(&amp;quot;not in firefox addon mode...&amp;quot;);&lt;br /&gt;
        // See also: https://wiki.greasespot.net/Cross-browser_userscripting&lt;br /&gt;
        return Environment.GreaseMonkey; // return the only/default host (for now)&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
    validate: function (host) {&lt;br /&gt;
        if (host.get_persistent('startup.disable_validation', false))&lt;br /&gt;
            return;&lt;br /&gt;
&lt;br /&gt;
        if (Environment.scriptEngine !== &amp;quot;Greasemonkey&amp;quot;)&lt;br /&gt;
            console.log(&lt;br /&gt;
                &amp;quot;NOTE: This script has not been tested with script engines&amp;quot;&lt;br /&gt;
                + &amp;quot; other than GreaseMonkey recently!&amp;quot;&lt;br /&gt;
            );&lt;br /&gt;
&lt;br /&gt;
        var dependencies = [{&lt;br /&gt;
            name: 'jQuery',&lt;br /&gt;
            test: function () {}&lt;br /&gt;
        }, {&lt;br /&gt;
            name: 'genetic.js',&lt;br /&gt;
            test: function () {}&lt;br /&gt;
        }, {&lt;br /&gt;
            name: 'synaptic',&lt;br /&gt;
            test: function () {}&lt;br /&gt;
        }, ];&lt;br /&gt;
&lt;br /&gt;
        [].forEach.call(dependencies, function (dep) {&lt;br /&gt;
            console.log(&amp;quot;Checking for dependency:&amp;quot; + dep.name);&lt;br /&gt;
            var status = false;&lt;br /&gt;
            try {&lt;br /&gt;
                dep.test.call(undefined);&lt;br /&gt;
                status = true;&lt;br /&gt;
            } catch (e) {&lt;br /&gt;
                status = false;&lt;br /&gt;
            } finally {&lt;br /&gt;
                var success = (status) ? '==&amp;gt; success' :&lt;br /&gt;
                    '==&amp;gt; failed';&lt;br /&gt;
                console.log(success);&lt;br /&gt;
                return status;&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }, // validate&lt;br /&gt;
&lt;br /&gt;
    // this contains unit tests for checking crucial APIs that must work for&lt;br /&gt;
    // the script to work correctly&lt;br /&gt;
    // for the time being, most of these are stubs waiting to be filled in&lt;br /&gt;
    // for a working example, refer to the JSON test at the end&lt;br /&gt;
    // TODO: add jQuery tests&lt;br /&gt;
    APITests: [{&lt;br /&gt;
            name: 'download',&lt;br /&gt;
            test: function (recipient) {&lt;br /&gt;
                recipient(true);&lt;br /&gt;
            }&lt;br /&gt;
        }, {&lt;br /&gt;
            name: 'make_doc',&lt;br /&gt;
            test: function (recipient) {&lt;br /&gt;
                recipient(true);&lt;br /&gt;
            }&lt;br /&gt;
        }, {&lt;br /&gt;
            name: 'eval_xpath',&lt;br /&gt;
            test: function (recipient) {&lt;br /&gt;
                recipient(true);&lt;br /&gt;
            }&lt;br /&gt;
        }, {&lt;br /&gt;
            name: 'JSON de/serialization',&lt;br /&gt;
            test: function (recipient) {&lt;br /&gt;
                    //console.log(&amp;quot;running json test&amp;quot;);&lt;br /&gt;
                    var identifier = 'unit_tests.json_serialization';&lt;br /&gt;
                    var hash1 = {&lt;br /&gt;
                        x: 1,&lt;br /&gt;
                        y: 2,&lt;br /&gt;
                        z: 3&lt;br /&gt;
                    };&lt;br /&gt;
                    Host.set_persistent(identifier, hash1, true);&lt;br /&gt;
                    var hash2 = Host.get_persistent(identifier, null,&lt;br /&gt;
                        true);&lt;br /&gt;
&lt;br /&gt;
                    recipient(JSON.stringify(hash1) === JSON.stringify(&lt;br /&gt;
                        hash2));&lt;br /&gt;
                } // callback&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
        // downloads a posting and tries to transform it to 3rd person speech ...&lt;br /&gt;
        // TODO: add another test to check forum postings&lt;br /&gt;
        {&lt;br /&gt;
            name: 'text/speech transformation',&lt;br /&gt;
            test: function (recipient) {&lt;br /&gt;
&lt;br /&gt;
                    // the posting we want to download&lt;br /&gt;
                    var url =&lt;br /&gt;
                        'https://sourceforge.net/p/flightgear/mailman/message/35066974/';&lt;br /&gt;
                    Host.downloadPosting(url, function (result) {&lt;br /&gt;
&lt;br /&gt;
                        // only process the first sentence by using comma/dot as&lt;br /&gt;
                        // delimiter&lt;br /&gt;
                        var firstSentence = result.content.substring(&lt;br /&gt;
                            result.content.indexOf(',') + 1,&lt;br /&gt;
                            result.content.indexOf('.'));&lt;br /&gt;
&lt;br /&gt;
                        var transformed = transformSpeech(&lt;br /&gt;
                            firstSentence, result.author,&lt;br /&gt;
                            null, speechTransformations);&lt;br /&gt;
                        console.log(&lt;br /&gt;
                            &amp;quot;3rd person speech transformation:\n&amp;quot; +&lt;br /&gt;
                            transformed);&lt;br /&gt;
&lt;br /&gt;
                        recipient(true);&lt;br /&gt;
                    }); // downloadPosting()&lt;br /&gt;
&lt;br /&gt;
                } // test()&lt;br /&gt;
        }, // end of speech transform test&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;download $FG_ROOT/options.xml&amp;quot;,&lt;br /&gt;
            test: function (recipient) {&lt;br /&gt;
                    downloadOptionsXML();&lt;br /&gt;
                    recipient(true);&lt;br /&gt;
                } // test&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    ], // end of APITests&lt;br /&gt;
&lt;br /&gt;
    runAPITests: function (host, recipient) {&lt;br /&gt;
        console.log(&amp;quot;Running API tests&amp;quot;);&lt;br /&gt;
        for (let test of Environment.APITests) {&lt;br /&gt;
            //var test = Environment.APITests[t];&lt;br /&gt;
            // invoke the callback passed, with the hash containing the test&lt;br /&gt;
            // specs, so that the console/log or a div can be updated showing&lt;br /&gt;
            // the test results&lt;br /&gt;
            recipient.call(undefined, test);&lt;br /&gt;
&lt;br /&gt;
        } // foreach test&lt;br /&gt;
    }, // runAPITests&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * ========================================================================&lt;br /&gt;
     */&lt;br /&gt;
&lt;br /&gt;
    // NOTE: This mode/environment is WIP and highly experimental ...&lt;br /&gt;
    // To see this working, you need to package up the whole file as a Firefox&lt;br /&gt;
    // XPI using &amp;quot;jpm xpi&amp;quot; and then start the whole thing via &amp;quot;jpm run&amp;quot;, to do&lt;br /&gt;
    // that, you also need a matching package.json (i.e. via jpm init)&lt;br /&gt;
    // ALSO: you will have to explicitly install any dependencies using jpm&lt;br /&gt;
    FirefoxAddon: {&lt;br /&gt;
        init: function () {&lt;br /&gt;
            console.log(&amp;quot;Firefox addon mode ...&amp;quot;);&lt;br /&gt;
        },&lt;br /&gt;
        getScriptVersion: function () {&lt;br /&gt;
            return '0.36'; // FIXME&lt;br /&gt;
        },&lt;br /&gt;
        dbLog: function (msg) {&lt;br /&gt;
            console.log(msg);&lt;br /&gt;
        },&lt;br /&gt;
        addEventListener: function (ev, cb) {&lt;br /&gt;
&lt;br /&gt;
            require(&amp;quot;sdk/tabs&amp;quot;).on(&amp;quot;ready&amp;quot;, logURL);&lt;br /&gt;
&lt;br /&gt;
            function logURL(tab) {&lt;br /&gt;
                console.log(&amp;quot;URL loaded:&amp;quot; + tab.url);&lt;br /&gt;
            }&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
        registerConfigurationOption: function (name, callback, hook) {&lt;br /&gt;
            // https://developer.mozilla.org/en-US/Add-ons/SDK/Tutorials/Add_a_Context_Menu_Item&lt;br /&gt;
            console.log(&amp;quot;config menu support n/a in firefox mode&amp;quot;);&lt;br /&gt;
            // https://developer.mozilla.org/en-US/Add-ons/SDK/Tutorials/Using_third-party_modules_%28jpm%29&lt;br /&gt;
            var menuitems = require(&amp;quot;menuitem&amp;quot;);&lt;br /&gt;
            var menuitem = menuitems.Menuitem({&lt;br /&gt;
                id: &amp;quot;clickme&amp;quot;,&lt;br /&gt;
                menuid: &amp;quot;menu_ToolsPopup&amp;quot;,&lt;br /&gt;
                label: name,&lt;br /&gt;
                onCommand: function () {&lt;br /&gt;
                    console.log(&amp;quot;menuitem clicked:&amp;quot;);&lt;br /&gt;
                    callback();&lt;br /&gt;
                },&lt;br /&gt;
                insertbefore: &amp;quot;menu_pageInfo&amp;quot;&lt;br /&gt;
            });&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
        registerTrigger: function () {&lt;br /&gt;
            // https://developer.mozilla.org/en-US/Add-ons/SDK/Tutorials/Add_a_Context_Menu_Item&lt;br /&gt;
            // https://developer.mozilla.org/en-US/Add-ons/SDK/High-Level_APIs/context-menu#Item%28options%29&lt;br /&gt;
            var contextMenu = require(&amp;quot;sdk/context-menu&amp;quot;);&lt;br /&gt;
            var menuItem = contextMenu.Item({&lt;br /&gt;
                label: &amp;quot;Instant Cquote&amp;quot;,&lt;br /&gt;
                context: contextMenu.SelectionContext(),&lt;br /&gt;
                // https://developer.mozilla.org/en/Add-ons/SDK/Guides/Two_Types_of_Scripts&lt;br /&gt;
                // https://developer.mozilla.org/en-US/Add-ons/SDK/Guides/Content_Scripts&lt;br /&gt;
                contentScript: 'self.on(&amp;quot;click&amp;quot;, function () {' +&lt;br /&gt;
                    '  var text = window.getSelection().toString();' +&lt;br /&gt;
                    '  self.postMessage(text);' +&lt;br /&gt;
                    '});',&lt;br /&gt;
                onMessage: function (selectionText) {&lt;br /&gt;
                    console.log(selectionText);&lt;br /&gt;
                    instantCquote(selectionText);&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            // for selection handling stuff, see: https://developer.mozilla.org/en-US/Add-ons/SDK/High-Level_APIs/selection&lt;br /&gt;
&lt;br /&gt;
            function myListener() {&lt;br /&gt;
                console.log(&amp;quot;A selection has been made.&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            var selection = require(&amp;quot;sdk/selection&amp;quot;);&lt;br /&gt;
            selection.on('select', myListener);&lt;br /&gt;
&lt;br /&gt;
        }, //registerTrigger&lt;br /&gt;
&lt;br /&gt;
        get_persistent: function (key, default_value) {&lt;br /&gt;
            // https://developer.mozilla.org/en-US/Add-ons/SDK/High-Level_APIs/simple-storage&lt;br /&gt;
            var ss = require(&amp;quot;sdk/simple-storage&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
            console.log(&lt;br /&gt;
                &amp;quot;firefox mode does not yet have persistence support&amp;quot;&lt;br /&gt;
            );&lt;br /&gt;
            return default_value;&lt;br /&gt;
        },&lt;br /&gt;
        set_persistent: function (key, value) {&lt;br /&gt;
            console.log(&amp;quot;firefox persistence stubs not yet filled in !&amp;quot;);&lt;br /&gt;
        },&lt;br /&gt;
        set_clipboard: function (content) {&lt;br /&gt;
            // https://developer.mozilla.org/en-US/Add-ons/SDK/High-Level_APIs/clipboard&lt;br /&gt;
&lt;br /&gt;
            //console.log('clipboard stub not yet filled in ...');&lt;br /&gt;
            var clipboard = require(&amp;quot;sdk/clipboard&amp;quot;);&lt;br /&gt;
            clipboard.set(content);&lt;br /&gt;
        } //set_cliipboard&lt;br /&gt;
&lt;br /&gt;
    }, // end of FireFox addon config&lt;br /&gt;
&lt;br /&gt;
    // placeholder for now ...&lt;br /&gt;
    Android: {&lt;br /&gt;
        // NOP&lt;br /&gt;
    }, // Android&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    ///////////////////////////////////////&lt;br /&gt;
    // supported  script engines:&lt;br /&gt;
    ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
    GreaseMonkey: {&lt;br /&gt;
        // TODO: move environment specific initialization code here&lt;br /&gt;
        init: function () {&lt;br /&gt;
            // Check if Greasemonkey/Tampermonkey is available&lt;br /&gt;
            try {&lt;br /&gt;
                // TODO: add version check for clipboard API and check for TamperMonkey/Scriptish equivalents?&lt;br /&gt;
                GM_addStyle(GM_getResourceText('jQUI_CSS'));&lt;br /&gt;
            } // try&lt;br /&gt;
            catch (error) {&lt;br /&gt;
                console.log(&lt;br /&gt;
                    'Could not add style or determine script version'&lt;br /&gt;
                );&lt;br /&gt;
            } // catch&lt;br /&gt;
&lt;br /&gt;
            var commands = [{&lt;br /&gt;
                name: 'Setup quotes',&lt;br /&gt;
                callback: setupDialog,&lt;br /&gt;
                hook: 'S'&lt;br /&gt;
            }, {&lt;br /&gt;
                name: 'Check quotes',&lt;br /&gt;
                callback: selfCheckDialog,&lt;br /&gt;
                hook: 'C'&lt;br /&gt;
            }];&lt;br /&gt;
&lt;br /&gt;
            for (let c of commands) {&lt;br /&gt;
                this.registerConfigurationOption(c.name, c.callback, c.hook);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
        }, // init()&lt;br /&gt;
&lt;br /&gt;
        getScriptVersion: function () {&lt;br /&gt;
            return GM_info.script.version;&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
        dbLog: function (message) {&lt;br /&gt;
            if (Boolean(DEBUG)) {&lt;br /&gt;
                console.log('Instant cquotes:' + message);&lt;br /&gt;
            }&lt;br /&gt;
        }, // dbLog()&lt;br /&gt;
&lt;br /&gt;
        registerConfigurationOption: function (name, callback, hook) {&lt;br /&gt;
            // https://wiki.greasespot.net/GM_registerMenuCommand&lt;br /&gt;
            // https://wiki.greasespot.net/Greasemonkey_Manual:Monkey_Menu#The_Menu&lt;br /&gt;
            GM_registerMenuCommand(name, callback, hook);&lt;br /&gt;
        }, //registerMenuCommand()&lt;br /&gt;
&lt;br /&gt;
        registerTrigger: function () {&lt;br /&gt;
&lt;br /&gt;
            // TODO: we can use the following callback non-interactively, i.e. to trigger background tasks&lt;br /&gt;
            // http://javascript.info/tutorial/onload-ondomcontentloaded&lt;br /&gt;
            document.addEventListener(&amp;quot;DOMContentLoaded&amp;quot;, function (&lt;br /&gt;
                event) {&lt;br /&gt;
                console.log(&lt;br /&gt;
                    &amp;quot;Instant Cquotes: DOM fully loaded and parsed&amp;quot;&lt;br /&gt;
                );&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            window.addEventListener('load', init); // page fully loaded&lt;br /&gt;
            Host.dbLog('Instant Cquotes: page load handler registered');&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            // Initialize (matching page loaded)&lt;br /&gt;
            function init() {&lt;br /&gt;
                console.log(&lt;br /&gt;
                    'Instant Cquotes: page load handler invoked');&lt;br /&gt;
                var profile = getProfile();&lt;br /&gt;
&lt;br /&gt;
                Host.dbLog(&amp;quot;Profile type is:&amp;quot; + profile.type);&lt;br /&gt;
&lt;br /&gt;
                // Dispatch to correct event handler (depending on website/URL)&lt;br /&gt;
                // TODO: this stuff could/should be moved into the config hash itself&lt;br /&gt;
&lt;br /&gt;
                if (profile.type == 'wiki') {&lt;br /&gt;
                    profile.event_handler(); // just for testing&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                Host.dbLog('using default mode');&lt;br /&gt;
                document.onmouseup = instantCquote;&lt;br /&gt;
                // HACK: preparations for moving the the event/handler logic also into the profile hash, so that the wiki (edit mode) can be handled equally&lt;br /&gt;
                //eval(profile.event+&amp;quot;=instantCquote&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
            } // init()&lt;br /&gt;
&lt;br /&gt;
        }, // registerTrigger&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        download: function (url, callback, method = 'GET') {&lt;br /&gt;
            // http://wiki.greasespot.net/GM_xmlhttpRequest&lt;br /&gt;
            try {&lt;br /&gt;
                GM_xmlhttpRequest({&lt;br /&gt;
                    method: method,&lt;br /&gt;
                    url: url,&lt;br /&gt;
                    onload: callback&lt;br /&gt;
                });&lt;br /&gt;
            } catch (e) {&lt;br /&gt;
                console.log(&amp;quot;download did not work&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
        }, // download()&lt;br /&gt;
&lt;br /&gt;
        // is only intended to work with archives supported by the  hash&lt;br /&gt;
        downloadPosting: function (url, EventHandler) {&lt;br /&gt;
&lt;br /&gt;
            Host.download(url, function (response) {&lt;br /&gt;
                var profile = getProfile(url);&lt;br /&gt;
                var blob = response.responseText;&lt;br /&gt;
                var doc = Host.make_doc(blob, 'text/html');&lt;br /&gt;
                var result = {}; // hash to be returned&lt;br /&gt;
&lt;br /&gt;
                [].forEach.call(['author', 'date', 'title',&lt;br /&gt;
                    'content'&lt;br /&gt;
                ], function (field) {&lt;br /&gt;
                    var xpath_query = '//' + profile[&lt;br /&gt;
                        field].xpath;&lt;br /&gt;
                    try {&lt;br /&gt;
                        var value = Host.eval_xpath(doc,&lt;br /&gt;
                            xpath_query).stringValue;&lt;br /&gt;
                        //UI.alert(&amp;quot;extracted field value:&amp;quot;+value);&lt;br /&gt;
&lt;br /&gt;
                        // now apply all transformations, if any&lt;br /&gt;
                        value = applyTransformations(&lt;br /&gt;
                            value, profile[field].transform&lt;br /&gt;
                        );&lt;br /&gt;
&lt;br /&gt;
                        result[field] = value; // store the extracted/transormed value in the hash that we pass on&lt;br /&gt;
                    } // try&lt;br /&gt;
                    catch (e) {&lt;br /&gt;
                        UI.alert(&lt;br /&gt;
                            &amp;quot;downloadPosting failed:\n&amp;quot; +&lt;br /&gt;
                            e.message);&lt;br /&gt;
                    } // catch&lt;br /&gt;
                }); // forEach field&lt;br /&gt;
&lt;br /&gt;
                EventHandler(result); // pass the result to the handler&lt;br /&gt;
            }); // call to Host.download()&lt;br /&gt;
&lt;br /&gt;
        }, // downloadPosting()&lt;br /&gt;
&lt;br /&gt;
        // TODO: add makeAJAXCall, and makeWikiCall here&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        // turn a string/text blob into a DOM tree that can be queried (e.g. for xpath expressions)&lt;br /&gt;
        // FIXME: this is browser specific not GM specific ...&lt;br /&gt;
        make_doc: function (text, type = 'text/html') {&lt;br /&gt;
            // to support other browsers, see: https://developer.mozilla.org/en/docs/Web/API/DOMParser&lt;br /&gt;
            return new DOMParser().parseFromString(text, type);&lt;br /&gt;
        }, // make DOM document&lt;br /&gt;
&lt;br /&gt;
        // xpath handling may be handled separately depending on browser/platform, so better encapsulate this&lt;br /&gt;
        // FIXME: this is browser specific not GM specific ...&lt;br /&gt;
        eval_xpath: function (doc, xpath, type = XPathResult.STRING_TYPE) {&lt;br /&gt;
            return doc.evaluate(xpath, doc, null, type, null);&lt;br /&gt;
        }, // eval_xpath&lt;br /&gt;
&lt;br /&gt;
        set_persistent: function (key, value, json = false) {&lt;br /&gt;
            // transparently stringify to json&lt;br /&gt;
            if (json) {&lt;br /&gt;
                // http://stackoverflow.com/questions/16682150/store-a-persistent-list-between-sessions&lt;br /&gt;
                value = JSON.stringify(value);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // https://wiki.greasespot.net/GM_setValue&lt;br /&gt;
            GM_setValue(key, value);&lt;br /&gt;
            //UI.alert('Saved value for key\n'+key+':'+value);&lt;br /&gt;
        }, // set_persistent&lt;br /&gt;
&lt;br /&gt;
        get_persistent: function (key, default_value, json = false) {&lt;br /&gt;
            // https://wiki.greasespot.net/GM_getValue&lt;br /&gt;
&lt;br /&gt;
            var value = GM_getValue(key, default_value);&lt;br /&gt;
            // transparently support JSON: http://stackoverflow.com/questions/16682150/store-a-persistent-list-between-sessions&lt;br /&gt;
            if (json) {&lt;br /&gt;
                value = JSON.parse(value) || {};&lt;br /&gt;
            }&lt;br /&gt;
            return value;&lt;br /&gt;
        }, // get_persistent&lt;br /&gt;
&lt;br /&gt;
        setClipboard: function (msg) {&lt;br /&gt;
            // this being a greasemonkey user-script, we are not&lt;br /&gt;
            // subject to usual browser restrictions&lt;br /&gt;
            // http://wiki.greasespot.net/GM_setClipboard&lt;br /&gt;
            GM_setClipboard(msg);&lt;br /&gt;
        }, // setClipboard()&lt;br /&gt;
&lt;br /&gt;
        getTemplate: function () {&lt;br /&gt;
&lt;br /&gt;
                // hard-coded default template&lt;br /&gt;
                var template = '$CONTENT&amp;lt;ref&amp;gt;{{cite web\n' +&lt;br /&gt;
                    '  |url    =  $URL \n' +&lt;br /&gt;
                    '  |title  =  &amp;lt;nowiki&amp;gt; $TITLE &amp;lt;/nowiki&amp;gt; \n' +&lt;br /&gt;
                    '  |author =  &amp;lt;nowiki&amp;gt; $AUTHOR &amp;lt;/nowiki&amp;gt; \n' +&lt;br /&gt;
                    '  |date   =  $DATE \n' +&lt;br /&gt;
                    '  |added  =  $ADDED \n' +&lt;br /&gt;
                    '  |script_version = $SCRIPT_VERSION \n' +&lt;br /&gt;
                    '  }}&amp;lt;/ref&amp;gt;\n';&lt;br /&gt;
&lt;br /&gt;
                // return a saved template if found, fall back to hard-coded one above otherwise&lt;br /&gt;
                return Host.get_persistent('default_template', template);&lt;br /&gt;
&lt;br /&gt;
            } // getTemplate&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    } // end of GreaseMonkey environment, add other environments below&lt;br /&gt;
&lt;br /&gt;
}; // Environment hash - intended to help encapsulate host specific stuff (APIs)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// the first thing we need to do is to determine what APIs are available&lt;br /&gt;
// and store everything in a Host hash, which is subsequently used for API lookups&lt;br /&gt;
// the Host hash contains all platform/browser-specific APIs&lt;br /&gt;
var Host = Environment.getHost();&lt;br /&gt;
Environment.validate(Host); // this checks the obtained host to see if all required dependencies are available&lt;br /&gt;
Host.init(); // run environment specific initialization code (e.g. logic for GreaseMonkey setup)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// move DEBUG handling to a persistent configuration flag so that we can&lt;br /&gt;
// configure this using a jQuery dialog (defaulted to false)&lt;br /&gt;
// TODO: move DEBUG variable to Environment hash / init() routine&lt;br /&gt;
var DEBUG = Host.get_persistent('debug_mode_enabled', false);&lt;br /&gt;
Host.dbLog(&amp;quot;Debug mode is:&amp;quot; + DEBUG);&lt;br /&gt;
&lt;br /&gt;
function DEBUG_mode() {&lt;br /&gt;
    // reset script invocation counter for testing purposes&lt;br /&gt;
    Host.dbLog('Resetting script invocation counter');&lt;br /&gt;
    Host.set_persistent(GM_info.script.version, 0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if (DEBUG)&lt;br /&gt;
    DEBUG_mode();&lt;br /&gt;
&lt;br /&gt;
// hash with supported websites/URLs,  includes xpath and regex expressions to&lt;br /&gt;
// extract certain fields, and a vector with optional transformations for&lt;br /&gt;
// post-processing each field&lt;br /&gt;
&lt;br /&gt;
var CONFIG = {&lt;br /&gt;
    // WIP: the first entry is special, i.e. it's not an actual list archive (source), but only added here so that the same script can be used&lt;br /&gt;
    // for editing the FlightGear wiki&lt;br /&gt;
&lt;br /&gt;
    'FlightGear.wiki': {&lt;br /&gt;
        type: 'wiki',&lt;br /&gt;
        enabled: false,&lt;br /&gt;
        event: 'document.onmouseup', // when to invoke the event handler&lt;br /&gt;
        // TODO: move downloadWatchlist() etc here&lt;br /&gt;
        event_handler: function () {&lt;br /&gt;
            console.log(&lt;br /&gt;
                'FlightGear wiki handler active (waiting to be populated)'&lt;br /&gt;
            );&lt;br /&gt;
            // this is where the logic for a wiki mode can be added over time (for now, it's a NOP)&lt;br /&gt;
&lt;br /&gt;
            //for each supported mode, invoke the trigger and call the corresponding handler&lt;br /&gt;
            [].forEach.call(CONFIG['FlightGear.wiki'].modes, function (&lt;br /&gt;
                mode) {&lt;br /&gt;
                //dbLog(&amp;quot;Checking trigger:&amp;quot;+mode.name);&lt;br /&gt;
                if (mode.trigger()) {&lt;br /&gt;
                    mode.handler();&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
        }, // the event handler to be invoked&lt;br /&gt;
        url_reg: '^(http|https)://wiki.flightgear.org', // ignore for now: not currently used by the wiki mode&lt;br /&gt;
&lt;br /&gt;
        modes: [{&lt;br /&gt;
                    name: 'process-editSections',&lt;br /&gt;
                    trigger: function () {&lt;br /&gt;
                        return true;&lt;br /&gt;
                    }, // match URL regex - return true for always match&lt;br /&gt;
&lt;br /&gt;
                    // the code implementing the mode&lt;br /&gt;
                    handler: function () {&lt;br /&gt;
&lt;br /&gt;
                            var editSections = document.getElementsByClassName(&lt;br /&gt;
                                'mw-editsection');&lt;br /&gt;
                            console.log(&lt;br /&gt;
                                'FlightGear wiki article, number of edit sections: ' +&lt;br /&gt;
                                editSections.length);&lt;br /&gt;
&lt;br /&gt;
                            // for now, just rewrite edit sections and add a note to them&lt;br /&gt;
&lt;br /&gt;
                            [].forEach.call(editSections, function (sec) {&lt;br /&gt;
                                sec.appendChild(&lt;br /&gt;
                                    document.createTextNode(&lt;br /&gt;
                                        ' (instant-cquotes is lurking) '&lt;br /&gt;
                                    )&lt;br /&gt;
                                );&lt;br /&gt;
                            }); //forEach section&lt;br /&gt;
                        } // handler&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                } // process-editSections&lt;br /&gt;
                // TODO: add other wiki modes below&lt;br /&gt;
&lt;br /&gt;
            ] // modes&lt;br /&gt;
&lt;br /&gt;
    }, // end of wiki profile&lt;br /&gt;
&lt;br /&gt;
    'Sourceforge Mailing list': {&lt;br /&gt;
        enabled: true,&lt;br /&gt;
        type: 'archive',&lt;br /&gt;
        event: 'document.onmouseup', // when to invoke the event handler&lt;br /&gt;
        event_handler: instantCquote, // the event handler to be invoked&lt;br /&gt;
        url_reg: '^(http|https)://sourceforge.net/p/flightgear/mailman/.*/',&lt;br /&gt;
        content: {&lt;br /&gt;
            xpath: 'tbody/tr[2]/td/pre/text()', // NOTE this is only used by the downloadPosting  helper to retrieve the posting without having a selection (TODO:add content xpath to forum hash)&lt;br /&gt;
            selection: getSelectedText,&lt;br /&gt;
            idStyle: /msg[0-9]{8}/,&lt;br /&gt;
            parentTag: [&lt;br /&gt;
                'tagName',&lt;br /&gt;
                'PRE'&lt;br /&gt;
            ],&lt;br /&gt;
            transform: [],&lt;br /&gt;
        }, // content recipe&lt;br /&gt;
        // vector with tests to be executed for sanity checks (unit testing)&lt;br /&gt;
        tests: [{&lt;br /&gt;
                url: 'https://sourceforge.net/p/flightgear/mailman/message/35059454/',&lt;br /&gt;
                author: 'Erik Hofman',&lt;br /&gt;
                date: 'May 3rd, 2016', // NOTE: using the transformed date here&lt;br /&gt;
                title: 'Re: [Flightgear-devel] Auto altimeter setting at startup (?)'&lt;br /&gt;
            }, {&lt;br /&gt;
                url: 'https://sourceforge.net/p/flightgear/mailman/message/35059961/',&lt;br /&gt;
                author: 'Ludovic Brenta',&lt;br /&gt;
                date: 'May 3rd, 2016',&lt;br /&gt;
                title: 'Re: [Flightgear-devel] dual-control-tools and the limit on packet size'&lt;br /&gt;
            }, {&lt;br /&gt;
                url: 'https://sourceforge.net/p/flightgear/mailman/message/20014126/',&lt;br /&gt;
                author: 'Tim Moore',&lt;br /&gt;
                date: 'Aug 4th, 2008',&lt;br /&gt;
                title: 'Re: [Flightgear-devel] Cockpit displays (rendering, modelling)'&lt;br /&gt;
            }, {&lt;br /&gt;
                url: 'https://sourceforge.net/p/flightgear/mailman/message/23518343/',&lt;br /&gt;
                author: 'Tim Moore',&lt;br /&gt;
                date: 'Sep 10th, 2009',&lt;br /&gt;
                title: '[Flightgear-devel] Atmosphere patch from John Denker'&lt;br /&gt;
            } // add other tests below&lt;br /&gt;
&lt;br /&gt;
        ], // end of vector with self-tests&lt;br /&gt;
        // regex/xpath and transformations for extracting various required fields&lt;br /&gt;
        author: {&lt;br /&gt;
            xpath: 'tbody/tr[1]/td/div/small/text()',&lt;br /&gt;
            transform: [extract(/From: (.*) &amp;lt;.*@.*&amp;gt;/)]&lt;br /&gt;
        },&lt;br /&gt;
        title: {&lt;br /&gt;
            xpath: 'tbody/tr[1]/td/div/div[1]/b/a/text()',&lt;br /&gt;
            transform: []&lt;br /&gt;
        },&lt;br /&gt;
        date: {&lt;br /&gt;
            xpath: 'tbody/tr[1]/td/div/small/text()',&lt;br /&gt;
            transform: [extract(/- (.*-.*-.*) /)]&lt;br /&gt;
        },&lt;br /&gt;
        url: {&lt;br /&gt;
            xpath: 'tbody/tr[1]/td/div/div[1]/b/a/@href',&lt;br /&gt;
            transform: [prepend('https://sourceforge.net')]&lt;br /&gt;
        }&lt;br /&gt;
    }, // end of mailing list profile&lt;br /&gt;
    // next website/URL (forum)&lt;br /&gt;
    'FlightGear forum': {&lt;br /&gt;
        enabled: true,&lt;br /&gt;
        type: 'archive',&lt;br /&gt;
        event: 'document.onmouseup', // when to invoke the event handler (not used atm)&lt;br /&gt;
        event_handler: null, // the event handler to be invoked (not used atm)&lt;br /&gt;
        url_reg: /https:\/\/forum\.flightgear\.org\/.*/,&lt;br /&gt;
        content: {&lt;br /&gt;
            xpath: '', //TODO: this must be added for downloadPosting() to work, or it cannot extract contents&lt;br /&gt;
            selection: getSelectedHtml,&lt;br /&gt;
            idStyle: /p[0-9]{6}/,&lt;br /&gt;
            parentTag: [&lt;br /&gt;
                'className',&lt;br /&gt;
                'content',&lt;br /&gt;
                'postbody'&lt;br /&gt;
            ],&lt;br /&gt;
            transform: [&lt;br /&gt;
                removeComments,&lt;br /&gt;
                forum_quote2cquote,&lt;br /&gt;
                forum_smilies2text,&lt;br /&gt;
                forum_fontstyle2wikistyle,&lt;br /&gt;
                forum_code2syntaxhighlight,&lt;br /&gt;
                img2link,&lt;br /&gt;
                a2wikilink,&lt;br /&gt;
                vid2wiki,&lt;br /&gt;
                list2wiki,&lt;br /&gt;
                forum_br2newline&lt;br /&gt;
            ]&lt;br /&gt;
        },&lt;br /&gt;
        // vector with tests to be executed for sanity checks (unit testing)&lt;br /&gt;
        // postings will be downloaded using the URL specified, and then the author/title&lt;br /&gt;
        // fields extracted using the outer regex and matched against what is expected&lt;br /&gt;
        // NOTE: forum postings can be edited, so that these tests would fail - thus, it makes sense to pick locked topics/postings for such tests&lt;br /&gt;
        tests: [{&lt;br /&gt;
                url: 'https://forum.flightgear.org/viewtopic.php?f=18&amp;amp;p=284108#p284108',&lt;br /&gt;
                author: 'mickybadia',&lt;br /&gt;
                date: 'May 3rd, 2016',&lt;br /&gt;
                title: 'OSM still PNG maps'&lt;br /&gt;
            }, {&lt;br /&gt;
                url: 'https://forum.flightgear.org/viewtopic.php?f=19&amp;amp;p=284120#p284120',&lt;br /&gt;
                author: 'Thorsten',&lt;br /&gt;
                date: 'May 3rd, 2016',&lt;br /&gt;
                title: 'Re: FlightGear\'s Screenshot Of The Month MAY 2016'&lt;br /&gt;
            }, {&lt;br /&gt;
                url: 'https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;t=29279&amp;amp;p=283455#p283446',&lt;br /&gt;
                author: 'Hooray',&lt;br /&gt;
                date: 'Apr 25th, 2016',&lt;br /&gt;
                title: 'Re: Best way to learn Canvas?'&lt;br /&gt;
            }, {&lt;br /&gt;
                url: 'https://forum.flightgear.org/viewtopic.php?f=4&amp;amp;t=1460&amp;amp;p=283994#p283994',&lt;br /&gt;
                author: 'bugman',&lt;br /&gt;
                date: 'May 2nd, 2016',&lt;br /&gt;
                title: 'Re: eurofighter typhoon'&lt;br /&gt;
            } // add other tests below&lt;br /&gt;
&lt;br /&gt;
        ], // end of vector with self-tests&lt;br /&gt;
        author: {&lt;br /&gt;
            xpath: 'div/div[1]/p/strong/a/text()',&lt;br /&gt;
            transform: [] // no transformations applied&lt;br /&gt;
        },&lt;br /&gt;
        title: {&lt;br /&gt;
            xpath: 'div/div[1]/h3/a/text()',&lt;br /&gt;
            transform: [] // no transformations applied&lt;br /&gt;
        },&lt;br /&gt;
        date: {&lt;br /&gt;
            xpath: 'div/div[1]/p/text()[2]',&lt;br /&gt;
            transform: [extract(/» (.*?[0-9]{4})/)]&lt;br /&gt;
        },&lt;br /&gt;
        url: {&lt;br /&gt;
            xpath: 'div/div[1]/p/a/@href',&lt;br /&gt;
            transform: [&lt;br /&gt;
                    extract(/\.(.*)/),&lt;br /&gt;
                    prepend('https://forum.flightgear.org')&lt;br /&gt;
                ] // transform vector&lt;br /&gt;
        } // url&lt;br /&gt;
    } // forum&lt;br /&gt;
}; // CONFIG has&lt;br /&gt;
&lt;br /&gt;
// hash to map URLs (wiki article, issue tracker, sourceforge link, forum thread etc) to existing wiki templates&lt;br /&gt;
var MatchURL2Templates = [&lt;br /&gt;
    // placeholder for now&lt;br /&gt;
    {&lt;br /&gt;
        name: 'rewrite sourceforge code links',&lt;br /&gt;
        url_reg: '',&lt;br /&gt;
        handler: function () {&lt;br /&gt;
&lt;br /&gt;
            } // handler&lt;br /&gt;
&lt;br /&gt;
    } // add other templates below&lt;br /&gt;
&lt;br /&gt;
]; // MatchURL2Templates&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// output methods (alert and jQuery for now)&lt;br /&gt;
var OUTPUT = {&lt;br /&gt;
    // Shows a window.prompt() message box&lt;br /&gt;
    msgbox: function (msg) {&lt;br /&gt;
        UI.prompt('Copy to clipboard ' + Host.getScriptVersion(), msg);&lt;br /&gt;
        Host.setClipboard(msg);&lt;br /&gt;
    }, // msgbox&lt;br /&gt;
&lt;br /&gt;
    // this is currently work-in-progress, and will need to be refactored sooner or later&lt;br /&gt;
    // for now, functionality matters more than elegant design/code :)&lt;br /&gt;
    jQueryTabbed: function (msg, original) {&lt;br /&gt;
            // FIXME: using backtics here makes the whole thing require ES6  ....&lt;br /&gt;
            var markup = $(&lt;br /&gt;
                `&amp;lt;div id=&amp;quot;tabs&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;ul&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#selection&amp;quot;&amp;gt;Selection&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#articles&amp;quot;&amp;gt;Articles&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#templates&amp;quot;&amp;gt;Templates&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#development&amp;quot;&amp;gt;Development&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#settings&amp;quot;&amp;gt;Settings&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#help&amp;quot;&amp;gt;Help&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#about&amp;quot;&amp;gt;About&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;/ul&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;selection&amp;quot;&amp;gt;This tab contains your extracted and post-processed selection, converted to proper wikimedia markup, including proper attribution.&lt;br /&gt;
  &amp;lt;div id=&amp;quot;content&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;label for=&amp;quot;template_select&amp;quot;&amp;gt;Select a template&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;select name=&amp;quot;template_select&amp;quot; id=&amp;quot;template_select&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;option&amp;gt;default&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option&amp;gt;cquote&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;/select&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;options&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Note this is work-in-progress, i.e. not yet fully functional&amp;lt;/b&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
    &amp;lt;label for=&amp;quot;article_select&amp;quot;&amp;gt;Select an article to update&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;select name=&amp;quot;article_select&amp;quot; id=&amp;quot;article_select&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;news&amp;quot; label=&amp;quot;News&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;support&amp;quot; label=&amp;quot;Support&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;release&amp;quot; label=&amp;quot;Release&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;develop&amp;quot; label=&amp;quot;Development&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;watchlist&amp;quot; label=&amp;quot;Watchlist&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;/select&amp;gt;&lt;br /&gt;
    &amp;lt;p/&amp;gt;&lt;br /&gt;
    &amp;lt;label for=&amp;quot;section_select&amp;quot;&amp;gt;Select section:&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;select name=&amp;quot;section_select&amp;quot; id=&amp;quot;section_select&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;/select&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;articles&amp;quot;&amp;gt;This tab contains articles that you can directly access/edit using the mediawiki API&amp;lt;br/&amp;gt;&lt;br /&gt;
  Note: The watchlist is retrieved dynamically, so does not need to be edited here&amp;lt;br/&amp;gt;&lt;br /&gt;
    &amp;lt;label for=&amp;quot;article_select&amp;quot;&amp;gt;Select an article&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;select name=&amp;quot;article_select&amp;quot; id=&amp;quot;article_select&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;news&amp;quot; label=&amp;quot;News&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;support&amp;quot; label=&amp;quot;Support&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;develop&amp;quot; label=&amp;quot;Development&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;release&amp;quot; label=&amp;quot;Release&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;!-- the watchlist is retrieved dynamically, so omit it here&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;watchlist&amp;quot; label=&amp;quot;Watchlist&amp;quot;/&amp;gt;&lt;br /&gt;
    --&amp;gt;&lt;br /&gt;
    &amp;lt;/select&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;button id=&amp;quot;article_new&amp;quot;&amp;gt;New&amp;lt;/button&amp;gt;&lt;br /&gt;
   &amp;lt;button id=&amp;quot;article_remove&amp;quot;&amp;gt;Remove&amp;lt;/button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div id=&amp;quot;edit_article&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;label for=&amp;quot;article_name&amp;quot;&amp;gt;Article&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;text&amp;quot; id=&amp;quot;article_name&amp;quot; name=&amp;quot;article_name&amp;quot;&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;label for=&amp;quot;article_url&amp;quot;&amp;gt;Link&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;text&amp;quot; id=&amp;quot;article_url&amp;quot; name=&amp;quot;article_url&amp;quot;&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;button id=&amp;quot;article_save&amp;quot;&amp;gt;Save&amp;lt;/button&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;templates&amp;quot;&amp;gt;This tab contains templates for different types of articles (newsletter, changelog, release plan etc)&amp;lt;p/&amp;gt;&lt;br /&gt;
  For now, this is WIP - in the future, there will be a dropdown menu added and all templates will be editable.&amp;lt;p/&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;template_header&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;label for=&amp;quot;template_select&amp;quot;&amp;gt;Select a template&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;select name=&amp;quot;template_select&amp;quot; id=&amp;quot;template_select&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;option&amp;gt;default&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option&amp;gt;cquote&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;/select&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;template_area&amp;quot;/&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;template_controls&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;button id=&amp;quot;template_save&amp;quot;&amp;gt;Save&amp;lt;/button&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;development&amp;quot;&amp;gt;This tab is a placeholder for features currently under development&amp;lt;p/&amp;gt;&lt;br /&gt;
  &amp;lt;button id=&amp;quot;evolve_regex&amp;quot;&amp;gt;Evolve regex&amp;lt;/button&amp;gt;&amp;lt;p/&amp;gt;&lt;br /&gt;
  &amp;lt;button id=&amp;quot;test_perceptron&amp;quot;&amp;gt;Test Perceptron&amp;lt;/button&amp;gt;&amp;lt;p/&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;output&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table id=&amp;quot;results&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;thead&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
     &amp;lt;th&amp;gt;Generation&amp;lt;/th&amp;gt;&lt;br /&gt;
     &amp;lt;th&amp;gt;Fitness&amp;lt;/th&amp;gt;&lt;br /&gt;
     &amp;lt;th&amp;gt;Expression&amp;lt;/th&amp;gt;&lt;br /&gt;
     &amp;lt;th&amp;gt;Result&amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
  &amp;lt;/thead&amp;gt;&lt;br /&gt;
  &amp;lt;tbody&amp;gt;&lt;br /&gt;
  &amp;lt;/tbody&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;!--&lt;br /&gt;
   &amp;lt;textarea id=&amp;quot;devel_output&amp;quot; lines=&amp;quot;10&amp;quot;&amp;gt;&amp;lt;/textarea&amp;gt;&amp;lt;p/&amp;gt;&lt;br /&gt;
  --&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div id=&amp;quot;settings&amp;quot;&amp;gt;This tab will contain script specific settings&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;help&amp;quot;&amp;gt;One day, this tab may contain help....&amp;lt;p/&amp;gt;&amp;lt;button id=&amp;quot;helpButton&amp;quot;&amp;gt;Instant Cquotes&amp;lt;/button&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;about&amp;quot;&amp;gt;show some  script related information here&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;`&lt;br /&gt;
            ); // tabs div&lt;br /&gt;
&lt;br /&gt;
            var evolve_regex = $('div#development button#evolve_regex',&lt;br /&gt;
                markup);&lt;br /&gt;
            evolve_regex.click(function () {&lt;br /&gt;
                //alert(&amp;quot;Evolve regex&amp;quot;);&lt;br /&gt;
                evolve_expression_test();&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            var test_perceptron = $(&lt;br /&gt;
                'div#development button#test_perceptron', markup);&lt;br /&gt;
            test_perceptron.click(function () {&lt;br /&gt;
                alert(&amp;quot;Test perceptron&amp;quot;);&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            // add dynamic elements to each tab&lt;br /&gt;
&lt;br /&gt;
            // NOTE: this affects all template selectors, on all tabs&lt;br /&gt;
            $('select#template_select', markup).change(function () {&lt;br /&gt;
                UI.alert(&lt;br /&gt;
                    &amp;quot;Sorry, templates are not yet fully implemented (WIP)&amp;quot;&lt;br /&gt;
                );&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            var help = $('#helpButton', markup);&lt;br /&gt;
            help.button();&lt;br /&gt;
            help.click(function () {&lt;br /&gt;
                window.open(&lt;br /&gt;
                    &amp;quot;http://wiki.flightgear.org/FlightGear_wiki:Instant-Cquotes&amp;quot;&lt;br /&gt;
                );&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            // rows=&amp;quot;10&amp;quot;cols=&amp;quot;80&amp;quot; style=&amp;quot; width: 420px; height: 350px&amp;quot;&lt;br /&gt;
            var textarea = $(&lt;br /&gt;
                '&amp;lt;textarea id=&amp;quot;quotedtext&amp;quot; rows=&amp;quot;20&amp;quot; cols=&amp;quot;70&amp;quot;/&amp;gt;');&lt;br /&gt;
            textarea.val(msg);&lt;br /&gt;
            $('#selection #content', markup).append(textarea);&lt;br /&gt;
&lt;br /&gt;
            var templateArea = $(&lt;br /&gt;
                '&amp;lt;textarea id=&amp;quot;template-edit&amp;quot; rows=&amp;quot;20&amp;quot; cols=&amp;quot;70&amp;quot;/&amp;gt;');&lt;br /&gt;
            templateArea.val(Host.getTemplate());&lt;br /&gt;
            $('div#templates div#template_area', markup).append(&lt;br /&gt;
                templateArea);&lt;br /&gt;
&lt;br /&gt;
            //$('#templates', markup).append($('&amp;lt;button&amp;gt;'));&lt;br /&gt;
            $('div#templates div#template_controls button#template_save',&lt;br /&gt;
                markup).button().click(function () {&lt;br /&gt;
                //UI.alert(&amp;quot;Saving template:\n&amp;quot;+templateArea.val() );&lt;br /&gt;
&lt;br /&gt;
                Host.set_persistent('default_template',&lt;br /&gt;
                    templateArea.val());&lt;br /&gt;
            }); // save template&lt;br /&gt;
&lt;br /&gt;
            // TODO: Currently, this is hard-coded, but should be made customizable via the &amp;quot;articles&amp;quot; tab at some point ...&lt;br /&gt;
            var articles = [&lt;br /&gt;
                // NOTE: category must match an existing &amp;lt;optgroup&amp;gt; above, title must match an existing wiki article&lt;br /&gt;
                {&lt;br /&gt;
                    category: 'support',&lt;br /&gt;
                    name: 'Frequently asked questions',&lt;br /&gt;
                    url: ''&lt;br /&gt;
                }, {&lt;br /&gt;
                    category: 'support',&lt;br /&gt;
                    name: 'Asking for help',&lt;br /&gt;
                    url: ''&lt;br /&gt;
                }, {&lt;br /&gt;
                    category: 'news',&lt;br /&gt;
                    name: 'Next newsletter',&lt;br /&gt;
                    url: ''&lt;br /&gt;
                }, {&lt;br /&gt;
                    category: 'news',&lt;br /&gt;
                    name: 'Next changelog',&lt;br /&gt;
                    url: ''&lt;br /&gt;
                }, {&lt;br /&gt;
                    category: 'release',&lt;br /&gt;
                    name: 'Release plan/Lessons learned',&lt;br /&gt;
                    url: ''&lt;br /&gt;
                }, // TODO: use wikimedia template&lt;br /&gt;
                {&lt;br /&gt;
                    category: 'develop',&lt;br /&gt;
                    name: 'Nasal library',&lt;br /&gt;
                    url: ''&lt;br /&gt;
                }, {&lt;br /&gt;
                    category: 'develop',&lt;br /&gt;
                    name: 'Canvas Snippets',&lt;br /&gt;
                    url: ''&lt;br /&gt;
                },&lt;br /&gt;
&lt;br /&gt;
            ];&lt;br /&gt;
&lt;br /&gt;
            // TODO: this should be moved elsewhere&lt;br /&gt;
            function updateArticleList(selector) {&lt;br /&gt;
                $.each(articles, function (i, article) {&lt;br /&gt;
                    $(selector + ' optgroup#' + article.category,&lt;br /&gt;
                        markup).append($('&amp;lt;option&amp;gt;', {&lt;br /&gt;
                        value: article.name, // FIXME: just a placeholder for now&lt;br /&gt;
                        text: article.name&lt;br /&gt;
                    })); //append option&lt;br /&gt;
                }); // foreach&lt;br /&gt;
            } // updateArticleList&lt;br /&gt;
&lt;br /&gt;
            // add the article list to the corresponding dropdown menus&lt;br /&gt;
            updateArticleList('select#article_select');&lt;br /&gt;
&lt;br /&gt;
            // populate watchlist (prototype for now)&lt;br /&gt;
            // TODO: generalize &amp;amp; refactor: url, format&lt;br /&gt;
&lt;br /&gt;
            // https://www.mediawiki.org/wiki/API:Watchlist&lt;br /&gt;
            // http://wiki.flightgear.org/api.php?action=query&amp;amp;list=watchlist&lt;br /&gt;
            var watchlist_url =&lt;br /&gt;
                'http://wiki.flightgear.org/api.php?action=query&amp;amp;list=watchlist&amp;amp;format=json';&lt;br /&gt;
            Host.download(watchlist_url, function (response) {&lt;br /&gt;
                try {&lt;br /&gt;
                    var watchlist = JSON.parse(response.responseText);&lt;br /&gt;
&lt;br /&gt;
                    //$('div#options select#section_select', markup).empty(); // delete all sections&lt;br /&gt;
&lt;br /&gt;
                    $.each(watchlist.query.watchlist, function (i,&lt;br /&gt;
                        article) {&lt;br /&gt;
                        $(&lt;br /&gt;
                            'div#options select#article_select optgroup#watchlist',&lt;br /&gt;
                            markup).append($('&amp;lt;option&amp;gt;', {&lt;br /&gt;
                            value: article.title, //FIXME just a placeholder for now&lt;br /&gt;
                            text: article.title&lt;br /&gt;
                        }));&lt;br /&gt;
                    }); //foreach section&lt;br /&gt;
&lt;br /&gt;
                } catch (e) {&lt;br /&gt;
                    UI.alert(e.message);&lt;br /&gt;
                }&lt;br /&gt;
            }); // download &amp;amp; populate watchlist&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            // register an event handler for the main tab, so that article specific sections can be retrieved&lt;br /&gt;
            $('div#options select#article_select', markup).change(function () {&lt;br /&gt;
                var article = this.value;&lt;br /&gt;
&lt;br /&gt;
                // HACK: try to get a login token (actually not needed just for reading ...)&lt;br /&gt;
                Host.download(&lt;br /&gt;
                    'http://wiki.flightgear.org/api.php?action=query&amp;amp;prop=info|revisions&amp;amp;intoken=edit&amp;amp;rvprop=timestamp&amp;amp;titles=Main%20Page',&lt;br /&gt;
                    function (response) {&lt;br /&gt;
                        var message =&lt;br /&gt;
                            'FlightGear wiki login status (AJAX):';&lt;br /&gt;
                        var status = response.statusText;&lt;br /&gt;
&lt;br /&gt;
                        // populate dropdown menu with article sections&lt;br /&gt;
                        if (status === 'OK') {&lt;br /&gt;
&lt;br /&gt;
                            // Resolve redirects: https://www.mediawiki.org/wiki/API:Query#Resolving_redirects&lt;br /&gt;
                            var section_url =&lt;br /&gt;
                                'http://wiki.flightgear.org/api.php?action=parse&amp;amp;page=' +&lt;br /&gt;
                                encodeURIComponent(article) +&lt;br /&gt;
                                '&amp;amp;prop=sections&amp;amp;format=json&amp;amp;redirects';&lt;br /&gt;
                            Host.download(section_url, function (&lt;br /&gt;
                                response) {&lt;br /&gt;
                                try {&lt;br /&gt;
                                    var sections = JSON&lt;br /&gt;
                                        .parse(response&lt;br /&gt;
                                            .responseText&lt;br /&gt;
                                        );&lt;br /&gt;
&lt;br /&gt;
                                    $(&lt;br /&gt;
                                        'div#options select#section_select',&lt;br /&gt;
                                        markup).empty(); // delete all sections&lt;br /&gt;
&lt;br /&gt;
                                    $.each(sections.parse&lt;br /&gt;
                                        .sections,&lt;br /&gt;
                                        function (i,&lt;br /&gt;
                                            section&lt;br /&gt;
                                        ) {&lt;br /&gt;
                                            $(&lt;br /&gt;
                                                'div#options select#section_select',&lt;br /&gt;
                                                markup&lt;br /&gt;
                                            ).append(&lt;br /&gt;
                                                $(&lt;br /&gt;
                                                    '&amp;lt;option&amp;gt;', {&lt;br /&gt;
                                                        value: section&lt;br /&gt;
                                                            .line, //FIXME just a placeholder for now&lt;br /&gt;
                                                        text: section&lt;br /&gt;
                                                            .line&lt;br /&gt;
                                                    }&lt;br /&gt;
                                                )&lt;br /&gt;
                                            );&lt;br /&gt;
                                        }); //foreach section&lt;br /&gt;
&lt;br /&gt;
                                } catch (e) {&lt;br /&gt;
                                    UI.alert(e.message);&lt;br /&gt;
                                }&lt;br /&gt;
&lt;br /&gt;
                            }); //download sections&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                        } // login status is OK&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    }); // Host.download() call, i.e. we have a login token&lt;br /&gt;
&lt;br /&gt;
            }); // on select change&lt;br /&gt;
&lt;br /&gt;
            // init the tab stuff&lt;br /&gt;
            markup.tabs();&lt;br /&gt;
&lt;br /&gt;
            var diagParam = {&lt;br /&gt;
                title: 'Instant Cquotes ' + Host.getScriptVersion(),&lt;br /&gt;
                modal: true,&lt;br /&gt;
                width: 700,&lt;br /&gt;
                buttons: [{&lt;br /&gt;
                        text: 'reported speech',&lt;br /&gt;
                        click: function () {&lt;br /&gt;
                            textarea.val(createCquote(original,&lt;br /&gt;
                                true));&lt;br /&gt;
                        }&lt;br /&gt;
                    },&lt;br /&gt;
&lt;br /&gt;
                    {&lt;br /&gt;
                        text: 'Copy',&lt;br /&gt;
                        click: function () {&lt;br /&gt;
                            Host.setClipboard(msg);&lt;br /&gt;
                            $(this).dialog('close');&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
&lt;br /&gt;
                ]&lt;br /&gt;
            };&lt;br /&gt;
&lt;br /&gt;
            // actually show our tabbed dialog using the params above&lt;br /&gt;
            markup.dialog(diagParam);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        } // jQueryTabbed()&lt;br /&gt;
&lt;br /&gt;
}; // output methods&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// TODO: we can use an online API to  help with some of this: http://www.eslnow.org/reported-speech-converter/&lt;br /&gt;
// See also: http://blog.mashape.com/list-of-25-natural-language-processing-apis/&lt;br /&gt;
// http://text-processing.com/docs/phrases.html&lt;br /&gt;
// http://www.alchemyapi.com/&lt;br /&gt;
// https://words.bighugelabs.com/api.php&lt;br /&gt;
// https://www.wordsapi.com/&lt;br /&gt;
// http://www.dictionaryapi.com/&lt;br /&gt;
// https://www.textrazor.com/&lt;br /&gt;
// http://www.programmableweb.com/news/how-5-natural-language-processing-apis-stack/analysis/2014/07/28&lt;br /&gt;
&lt;br /&gt;
var speechTransformations = [&lt;br /&gt;
    // TODO: support aliasing using vectors: would/should&lt;br /&gt;
    // ordering is crucial here (most specific first, least specific/most generic last)&lt;br /&gt;
&lt;br /&gt;
    // first, we start off  by expanding short forms: http://www.learnenglish.de/grammar/shortforms.html&lt;br /&gt;
    // http://www.macmillandictionary.com/thesaurus-category/british/short-forms&lt;br /&gt;
&lt;br /&gt;
    {&lt;br /&gt;
        query: /couldn\'t/gi,&lt;br /&gt;
        replacement: 'could not'&lt;br /&gt;
    }, {&lt;br /&gt;
        query: /I could not/gi,&lt;br /&gt;
        replacement: '$author could not'&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
    {&lt;br /&gt;
        query: /I\'m/gi,&lt;br /&gt;
        replacement: 'I am'&lt;br /&gt;
    }, {&lt;br /&gt;
        query: /I am/gi,&lt;br /&gt;
        replacement: '$author is'&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
    {&lt;br /&gt;
        query: /I\'ve/,&lt;br /&gt;
        replacement: 'I have'&lt;br /&gt;
    }, {&lt;br /&gt;
        query: /I have had/,&lt;br /&gt;
        replacement: '$author had'&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    {&lt;br /&gt;
        query: /can(\'|\’)t/gi,&lt;br /&gt;
        replacement: 'cannot'&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
    {&lt;br /&gt;
        query: /I(\'|\’)ll/gi,&lt;br /&gt;
        replacement: '$author will'&lt;br /&gt;
    }, {&lt;br /&gt;
        query: /I(\'|\’)d/gi,&lt;br /&gt;
        replacement: '$author would'&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
    {&lt;br /&gt;
        query: /I have done/gi,&lt;br /&gt;
        replacement: '$author has done'&lt;br /&gt;
    }, {&lt;br /&gt;
        query: /I\'ve done/gi,&lt;br /&gt;
        replacement: '$author has done'&lt;br /&gt;
    }, //FIXME. queries should really be vectors ...&lt;br /&gt;
&lt;br /&gt;
    {&lt;br /&gt;
        query: /I believe/gi,&lt;br /&gt;
        replacement: '$author suggested'&lt;br /&gt;
    }, {&lt;br /&gt;
        query: /I think/gi,&lt;br /&gt;
        replacement: '$author suggested'&lt;br /&gt;
    }, {&lt;br /&gt;
        query: /I guess/gi,&lt;br /&gt;
        replacement: '$author believes'&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
    {&lt;br /&gt;
        query: /I can see that/gi,&lt;br /&gt;
        replacement: '$author suggested that'&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    {&lt;br /&gt;
        query: /I have got/gi,&lt;br /&gt;
        replacement: '$author has got'&lt;br /&gt;
    }, {&lt;br /&gt;
        query: /I\'ve got/gi,&lt;br /&gt;
        replacement: '$author has got'&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
    {&lt;br /&gt;
        query: /I\'d suggest/gi,&lt;br /&gt;
        replacement: '$author would suggest'&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
    {&lt;br /&gt;
        query: /I\’m prototyping/gi,&lt;br /&gt;
        replacement: '$author is prototyping'&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
    {&lt;br /&gt;
        query: /I myself/gi,&lt;br /&gt;
        replacement: '$author himself'&lt;br /&gt;
    }, {&lt;br /&gt;
        query: /I am/gi,&lt;br /&gt;
        replacement: ' $author is'&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
    {&lt;br /&gt;
        query: /I can see/gi,&lt;br /&gt;
        replacement: '$author can see'&lt;br /&gt;
    }, {&lt;br /&gt;
        query: /I can/gi,&lt;br /&gt;
        replacement: '$author can'&lt;br /&gt;
    }, {&lt;br /&gt;
        query: /I have/gi,&lt;br /&gt;
        replacement: '$author has'&lt;br /&gt;
    }, {&lt;br /&gt;
        query: /I should/g,&lt;br /&gt;
        replacement: '$author should'&lt;br /&gt;
    }, {&lt;br /&gt;
        query: /I shall/gi,&lt;br /&gt;
        replacement: '$author shall'&lt;br /&gt;
    }, {&lt;br /&gt;
        query: /I may/gi,&lt;br /&gt;
        replacement: '$author may'&lt;br /&gt;
    }, {&lt;br /&gt;
        query: /I will/gi,&lt;br /&gt;
        replacement: '$author will'&lt;br /&gt;
    }, {&lt;br /&gt;
        query: /I would/gi,&lt;br /&gt;
        replacement: '$author would'&lt;br /&gt;
    }, {&lt;br /&gt;
        query: /by myself/gi,&lt;br /&gt;
        replacement: 'by $author'&lt;br /&gt;
    }, {&lt;br /&gt;
        query: /and I/gi,&lt;br /&gt;
        replacement: 'and $author'&lt;br /&gt;
    }, {&lt;br /&gt;
        query: /and me/gi,&lt;br /&gt;
        replacement: 'and $author'&lt;br /&gt;
    }, {&lt;br /&gt;
        query: /and myself/gi,&lt;br /&gt;
        replacement: 'and $author'&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    // least specific stuff last (broad/generic stuff is kept as is, with author clarification added in parentheses)&lt;br /&gt;
    /*&lt;br /&gt;
    {query:/I/, replacement:'I ($author)'},&lt;br /&gt;
    {query:/me/, replacement:'me ($author)'},&lt;br /&gt;
    {query:/my/, replacement:'my ($author)'},&lt;br /&gt;
    {query:/myself/, replacement:'myself ($author)'},&lt;br /&gt;
    {query:/mine/, replacement:'$author'}&lt;br /&gt;
    */&lt;br /&gt;
];&lt;br /&gt;
&lt;br /&gt;
// try to assist in transforming speech using the transformation vector passed in&lt;br /&gt;
// still needs to be exposed via the UI&lt;br /&gt;
function transformSpeech(text, author, gender, transformations) {&lt;br /&gt;
    // WIP: foreach transformation in vector, replace the search pattern with the matched string (replacing author/gender as applicable)&lt;br /&gt;
    //alert(&amp;quot;text to be transformed:\n&amp;quot;+text);&lt;br /&gt;
    for (var i = 0; i &amp;lt; transformations.length; i++) {&lt;br /&gt;
        var token = transformations[i];&lt;br /&gt;
        // patch the replacement string using the correct author name&lt;br /&gt;
        var replacement = token.replacement.replace(/\$author/gi, author);&lt;br /&gt;
        text = text.replace(token.query, replacement);&lt;br /&gt;
    } // end of token transformation&lt;br /&gt;
    console.log(&amp;quot;transformed text is:&amp;quot; + text);&lt;br /&gt;
    return text;&lt;br /&gt;
} // transformSpeech&lt;br /&gt;
&lt;br /&gt;
// run a self-test&lt;br /&gt;
&lt;br /&gt;
(function () {&lt;br /&gt;
    var author = &amp;quot;John Doe&amp;quot;;&lt;br /&gt;
    var transformed = transformSpeech(&lt;br /&gt;
        &amp;quot;I have decided to commit a new feature&amp;quot;, author, null,&lt;br /&gt;
        speechTransformations);&lt;br /&gt;
    if (transformed !== author + &amp;quot; has decided to commit a new feature&amp;quot;)&lt;br /&gt;
        Host.dbLog(&lt;br /&gt;
            &amp;quot;FIXME: Speech transformations are not working correctly&amp;quot;);&lt;br /&gt;
})();&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
var MONTHS = [&lt;br /&gt;
    'Jan',&lt;br /&gt;
    'Feb',&lt;br /&gt;
    'Mar',&lt;br /&gt;
    'Apr',&lt;br /&gt;
    'May',&lt;br /&gt;
    'Jun',&lt;br /&gt;
    'Jul',&lt;br /&gt;
    'Aug',&lt;br /&gt;
    'Sep',&lt;br /&gt;
    'Oct',&lt;br /&gt;
    'Nov',&lt;br /&gt;
    'Dec'&lt;br /&gt;
];&lt;br /&gt;
// Conversion for forum emoticons&lt;br /&gt;
var EMOTICONS = [&lt;br /&gt;
    [/:shock:/g,&lt;br /&gt;
        'O_O'&lt;br /&gt;
    ],&lt;br /&gt;
    [&lt;br /&gt;
        /:lol:/g,&lt;br /&gt;
        '(lol)'&lt;br /&gt;
    ],&lt;br /&gt;
    [&lt;br /&gt;
        /:oops:/g,&lt;br /&gt;
        ':$'&lt;br /&gt;
    ],&lt;br /&gt;
    [&lt;br /&gt;
        /:cry:/g,&lt;br /&gt;
        ';('&lt;br /&gt;
    ],&lt;br /&gt;
    [&lt;br /&gt;
        /:evil:/g,&lt;br /&gt;
        '&amp;gt;:)'&lt;br /&gt;
    ],&lt;br /&gt;
    [&lt;br /&gt;
        /:twisted:/g,&lt;br /&gt;
        '3:)'&lt;br /&gt;
    ],&lt;br /&gt;
    [&lt;br /&gt;
        /:roll:/g,&lt;br /&gt;
        '(eye roll)'&lt;br /&gt;
    ],&lt;br /&gt;
    [&lt;br /&gt;
        /:wink:/g,&lt;br /&gt;
        ';)'&lt;br /&gt;
    ],&lt;br /&gt;
    [&lt;br /&gt;
        /:!:/g,&lt;br /&gt;
        '(!)'&lt;br /&gt;
    ],&lt;br /&gt;
    [&lt;br /&gt;
        /:\?:/g,&lt;br /&gt;
        '(?)'&lt;br /&gt;
    ],&lt;br /&gt;
    [&lt;br /&gt;
        /:idea:/g,&lt;br /&gt;
        '(idea)'&lt;br /&gt;
    ],&lt;br /&gt;
    [&lt;br /&gt;
        /:arrow:/g,&lt;br /&gt;
        '(-&amp;gt;)'&lt;br /&gt;
    ],&lt;br /&gt;
    [&lt;br /&gt;
        /:mrgreen:/g,&lt;br /&gt;
        'xD'&lt;br /&gt;
    ]&lt;br /&gt;
];&lt;br /&gt;
// ##################&lt;br /&gt;
// # Main functions #&lt;br /&gt;
// ##################&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// the required trigger is host specific (userscript vs. addon vs. android etc)&lt;br /&gt;
// for now, this merely wraps window.load mapping to the instantCquote callback&lt;br /&gt;
// below&lt;br /&gt;
Host.registerTrigger();&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// FIXME: function is currently referenced in CONFIG hash - event_handler, so&lt;br /&gt;
// cannot be easily moved across&lt;br /&gt;
// The main function&lt;br /&gt;
// TODO: split up, so that we can reuse the code elsewhere&lt;br /&gt;
function instantCquote(sel) {&lt;br /&gt;
    var profile = getProfile();&lt;br /&gt;
&lt;br /&gt;
    // TODO: use config hash here&lt;br /&gt;
    var selection = document.getSelection(),&lt;br /&gt;
        post_id = 0;&lt;br /&gt;
&lt;br /&gt;
    try {&lt;br /&gt;
        post_id = getPostId(selection, profile);&lt;br /&gt;
    } catch (error) {&lt;br /&gt;
        Host.dbLog('Failed extracting post id\nProfile:' + profile);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    if (selection.toString() === '') {&lt;br /&gt;
        Host.dbLog('No text is selected, aborting function');&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    if (!checkValid(selection, profile)) {&lt;br /&gt;
        Host.dbLog('Selection is not valid, aborting function');&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    try {&lt;br /&gt;
        transformationLoop(profile, post_id);&lt;br /&gt;
    } catch (e) {&lt;br /&gt;
        UI.alert(&amp;quot;Transformation loop:\n&amp;quot; + e.message);&lt;br /&gt;
    }&lt;br /&gt;
} // instantCquote&lt;br /&gt;
&lt;br /&gt;
// TODO: this needs to be refactored so that it can be also reused by the async/AJAX mode&lt;br /&gt;
// to extract fields in the background (i.e. move to a separate function)&lt;br /&gt;
function transformationLoop(profile, post_id) {&lt;br /&gt;
    var output = {},&lt;br /&gt;
        field;&lt;br /&gt;
    Host.dbLog(&amp;quot;Starting extraction/transformation loop&amp;quot;);&lt;br /&gt;
    for (field in profile) {&lt;br /&gt;
        if (field === 'name') continue;&lt;br /&gt;
        if (field === 'type' || field === 'event' || field === 'event_handler')&lt;br /&gt;
            continue; // skip fields that don't contain xpath expressions&lt;br /&gt;
        Host.dbLog(&amp;quot;Extracting field using field id:&amp;quot; + post_id);&lt;br /&gt;
        var fieldData = extractFieldInfo(profile, post_id, field);&lt;br /&gt;
        var transform = profile[field].transform;&lt;br /&gt;
        if (transform !== undefined) {&lt;br /&gt;
            Host.dbLog('Field \'' + field + '\' before transformation:\n\'' +&lt;br /&gt;
                fieldData + '\'');&lt;br /&gt;
            fieldData = applyTransformations(fieldData, transform);&lt;br /&gt;
            Host.dbLog('Field \'' + field + '\' after transformation:\n\'' +&lt;br /&gt;
                fieldData + '\'');&lt;br /&gt;
        }&lt;br /&gt;
        output[field] = fieldData;&lt;br /&gt;
    } // extract and transform all fields for the current profile (website)&lt;br /&gt;
    Host.dbLog(&amp;quot;extraction and transformation loop finished&amp;quot;);&lt;br /&gt;
    output.content = stripWhitespace(output.content);&lt;br /&gt;
&lt;br /&gt;
    var outputPlain = createCquote(output);&lt;br /&gt;
    outputText(outputPlain, output);&lt;br /&gt;
} // transformationLoop()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/// #############&lt;br /&gt;
&lt;br /&gt;
function runProfileTests() {&lt;br /&gt;
&lt;br /&gt;
    for (var profile in CONFIG) {&lt;br /&gt;
        if (CONFIG[profile].type != 'archive' || !CONFIG[profile].enabled)&lt;br /&gt;
            continue; // skip the wiki entry, because it's not an actual archive that we need to test&lt;br /&gt;
        // should be really moved to downloadPostign&lt;br /&gt;
        if (CONFIG[profile].content.xpath === '') console.log(&lt;br /&gt;
            &amp;quot;xpath for content extraction is empty, cannot procedurally extract contents&amp;quot;&lt;br /&gt;
        );&lt;br /&gt;
        for (var test in CONFIG[profile].tests) {&lt;br /&gt;
            var required_data = CONFIG[profile].tests[test];&lt;br /&gt;
            var title = required_data.title;&lt;br /&gt;
            //dbLog('Running test for posting titled:' + title);&lt;br /&gt;
            // fetch posting via getPostingDataAJAX() and compare to the fields we are looking for (author, title, date)&lt;br /&gt;
            //getPostingDataAJAX(profile, required_data.url);&lt;br /&gt;
            //alert(&amp;quot;required title:&amp;quot;+title);&lt;br /&gt;
        } // foreach test&lt;br /&gt;
&lt;br /&gt;
    } // foreach profile (website)&lt;br /&gt;
&lt;br /&gt;
} //runProfileTests&lt;br /&gt;
&lt;br /&gt;
function selfCheckDialog() {&lt;br /&gt;
    var sections = '&amp;lt;h3&amp;gt;Important APIs:&amp;lt;/h3&amp;gt;&amp;lt;div id=&amp;quot;api_checks&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;';&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    try {&lt;br /&gt;
        runProfileTests.call(undefined); // check website profiles&lt;br /&gt;
    } catch (e) {&lt;br /&gt;
        UI.alert(e.message);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (var profile in CONFIG) {&lt;br /&gt;
        // TODO: also check if enabled or not&lt;br /&gt;
        if (CONFIG[profile].type != 'archive') continue; // skip the wiki entry, because it's not an actual archive that we need to test&lt;br /&gt;
        var test_results = '';&lt;br /&gt;
        for (var test in CONFIG[profile].tests) {&lt;br /&gt;
            // var fieldData = extractFieldInfo(profile, post_id, 'author');&lt;br /&gt;
            test_results += CONFIG[profile].tests[test].title + '&amp;lt;p/&amp;gt;';&lt;br /&gt;
        }&lt;br /&gt;
        sections += '&amp;lt;h3&amp;gt;' + profile + ':&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;' + CONFIG[profile]&lt;br /&gt;
            .url_reg + '&amp;lt;/font&amp;gt;&amp;lt;/h3&amp;gt;&amp;lt;div&amp;gt;&amp;lt;p&amp;gt;' + test_results + '&amp;lt;/p&amp;gt;&amp;lt;/div&amp;gt;\n';&lt;br /&gt;
    } // https://jqueryui.com/accordion/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    var checkDlg = $(&lt;br /&gt;
        '&amp;lt;div id=&amp;quot;selfCheck&amp;quot; title=&amp;quot;Self Check dialog&amp;quot;&amp;gt;&amp;lt;p&amp;gt;&amp;lt;div id=&amp;quot;accordion&amp;quot;&amp;gt;' +&lt;br /&gt;
        sections + '&amp;lt;/div&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;/div&amp;gt;');&lt;br /&gt;
&lt;br /&gt;
    // run all API tests, invoke the callback to obtain the status&lt;br /&gt;
    Environment.runAPITests(Host, function (meta) {&lt;br /&gt;
&lt;br /&gt;
        //console.log('Running API test '+meta.name);&lt;br /&gt;
&lt;br /&gt;
        meta.test(function (result) {&lt;br /&gt;
            var status = (result) ? 'success' : 'fail';&lt;br /&gt;
            var test = $(&amp;quot;&amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&amp;quot;).text('Running API test ' +&lt;br /&gt;
                meta.name + ':' + status);&lt;br /&gt;
            $('#api_checks', checkDlg).append(test);&lt;br /&gt;
        }); // update tests results&lt;br /&gt;
&lt;br /&gt;
    }); // runAPITests&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
    [].forEach.call(CONFIG, function(profile) {&lt;br /&gt;
      alert(&amp;quot;profile is:&amp;quot;+profile);&lt;br /&gt;
    [].forEach.call(CONFIG[profile].tests, function(test) {&lt;br /&gt;
&lt;br /&gt;
      //UI.alert(test.url);&lt;br /&gt;
      Host.downloadPosting(test.url, function(downloaded) {&lt;br /&gt;
        alert(&amp;quot;downloaded:&amp;quot;);&lt;br /&gt;
        //if (test.title == downloaded.title) alert(&amp;quot;titles match:&amp;quot;+test.title);&lt;br /&gt;
      }); //downloadPosting&lt;br /&gt;
    }); //forEach test&lt;br /&gt;
    }); //forEach profile&lt;br /&gt;
    */&lt;br /&gt;
&lt;br /&gt;
    //$('#accordion',checkDlg).accordion();&lt;br /&gt;
    checkDlg.dialog({&lt;br /&gt;
        width: 700,&lt;br /&gt;
        height: 500,&lt;br /&gt;
        open: function () {&lt;br /&gt;
            // http://stackoverflow.com/questions/2929487/putting-a-jquery-ui-accordion-in-a-jquery-ui-dialog&lt;br /&gt;
            $('#accordion').accordion({&lt;br /&gt;
                autoHeight: true&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }); // show dialog&lt;br /&gt;
} // selfCheckDialog&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// show a simple configuration dialog (WIP)&lt;br /&gt;
function setupDialog() {&lt;br /&gt;
    //alert(&amp;quot;configuration dialog is not yet implemented&amp;quot;);&lt;br /&gt;
    var checked = (Host.get_persistent('debug_mode_enabled', false) === true) ?&lt;br /&gt;
        'checked' : '';&lt;br /&gt;
    //dbLog(&amp;quot;value is:&amp;quot;+get_persistent(&amp;quot;debug_mode_enabled&amp;quot;));&lt;br /&gt;
    //dbLog(&amp;quot;persistent debug flag is:&amp;quot;+checked);&lt;br /&gt;
    var setupDiv = $(&lt;br /&gt;
        '&amp;lt;div id=&amp;quot;setupDialog&amp;quot; title=&amp;quot;Setup dialog&amp;quot;&amp;gt;NOTE: this configuration dialog is still work-in-progress&amp;lt;/p&amp;gt;&amp;lt;label&amp;gt;&amp;lt;input id=&amp;quot;debugcb&amp;quot; type=&amp;quot;checkbox&amp;quot;' +&lt;br /&gt;
        checked +&lt;br /&gt;
        '&amp;gt;Enable Debug mode&amp;lt;/label&amp;gt;&amp;lt;p/&amp;gt;&amp;lt;div id=&amp;quot;progressbar&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;');&lt;br /&gt;
    setupDiv.click(function () {&lt;br /&gt;
        //alert(&amp;quot;changing persistent debug state&amp;quot;);&lt;br /&gt;
        Host.set_persistent('debug_mode_enabled', $('#debugcb').is(&lt;br /&gt;
            ':checked'));&lt;br /&gt;
    });&lt;br /&gt;
    //MediaWiki editing stub, based on: https://www.mediawiki.org/wiki/API:Edit#Editing_via_Ajax&lt;br /&gt;
    //only added here to show some status info in the setup dialog&lt;br /&gt;
    Host.download(&lt;br /&gt;
        'http://wiki.flightgear.org/api.php?action=query&amp;amp;prop=info|revisions&amp;amp;intoken=edit&amp;amp;rvprop=timestamp&amp;amp;titles=Main%20Page',&lt;br /&gt;
        function (response) {&lt;br /&gt;
            var message = 'FlightGear wiki login status (AJAX):';&lt;br /&gt;
            var status = response.statusText;&lt;br /&gt;
            var color = (status == 'OK') ? 'green' : 'red';&lt;br /&gt;
            Host.dbLog(message + status);&lt;br /&gt;
            var statusDiv = $('&amp;lt;p&amp;gt;' + message + status + '&amp;lt;/p&amp;gt;').css(&lt;br /&gt;
                'color', color);&lt;br /&gt;
            setupDiv.append(statusDiv);&lt;br /&gt;
        });&lt;br /&gt;
    setupDiv.dialog();&lt;br /&gt;
} // setupDialog&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// this  can be used to download/cache $FG_ROOT/options.xml so that fgfs CLI arguments can be recognized and post-processed automatically&lt;br /&gt;
// which can help transforming postings correctly&lt;br /&gt;
function downloadOptionsXML() {&lt;br /&gt;
&lt;br /&gt;
    // download $FG_ROOT/options.xml&lt;br /&gt;
    Host.download(&lt;br /&gt;
        &amp;quot;https://sourceforge.net/p/flightgear/fgdata/ci/next/tree/options.xml?format=raw&amp;quot;,&lt;br /&gt;
        function (response) {&lt;br /&gt;
            var xml = response.responseText;&lt;br /&gt;
            var doc = Host.make_doc(xml, 'text/xml');&lt;br /&gt;
            // https://developer.mozilla.org/en-US/docs/Web/API/XPathResult&lt;br /&gt;
            var options = Host.eval_xpath(doc, '//*/option', XPathResult.ORDERED_NODE_SNAPSHOT_TYPE);&lt;br /&gt;
&lt;br /&gt;
            // http://help.dottoro.com/ljgnejkp.php&lt;br /&gt;
            Host.dbLog(&amp;quot;Number of options found in options.xml:&amp;quot; + options.snapshotLength);&lt;br /&gt;
&lt;br /&gt;
            // http://help.dottoro.com/ljtfvvpx.php&lt;br /&gt;
&lt;br /&gt;
            // https://sourceforge.net/p/flightgear/fgdata/ci/next/tree/options.xml&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        }); // end of options.xml download&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
} // downloadOptionsXML&lt;br /&gt;
&lt;br /&gt;
function getProfile(url = undefined) {&lt;br /&gt;
&lt;br /&gt;
    if (url === undefined)&lt;br /&gt;
        url = window.location.href;&lt;br /&gt;
    else&lt;br /&gt;
        url = url;&lt;br /&gt;
&lt;br /&gt;
    Host.dbLog(&amp;quot;getProfile call URL is:&amp;quot; + url);&lt;br /&gt;
&lt;br /&gt;
    for (var profile in CONFIG) {&lt;br /&gt;
        if (url.match(CONFIG[profile].url_reg) !== null) {&lt;br /&gt;
            Host.dbLog('Matching website profile found');&lt;br /&gt;
            var invocations = Host.get_persistent(Host.getScriptVersion(), 0);&lt;br /&gt;
            Host.dbLog('Number of script invocations for version ' + Host.getScriptVersion() +&lt;br /&gt;
                ' is:' + invocations);&lt;br /&gt;
&lt;br /&gt;
            // determine if we want to show a config dialog&lt;br /&gt;
            if (invocations === 0) {&lt;br /&gt;
                Host.dbLog(&amp;quot;ask for config dialog to be shown&amp;quot;);&lt;br /&gt;
                var response = UI.confirm(&lt;br /&gt;
                    'This is your first time running version ' + Host.getScriptVersion() +&lt;br /&gt;
                    '\nConfigure now?');&lt;br /&gt;
                if (response) {&lt;br /&gt;
&lt;br /&gt;
                    // show configuration dialog (jQuery)&lt;br /&gt;
                    setupDialog();&lt;br /&gt;
                } else {} // don't configure&lt;br /&gt;
&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // increment number of invocations, use the script's version number as the key, to prevent the config dialog from showing up again (except for updated scripts)&lt;br /&gt;
            // FIXME: this is triggered/incremented by each click ...&lt;br /&gt;
            Host.dbLog(&amp;quot;increment number of script invocations&amp;quot;);&lt;br /&gt;
            Host.set_persistent(Host.getScriptVersion(), invocations + 1);&lt;br /&gt;
            return CONFIG[profile];&lt;br /&gt;
        } // matched website profile&lt;br /&gt;
        Host.dbLog('Could not find matching URL in getProfile() call!');&lt;br /&gt;
    } // for each profile&lt;br /&gt;
} // Get the HTML code that is selected&lt;br /&gt;
&lt;br /&gt;
function getSelectedHtml() {&lt;br /&gt;
    // From http://stackoverflow.com/a/6668159&lt;br /&gt;
    var html = '',&lt;br /&gt;
        selection = document.getSelection();&lt;br /&gt;
    if (selection.rangeCount) {&lt;br /&gt;
        var container = document.createElement('div');&lt;br /&gt;
        for (var i = 0; i &amp;lt; selection.rangeCount; i++) {&lt;br /&gt;
            container.appendChild(selection.getRangeAt(i).cloneContents());&lt;br /&gt;
        }&lt;br /&gt;
        html = container.innerHTML;&lt;br /&gt;
    }&lt;br /&gt;
    Host.dbLog('instantCquote(): Unprocessed HTML\n\'' + html + '\'');&lt;br /&gt;
    return html;&lt;br /&gt;
} // Gets the selected text&lt;br /&gt;
&lt;br /&gt;
function getSelectedText() {&lt;br /&gt;
    return document.getSelection().toString();&lt;br /&gt;
} // Get the ID of the post&lt;br /&gt;
// (this needs some work so that it can be used by the AJAX mode, without an actual selection)&lt;br /&gt;
&lt;br /&gt;
function getPostId(selection, profile, focus) {&lt;br /&gt;
    if (focus !== undefined) {&lt;br /&gt;
        Host.dbLog(&amp;quot;Trying to get PostId with defined focus&amp;quot;);&lt;br /&gt;
        selection = selection.focusNode.parentNode;&lt;br /&gt;
    } else {&lt;br /&gt;
        Host.dbLog(&amp;quot;Trying to get PostId with undefined focus&amp;quot;);&lt;br /&gt;
        selection = selection.anchorNode.parentNode;&lt;br /&gt;
    }&lt;br /&gt;
    while (selection.id.match(profile.content.idStyle) === null) {&lt;br /&gt;
        selection = selection.parentNode;&lt;br /&gt;
    }&lt;br /&gt;
    Host.dbLog(&amp;quot;Selection id is:&amp;quot; + selection.id);&lt;br /&gt;
    return selection.id;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Checks that the selection is valid&lt;br /&gt;
function checkValid(selection, profile) {&lt;br /&gt;
    var ret = true,&lt;br /&gt;
        selection_cp = {},&lt;br /&gt;
        tags = profile.content.parentTag;&lt;br /&gt;
    for (var n = 0; n &amp;lt; 2; n++) {&lt;br /&gt;
        if (n === 0) {&lt;br /&gt;
            selection_cp = selection.anchorNode.parentNode;&lt;br /&gt;
        } else {&lt;br /&gt;
            selection_cp = selection.focusNode.parentNode;&lt;br /&gt;
        }&lt;br /&gt;
        while (true) {&lt;br /&gt;
            if (selection_cp.tagName === 'BODY') {&lt;br /&gt;
                ret = false;&lt;br /&gt;
                break;&lt;br /&gt;
            } else {&lt;br /&gt;
                var cont = false;&lt;br /&gt;
                for (var i = 0; i &amp;lt; tags.length; i++) {&lt;br /&gt;
                    if (selection_cp[tags[0]] === tags[i]) {&lt;br /&gt;
                        cont = true;&lt;br /&gt;
                        break;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                if (cont) {&lt;br /&gt;
                    break;&lt;br /&gt;
                } else {&lt;br /&gt;
                    selection_cp = selection_cp.parentNode;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    ret = ret &amp;amp;&amp;amp; (getPostId(selection, profile) === getPostId(selection,&lt;br /&gt;
        profile, 1));&lt;br /&gt;
    return ret;&lt;br /&gt;
} // Extracts the raw text from a certain place, using an XPath&lt;br /&gt;
&lt;br /&gt;
function extractFieldInfo(profile, id, field) {&lt;br /&gt;
&lt;br /&gt;
    if (field === 'content') {&lt;br /&gt;
        Host.dbLog(&amp;quot;Returning content (selection)&amp;quot;);&lt;br /&gt;
        return profile[field].selection();&lt;br /&gt;
    } else {&lt;br /&gt;
        Host.dbLog(&amp;quot;Extracting field via xpath:&amp;quot; + field);&lt;br /&gt;
        var xpath = '//*[@id=&amp;quot;' + id + '&amp;quot;]/' + profile[field].xpath;&lt;br /&gt;
        return Host.eval_xpath(document, xpath).stringValue; // document.evaluate(xpath, document, null, XPathResult.STRING_TYPE, null).stringValue;&lt;br /&gt;
    }&lt;br /&gt;
} // Change the text using specified transformations&lt;br /&gt;
&lt;br /&gt;
function applyTransformations(fieldInfo, trans) {&lt;br /&gt;
    for (var i = 0; i &amp;lt; trans.length; i++) {&lt;br /&gt;
        fieldInfo = trans[i](fieldInfo);&lt;br /&gt;
        Host.dbLog(&lt;br /&gt;
            'applyTransformations(): Multiple transformation, transformation after loop #' +&lt;br /&gt;
            (i + 1) + ':\n\'' + fieldInfo + '\'');&lt;br /&gt;
    }&lt;br /&gt;
    return fieldInfo;&lt;br /&gt;
&lt;br /&gt;
} //applyTransformations&lt;br /&gt;
&lt;br /&gt;
// Formats the quote&lt;br /&gt;
&lt;br /&gt;
function createCquote(data, indirect_speech = false) {&lt;br /&gt;
    if (!indirect_speech)&lt;br /&gt;
        return nonQuotedRef(data); // conventional/verbatim selection&lt;br /&gt;
    else {&lt;br /&gt;
        // pattern match the content using a vector of regexes&lt;br /&gt;
        data.content = transformSpeech(data.content, data.author, null,&lt;br /&gt;
            speechTransformations);&lt;br /&gt;
        return nonQuotedRef(data);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function nonQuotedRef(data) { //TODO: rename&lt;br /&gt;
    var template = Host.getTemplate();&lt;br /&gt;
&lt;br /&gt;
    var substituted = template&lt;br /&gt;
        .replace('$CONTENT', data.content)&lt;br /&gt;
        .replace('$URL', data.url)&lt;br /&gt;
        .replace('$TITLE', data.title)&lt;br /&gt;
        .replace('$AUTHOR', data.author)&lt;br /&gt;
        .replace('$DATE', datef(data.date))&lt;br /&gt;
        .replace('$ADDED', datef(data.date))&lt;br /&gt;
        .replace('$SCRIPT_VERSION', Host.getScriptVersion());&lt;br /&gt;
&lt;br /&gt;
    return substituted;&lt;br /&gt;
} // &lt;br /&gt;
&lt;br /&gt;
// Output the text.&lt;br /&gt;
// Tries the jQuery dialog, and falls back to window.prompt()&lt;br /&gt;
&lt;br /&gt;
function outputText(msg, original) {&lt;br /&gt;
    try {&lt;br /&gt;
        OUTPUT.jQueryTabbed(msg, original);&lt;br /&gt;
    } catch (err) {&lt;br /&gt;
        msg = msg.replace(/&amp;amp;lt;\/syntaxhighligh(.)&amp;gt;/g, '&amp;lt;/syntaxhighligh$1');&lt;br /&gt;
        OUTPUT.msgbox(msg);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// #############&lt;br /&gt;
// # Utilities #&lt;br /&gt;
// #############&lt;br /&gt;
&lt;br /&gt;
function extract(regex) {&lt;br /&gt;
    return function (text) {&lt;br /&gt;
        return text.match(regex)[1];&lt;br /&gt;
    };&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function prepend(prefix) {&lt;br /&gt;
    return function (text) {&lt;br /&gt;
        return prefix + text;&lt;br /&gt;
    };&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function removeComments(html) {&lt;br /&gt;
    return html.replace(/&amp;lt;!--.*?--&amp;gt;/g, '');&lt;br /&gt;
} // Not currently used (as of June 2015), but kept just in case&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// currently unused&lt;br /&gt;
function escapePipes(html) {&lt;br /&gt;
    html = html.replace(/\|\|/g, '{{!!}n}');&lt;br /&gt;
    html = html.replace(/\|\-/g, '{{!-}}');&lt;br /&gt;
    return html.replace(/\|/g, '{{!}}');&lt;br /&gt;
} // Converts HTML &amp;lt;a href=&amp;quot;...&amp;quot;&amp;gt;...&amp;lt;/a&amp;gt; tags to wiki links, internal if possible.&lt;br /&gt;
&lt;br /&gt;
function a2wikilink(html) {&lt;br /&gt;
    // Links to wiki images, because&lt;br /&gt;
    // they need special treatment, or else they get displayed.&lt;br /&gt;
    html = html.replace(&lt;br /&gt;
        /&amp;lt;a.*?href=&amp;quot;http:\/\/wiki\.flightgear\.org\/File:(.*?)&amp;quot;.*?&amp;gt;(.*?)&amp;lt;\/a&amp;gt;/g,&lt;br /&gt;
        '[[Media:$1|$2]]');&lt;br /&gt;
    // Wiki links without custom text.&lt;br /&gt;
    html = html.replace(&lt;br /&gt;
        /&amp;lt;a.*?href=&amp;quot;http:\/\/wiki\.flightgear\.org\/(.*?)&amp;quot;.*?&amp;gt;http:\/\/wiki\.flightgear\.org\/.*?&amp;lt;\/a&amp;gt;/g,&lt;br /&gt;
        '[[$1]]');&lt;br /&gt;
    // Links to the wiki with custom text&lt;br /&gt;
    html = html.replace(&lt;br /&gt;
        /&amp;lt;a.*?href=&amp;quot;http:\/\/wiki\.flightgear\.org\/(.*?)&amp;quot;.*?&amp;gt;(.*?)&amp;lt;\/a&amp;gt;/g,&lt;br /&gt;
        '[[$1|$2]]');&lt;br /&gt;
    // Remove underscores from all wiki links&lt;br /&gt;
    var list = html.match(/\[\[.*?\]\]/g);&lt;br /&gt;
    if (list !== null) {&lt;br /&gt;
        for (var i = 0; i &amp;lt; list.length; i++) {&lt;br /&gt;
            html = html.replace(list[i], underscore2Space(list[i]));&lt;br /&gt;
        }&lt;br /&gt;
    } // Convert non-wiki links&lt;br /&gt;
    // TODO: identify forum/devel list links, and use the AJAX/Host.download helper to get a title/subject for unnamed links (using the existing xpath/regex helpers for that)&lt;br /&gt;
&lt;br /&gt;
    html = html.replace(/&amp;lt;a.*?href=&amp;quot;(.*?)&amp;quot;.*?&amp;gt;(.*?)&amp;lt;\/a&amp;gt;/g, '[$1 $2]');&lt;br /&gt;
    // Remove triple dots from external links.&lt;br /&gt;
    // Replace with raw URL (MediaWiki converts it to a link).&lt;br /&gt;
    list = html.match(/\[.*?(\.\.\.).*?\]/g);&lt;br /&gt;
    if (list !== null) {&lt;br /&gt;
        for (var i = 0; i &amp;lt; list.length; i++) {&lt;br /&gt;
            html = html.replace(list[i], list[i].match(/\[(.*?) .*?\]/)[1]);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return html;&lt;br /&gt;
} // Converts images, including images in &amp;lt;a&amp;gt; links&lt;br /&gt;
&lt;br /&gt;
function img2link(html) {&lt;br /&gt;
    html = html.replace(&lt;br /&gt;
        /&amp;lt;a[^&amp;lt;]*?href=&amp;quot;([^&amp;lt;]*?)&amp;quot;[^&amp;lt;]*?&amp;gt;&amp;lt;img.*?src=&amp;quot;http:\/\/wiki\.flightgear\.org\/images\/.*?\/.*?\/(.*?)&amp;quot;.*?&amp;gt;&amp;lt;\/a&amp;gt;/g,&lt;br /&gt;
        '[[File:$2|250px|link=$1]]');&lt;br /&gt;
    html = html.replace(&lt;br /&gt;
        /&amp;lt;img.*?src=&amp;quot;http:\/\/wiki\.flightgear\.org\/images\/.*?\/.*?\/(.*?)&amp;quot;.*?&amp;gt;/g,&lt;br /&gt;
        '[[File:$1|250px]]');&lt;br /&gt;
    html = html.replace(&lt;br /&gt;
        /&amp;lt;a[^&amp;lt;]*?href=&amp;quot;([^&amp;lt;]*?)&amp;quot;[^&amp;lt;]*?&amp;gt;&amp;lt;img.*?src=&amp;quot;(.*?)&amp;quot;.*?&amp;gt;&amp;lt;\/a&amp;gt;/g,&lt;br /&gt;
        '(see [$2 image], links to [$1 here])');&lt;br /&gt;
    return html.replace(/&amp;lt;img.*?src=&amp;quot;(.*?)&amp;quot;.*?&amp;gt;/g,&lt;br /&gt;
        '(see the [$1 linked image])');&lt;br /&gt;
} // Converts smilies&lt;br /&gt;
&lt;br /&gt;
function forum_smilies2text(html) {&lt;br /&gt;
    html = html.replace(&lt;br /&gt;
        /&amp;lt;img src=&amp;quot;\.\/images\/smilies\/icon_.*?\.gif&amp;quot; alt=&amp;quot;(.*?)&amp;quot;.*?&amp;gt;/g,&lt;br /&gt;
        '$1');&lt;br /&gt;
    for (var i = 0; i &amp;lt; EMOTICONS.length; i++) {&lt;br /&gt;
        html = html.replace(EMOTICONS[i][0], EMOTICONS[i][1]);&lt;br /&gt;
    }&lt;br /&gt;
    return html;&lt;br /&gt;
} // Converts font formatting&lt;br /&gt;
&lt;br /&gt;
function forum_fontstyle2wikistyle(html) {&lt;br /&gt;
    html = html.replace(/&amp;lt;span style=&amp;quot;font-weight: bold&amp;quot;&amp;gt;(.*?)&amp;lt;\/span&amp;gt;/g,&lt;br /&gt;
        '\'\'\'$1\'\'\'');&lt;br /&gt;
    html = html.replace(&lt;br /&gt;
        /&amp;lt;span style=&amp;quot;text-decoration: underline&amp;quot;&amp;gt;(.*?)&amp;lt;\/span&amp;gt;/g,&lt;br /&gt;
        '&amp;lt;u&amp;gt;$1&amp;lt;/u&amp;gt;');&lt;br /&gt;
    html = html.replace(/&amp;lt;span style=&amp;quot;font-style: italic&amp;quot;&amp;gt;(.*?)&amp;lt;\/span&amp;gt;/g,&lt;br /&gt;
        '\'\'$1\'\'');&lt;br /&gt;
    return html.replace(/&amp;lt;span class=&amp;quot;posthilit&amp;quot;&amp;gt;(.*?)&amp;lt;\/span&amp;gt;/g, '$1');&lt;br /&gt;
} // Converts code blocks&lt;br /&gt;
&lt;br /&gt;
function forum_code2syntaxhighlight(html) {&lt;br /&gt;
    var list = html.match(&lt;br /&gt;
            /&amp;lt;dl class=&amp;quot;codebox&amp;quot;&amp;gt;.*?&amp;lt;code&amp;gt;(.*?)&amp;lt;\/code&amp;gt;.*?&amp;lt;\/dl&amp;gt;/g),&lt;br /&gt;
        data = [];&lt;br /&gt;
    if (list === null) return html;&lt;br /&gt;
    for (var n = 0; n &amp;lt; list.length; n++) {&lt;br /&gt;
        data = html.match(/&amp;lt;dl class=&amp;quot;codebox&amp;quot;&amp;gt;.*?&amp;lt;code&amp;gt;(.*?)&amp;lt;\/code&amp;gt;.*?&amp;lt;\/dl&amp;gt;/);&lt;br /&gt;
        html = html.replace(data[0], processCode(data));&lt;br /&gt;
    }&lt;br /&gt;
    return html;&lt;br /&gt;
} // Strips any whitespace from the beginning and end of a string&lt;br /&gt;
&lt;br /&gt;
function stripWhitespace(html) {&lt;br /&gt;
    html = html.replace(/^\s*?(\S)/, '$1');&lt;br /&gt;
    return html.replace(/(\S)\s*?\z/, '$1');&lt;br /&gt;
} // Process code, including basic detection of language&lt;br /&gt;
&lt;br /&gt;
function processCode(data) {&lt;br /&gt;
    var lang = '',&lt;br /&gt;
        code = data[1];&lt;br /&gt;
    code = code.replace(/&amp;amp;nbsp;/g, ' ');&lt;br /&gt;
    if (code.match(/=?.*?\(?.*?\)?;/) !== null) lang = 'nasal';&lt;br /&gt;
    if (code.match(/&amp;amp;lt;.*?&amp;amp;gt;.*?&amp;amp;lt;\/.*?&amp;amp;gt;/) !== null || code.match(&lt;br /&gt;
            /&amp;amp;lt;!--.*?--&amp;amp;gt;/) !== null) lang = 'xml';&lt;br /&gt;
    code = code.replace(/&amp;lt;br\/?&amp;gt;/g, '\n');&lt;br /&gt;
    return '&amp;lt;syntaxhighlight lang=&amp;quot;' + lang + '&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;\n' + code +&lt;br /&gt;
        '\n&amp;amp;lt;/syntaxhighlight&amp;gt;';&lt;br /&gt;
} // Converts quote blocks to Cquotes&lt;br /&gt;
&lt;br /&gt;
function forum_quote2cquote(html) {&lt;br /&gt;
    html = html.replace(&lt;br /&gt;
        /&amp;lt;blockquote class=&amp;quot;uncited&amp;quot;&amp;gt;&amp;lt;div&amp;gt;(.*?)&amp;lt;\/div&amp;gt;&amp;lt;\/blockquote&amp;gt;/g,&lt;br /&gt;
        '{{cquote|$1}}');&lt;br /&gt;
    if (html.match(/&amp;lt;blockquote&amp;gt;/g) === null) return html;&lt;br /&gt;
    var numQuotes = html.match(/&amp;lt;blockquote&amp;gt;/g).length;&lt;br /&gt;
    for (var n = 0; n &amp;lt; numQuotes; n++) {&lt;br /&gt;
        html = html.replace(&lt;br /&gt;
            /&amp;lt;blockquote&amp;gt;&amp;lt;div&amp;gt;&amp;lt;cite&amp;gt;(.*?) wrote.*?:&amp;lt;\/cite&amp;gt;(.*?)&amp;lt;\/div&amp;gt;&amp;lt;\/blockquote&amp;gt;/,&lt;br /&gt;
            '{{cquote|$2|$1}}');&lt;br /&gt;
    }&lt;br /&gt;
    return html;&lt;br /&gt;
} // Converts videos to wiki style&lt;br /&gt;
&lt;br /&gt;
function vid2wiki(html) {&lt;br /&gt;
    // YouTube&lt;br /&gt;
    html = html.replace(&lt;br /&gt;
        /&amp;lt;div class=&amp;quot;video-wrapper&amp;quot;&amp;gt;\s.*?&amp;lt;div class=&amp;quot;video-container&amp;quot;&amp;gt;\s*?&amp;lt;iframe class=&amp;quot;youtube-player&amp;quot;.*?width=&amp;quot;(.*?)&amp;quot; height=&amp;quot;(.*?)&amp;quot; src=&amp;quot;http:\/\/www\.youtube\.com\/embed\/(.*?)&amp;quot;.*?&amp;gt;&amp;lt;\/iframe&amp;gt;\s*?&amp;lt;\/div&amp;gt;\s*?&amp;lt;\/div&amp;gt;/g,&lt;br /&gt;
        '{{#ev:youtube|$3|$1x$2}}');&lt;br /&gt;
    // Vimeo&lt;br /&gt;
    html = html.replace(&lt;br /&gt;
        /&amp;lt;iframe src=&amp;quot;http:\/\/player\.vimeo\.com\/video\/(.*?)\?.*?&amp;quot; width=&amp;quot;(.*?)&amp;quot; height=&amp;quot;(.*?)&amp;quot;.*?&amp;gt;.*?&amp;lt;\/iframe&amp;gt;/g,&lt;br /&gt;
        '{{#ev:vimeo|$1|$2x$3}}');&lt;br /&gt;
    return html.replace(/\[.*? Watch on Vimeo\]/g, '');&lt;br /&gt;
} // Not currently used (as of June 2015), but kept just in case&lt;br /&gt;
&lt;br /&gt;
// currently unused&lt;br /&gt;
function escapeEquals(html) {&lt;br /&gt;
    return html.replace(/=/g, '{{=}}');&lt;br /&gt;
} // &amp;lt;br&amp;gt; to newline.&lt;br /&gt;
&lt;br /&gt;
function forum_br2newline(html) {&lt;br /&gt;
    html = html.replace(/&amp;lt;br\/?&amp;gt;&amp;lt;br\/?&amp;gt;/g, '\n');&lt;br /&gt;
    return html.replace(/&amp;lt;br\/?&amp;gt;/g, '\n\n');&lt;br /&gt;
} // Forum list to wiki style&lt;br /&gt;
&lt;br /&gt;
function list2wiki(html) {&lt;br /&gt;
    var list = html.match(/&amp;lt;ul&amp;gt;(.*?)&amp;lt;\/ul&amp;gt;/g);&lt;br /&gt;
    if (list !== null) {&lt;br /&gt;
        for (var i = 0; i &amp;lt; list.length; i++) {&lt;br /&gt;
            html = html.replace(/&amp;lt;li&amp;gt;(.*?)&amp;lt;\/li&amp;gt;/g, '* $1\n');&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    list = html.match(/&amp;lt;ol.*?&amp;gt;(.*?)&amp;lt;\/ol&amp;gt;/g);&lt;br /&gt;
    if (list !== null) {&lt;br /&gt;
        for (var i = 0; i &amp;lt; list.length; i++) {&lt;br /&gt;
            html = html.replace(/&amp;lt;li&amp;gt;(.*?)&amp;lt;\/li&amp;gt;/g, '# $1\n');&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    html = html.replace(/&amp;lt;\/?[uo]l&amp;gt;/g, '');&lt;br /&gt;
    return html;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function nowiki(text) {&lt;br /&gt;
    return '&amp;lt;nowiki&amp;gt;' + text + '&amp;lt;/nowiki&amp;gt;';&lt;br /&gt;
} // Returns the correct ordinal adjective&lt;br /&gt;
&lt;br /&gt;
function ordAdj(date) {&lt;br /&gt;
    date = date.toString();&lt;br /&gt;
    if (date == '11' || date == '12' || date == '13') {&lt;br /&gt;
        return 'th';&lt;br /&gt;
    } else if (date.substr(1) == '1' || date == '1') {&lt;br /&gt;
        return 'st';&lt;br /&gt;
    } else if (date.substr(1) == '2' || date == '2') {&lt;br /&gt;
        return 'nd';&lt;br /&gt;
    } else if (date.substr(1) == '3' || date == '3') {&lt;br /&gt;
        return 'rd';&lt;br /&gt;
    } else {&lt;br /&gt;
        return 'th';&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Formats the date to this format: Apr 26th, 2015&lt;br /&gt;
function datef(text) {&lt;br /&gt;
    var date = new Date(text);&lt;br /&gt;
    return MONTHS[date.getMonth()] + ' ' + date.getDate() + ordAdj(date.getDate()) +&lt;br /&gt;
        ', ' + date.getFullYear();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function underscore2Space(str) {&lt;br /&gt;
    return str.replace(/_/g, ' ');&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// IGNORE EVERYTHING THAT FOLLOWS: &lt;br /&gt;
// This is an experiment to use GA/GP (genetic programming) to help procedurally evolve xpath and regex expressions if/when the underlying websites change&lt;br /&gt;
// so that we don't have to manually update/edit the script accordingly (this would also work for mobile themes etc)&lt;br /&gt;
// For now, this is heavily based on the genetic.js framework/examples: http://subprotocol.com/system/genetic-hello-world.html&lt;br /&gt;
// The idea is to evolve the xpath/regex expression by evaluating its return value against the expected/desired value&lt;br /&gt;
// the most important thing here is having a suitable fitness function&lt;br /&gt;
// &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function evolve_expression_test() {&lt;br /&gt;
&lt;br /&gt;
    try {&lt;br /&gt;
        var genetic = Genetic.create();&lt;br /&gt;
&lt;br /&gt;
        // TODO: use minimizer: redundant_bytes + duration_msec + xpath.length&lt;br /&gt;
        genetic.optimize = Genetic.Optimize.Maximize;&lt;br /&gt;
        genetic.select1 = Genetic.Select1.Tournament2;&lt;br /&gt;
        genetic.select2 = Genetic.Select2.Tournament2;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        genetic.seed = function () {&lt;br /&gt;
&lt;br /&gt;
            function randomString(len) {&lt;br /&gt;
                var text = &amp;quot;&amp;quot;;&lt;br /&gt;
                var charset =&lt;br /&gt;
                    &amp;quot;\\abcdefghijklmnopqrstuvwxyz0123456789[] ()&amp;lt;&amp;gt;*.,&amp;quot;;&lt;br /&gt;
                for (var i = 0; i &amp;lt; len; i++)&lt;br /&gt;
                    text += charset.charAt(Math.floor(Math.random() *&lt;br /&gt;
                        charset.length));&lt;br /&gt;
&lt;br /&gt;
                return text;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // create random strings that are equal in length to solution&lt;br /&gt;
            return randomString(this.userData[&amp;quot;solution&amp;quot;].length);&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        genetic.mutate = function (entity) {&lt;br /&gt;
&lt;br /&gt;
            function replaceAt(str, index, character) {&lt;br /&gt;
                return str.substr(0, index) + character + str.substr(index +&lt;br /&gt;
                    character.length);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // chromosomal drift&lt;br /&gt;
            var i = Math.floor(Math.random() * entity.length);&lt;br /&gt;
            return replaceAt(entity, i, String.fromCharCode(entity.charCodeAt(&lt;br /&gt;
                i) + (Math.floor(Math.random() * 2) ? 1 : -1)));&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
        genetic.crossover = function (mother, father) {&lt;br /&gt;
&lt;br /&gt;
            // two-point crossover&lt;br /&gt;
            var len = mother.length;&lt;br /&gt;
            var ca = Math.floor(Math.random() * len);&lt;br /&gt;
            var cb = Math.floor(Math.random() * len);&lt;br /&gt;
            if (ca &amp;gt; cb) {&lt;br /&gt;
                var tmp = cb;&lt;br /&gt;
                cb = ca;&lt;br /&gt;
                ca = tmp;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            var son = father.substr(0, ca) + mother.substr(ca, cb - ca) +&lt;br /&gt;
                father.substr(cb);&lt;br /&gt;
            var daughter = mother.substr(0, ca) + father.substr(ca, cb - ca) +&lt;br /&gt;
                mother.substr(cb);&lt;br /&gt;
&lt;br /&gt;
            return [son, daughter];&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
        genetic.determineExcessBytes = function (text, needle) {&lt;br /&gt;
            return text.length - needle.length;&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
        genetic.containsText = function (text, needle) {&lt;br /&gt;
            return text.search(needle);&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
        genetic.isValid = function (exp) {&lt;br /&gt;
&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
        /* myFitness:&lt;br /&gt;
         * - must be a valid xpath/regex expression (try/call)&lt;br /&gt;
         * - must containsText the needle&lt;br /&gt;
         * - low relative offset in text (begin/end)&lt;br /&gt;
         * - excessBytes&lt;br /&gt;
         * - short expression  (expression length)&lt;br /&gt;
         * - expression footprint (runtime)&lt;br /&gt;
         */&lt;br /&gt;
&lt;br /&gt;
        // TODO: the fitness function should validate each xpath/regex first&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        genetic.fitness = function (entity) {&lt;br /&gt;
            var fitness = 0;&lt;br /&gt;
            var result;&lt;br /&gt;
            var validExp = 0.1;&lt;br /&gt;
            var hasToken = 0.1;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            var t = this.userData.tests[0].haystack;&lt;br /&gt;
            //var regex = new RegExp(this.userData.solution);&lt;br /&gt;
            //var output = t.match( new RegExp(&amp;quot;From: (.*) &amp;lt;.*@.*&amp;gt;&amp;quot;))[1];  &lt;br /&gt;
            // TODO: use search &amp;amp; match for improving the fitness&lt;br /&gt;
&lt;br /&gt;
            if (0)&lt;br /&gt;
                try {&lt;br /&gt;
                    var regex = new RegExp(entity);&lt;br /&gt;
                    var output = t.search(regex);&lt;br /&gt;
                    validExp = 10;&lt;br /&gt;
                }&lt;br /&gt;
            catch (e) {&lt;br /&gt;
                validExp = 2;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            var i;&lt;br /&gt;
            for (i = 0; i &amp;lt; entity.length; ++i) {&lt;br /&gt;
                // increase fitness for each character that matches&lt;br /&gt;
                if (entity[i] == this.userData[&amp;quot;solution&amp;quot;][i])&lt;br /&gt;
                    fitness += 1;&lt;br /&gt;
&lt;br /&gt;
                // award fractions of a point as we get warmer&lt;br /&gt;
                fitness += (127 - Math.abs(entity.charCodeAt(i) - this.userData[&lt;br /&gt;
                    &amp;quot;solution&amp;quot;].charCodeAt(i))) / 50;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            return fitness; // + (1*validExp + 1* hasToken);&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
        genetic.generation = function (pop, generation, stats) {&lt;br /&gt;
            // stop running once we've reached the solution&lt;br /&gt;
            return pop[0].entity != this.userData[&amp;quot;solution&amp;quot;];&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
        genetic.notification = function (pop, generation, stats, isFinished) {&lt;br /&gt;
&lt;br /&gt;
            function lerp(a, b, p) {&lt;br /&gt;
                return a + (b - a) * p;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            var value = pop[0].entity;&lt;br /&gt;
            this.last = this.last || value;&lt;br /&gt;
&lt;br /&gt;
            if (pop != 0 &amp;amp;&amp;amp; value == this.last)&lt;br /&gt;
                return;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            var solution = [];&lt;br /&gt;
            var i;&lt;br /&gt;
            for (i = 0; i &amp;lt; value.length; ++i) {&lt;br /&gt;
                var diff = value.charCodeAt(i) - this.last.charCodeAt(i);&lt;br /&gt;
                var style = &amp;quot;background: transparent;&amp;quot;;&lt;br /&gt;
                if (diff &amp;gt; 0) {&lt;br /&gt;
                    style = &amp;quot;background: rgb(0,200,50); color: #fff;&amp;quot;;&lt;br /&gt;
                } else if (diff &amp;lt; 0) {&lt;br /&gt;
                    style = &amp;quot;background: rgb(0,100,50); color: #fff;&amp;quot;;&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                solution.push(&amp;quot;&amp;lt;span style=\&amp;quot;&amp;quot; + style + &amp;quot;\&amp;quot;&amp;gt;&amp;quot; + value[i] +&lt;br /&gt;
                    &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            var t = this.userData.tests[0].haystack;&lt;br /&gt;
            //console.log(&amp;quot;haystack is:&amp;quot;+t);&lt;br /&gt;
            // &amp;quot;From: John Doe &amp;lt;John@do...&amp;gt; - 2020-07-02 17:36:03&amp;quot;, needle: &amp;quot;John Doe&amp;quot;}, /From: (.*) &amp;lt;.*@.*&amp;gt;/&lt;br /&gt;
            var regex = new RegExp(this.userData.solution);&lt;br /&gt;
            //var output = t.match( new RegExp(&amp;quot;From: (.*) &amp;lt;.*@.*&amp;gt;&amp;quot;))[1];  &lt;br /&gt;
            // TODO: use search &amp;amp; match for improving the fitness&lt;br /&gt;
            var output = t.search(new RegExp(value));&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            var buf = &amp;quot;&amp;quot;;&lt;br /&gt;
            buf += &amp;quot;&amp;lt;tr&amp;gt;&amp;quot;;&lt;br /&gt;
            buf += &amp;quot;&amp;lt;td&amp;gt;&amp;quot; + generation + &amp;quot;&amp;lt;/td&amp;gt;&amp;quot;;&lt;br /&gt;
            buf += &amp;quot;&amp;lt;td&amp;gt;&amp;quot; + pop[0].fitness.toPrecision(5) + &amp;quot;&amp;lt;/td&amp;gt;&amp;quot;;&lt;br /&gt;
            buf += &amp;quot;&amp;lt;td&amp;gt;&amp;quot; + solution.join(&amp;quot;&amp;quot;) + &amp;quot;&amp;lt;/td&amp;gt;&amp;quot;;&lt;br /&gt;
            buf += &amp;quot;&amp;lt;td&amp;gt;&amp;quot; + output + &amp;quot;&amp;lt;/td&amp;gt;&amp;quot;;&lt;br /&gt;
            buf += &amp;quot;&amp;lt;/tr&amp;gt;&amp;quot;;&lt;br /&gt;
            $(&amp;quot;#results tbody&amp;quot;).prepend(buf);&lt;br /&gt;
&lt;br /&gt;
            this.last = value;&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        /*&lt;br /&gt;
genetic.notification2 = function(pop, generation, stats, isFinished) {&lt;br /&gt;
&lt;br /&gt;
    function lerp(a, b, p) {&lt;br /&gt;
        return a + (b-a)*p;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    var value = pop[0].entity;&lt;br /&gt;
    this.last = this.last||value;&lt;br /&gt;
    &lt;br /&gt;
    if (pop != 0 &amp;amp;&amp;amp; value == this.last)&lt;br /&gt;
        return;&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    var solution = [];&lt;br /&gt;
    var i;&lt;br /&gt;
    for (i=0;i&amp;lt;value.length;++i) {&lt;br /&gt;
    &lt;br /&gt;
    solution.push(value[i]);&lt;br /&gt;
 } &lt;br /&gt;
    console.log(&amp;quot;Generation:&amp;quot;+ generation + &amp;quot; Fitness:&amp;quot; + pop[0].fitness.toPrecision(5) + &amp;quot; Solution:&amp;quot; + solution.join(&amp;quot;&amp;quot;));&lt;br /&gt;
  &lt;br /&gt;
    this.last = value;&lt;br /&gt;
};&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        var config = {&lt;br /&gt;
            &amp;quot;iterations&amp;quot;: 4000,&lt;br /&gt;
            &amp;quot;size&amp;quot;: 250,&lt;br /&gt;
            &amp;quot;crossover&amp;quot;: 0.3,&lt;br /&gt;
            &amp;quot;mutation&amp;quot;: 0.4,&lt;br /&gt;
            &amp;quot;skip&amp;quot;: 30 // notifications&lt;br /&gt;
                //, &amp;quot;webWorkers&amp;quot;: false&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        /*&lt;br /&gt;
        var profile = CONFIG['Sourceforge Mailing list'];&lt;br /&gt;
        var posting = profile.tests[0];&lt;br /&gt;
        var author_xpath = profile.title.xpath;&lt;br /&gt;
        */&lt;br /&gt;
&lt;br /&gt;
        var regexTests = [{&lt;br /&gt;
            haystack: &amp;quot;From: John Doe &amp;lt;John@do...&amp;gt; - 2020-07-02 17:36:03&amp;quot;,&lt;br /&gt;
            needle: &amp;quot;John Doe&amp;quot;&lt;br /&gt;
        }, {&lt;br /&gt;
            haystack: &amp;quot;From: Marc Twain &amp;lt;Marc@ta...&amp;gt; - 2010-01-03 07:36:03&amp;quot;,&lt;br /&gt;
            needle: &amp;quot;Marc Twain&amp;quot;&lt;br /&gt;
        }, {&lt;br /&gt;
            haystack: &amp;quot;From: George W. Bush &amp;lt;GWB@wh...&amp;gt; - 2055-11-11 17:33:13&amp;quot;,&lt;br /&gt;
            needle: &amp;quot;George W. Bush&amp;quot;&lt;br /&gt;
        }];&lt;br /&gt;
&lt;br /&gt;
        // the regex we want to evolve&lt;br /&gt;
        var solution = &amp;quot;From: (.*) &amp;lt;.*@.*&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        // let's assume, we'd like to evolve a regex expression like this one&lt;br /&gt;
        var userData = {&lt;br /&gt;
            solution: solution,&lt;br /&gt;
            tests: regexTests&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
        genetic.evolve(config, userData);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        //console.log(&amp;quot;genetic.js is loaded and working, but disabled for now&amp;quot;);    &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    } // try&lt;br /&gt;
    catch (e) {&lt;br /&gt;
        console.log(&amp;quot;genetic.js error:\n&amp;quot; + e.message);&lt;br /&gt;
    } // catch&lt;br /&gt;
&lt;br /&gt;
} // evolveExpression_test()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if (0) //TODO: expose via development tab&lt;br /&gt;
    try {&lt;br /&gt;
    // https://github.com/cazala/synaptic&lt;br /&gt;
    var Neuron = synaptic.Neuron,&lt;br /&gt;
        Layer = synaptic.Layer,&lt;br /&gt;
        Network = synaptic.Network,&lt;br /&gt;
        Trainer = synaptic.Trainer,&lt;br /&gt;
        Architect = synaptic.Architect;&lt;br /&gt;
&lt;br /&gt;
    function Perceptron(input, hidden, output) {&lt;br /&gt;
        // create the layers&lt;br /&gt;
        var inputLayer = new Layer(input);&lt;br /&gt;
        var hiddenLayer = new Layer(hidden);&lt;br /&gt;
        var outputLayer = new Layer(output);&lt;br /&gt;
&lt;br /&gt;
        // connect the layers&lt;br /&gt;
        inputLayer.project(hiddenLayer);&lt;br /&gt;
        hiddenLayer.project(outputLayer);&lt;br /&gt;
&lt;br /&gt;
        // set the layers&lt;br /&gt;
        this.set({&lt;br /&gt;
            input: inputLayer,&lt;br /&gt;
            hidden: [hiddenLayer],&lt;br /&gt;
            output: outputLayer&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // extend the prototype chain&lt;br /&gt;
    Perceptron.prototype = new Network();&lt;br /&gt;
    Perceptron.prototype.constructor = Perceptron;&lt;br /&gt;
&lt;br /&gt;
    var myPerceptron = new Perceptron(2, 3, 1);&lt;br /&gt;
    var myTrainer = new Trainer(myPerceptron);&lt;br /&gt;
&lt;br /&gt;
    myTrainer.XOR(); // { error: 0.004998819355993572, iterations: 21871, time: 356 }&lt;br /&gt;
&lt;br /&gt;
    myPerceptron.activate([0, 0]); // 0.0268581547421616&lt;br /&gt;
    myPerceptron.activate([1, 0]); // 0.9829673642853368&lt;br /&gt;
    myPerceptron.activate([0, 1]); // 0.9831714267395621&lt;br /&gt;
    myPerceptron.activate([1, 1]); // 0.02128894618097928&lt;br /&gt;
&lt;br /&gt;
    console.log(&amp;quot;Syntaptic loaded&amp;quot;);&lt;br /&gt;
} catch (e) {&lt;br /&gt;
    UI.alert(e.message);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Appendix}}&lt;/div&gt;</summary>
		<author><name>Elgaton</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=FlightGear_wiki:Instant-Refs&amp;diff=98425</id>
		<title>FlightGear wiki:Instant-Refs</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=FlightGear_wiki:Instant-Refs&amp;diff=98425"/>
		<updated>2016-05-20T13:10:33Z</updated>

		<summary type="html">&lt;p&gt;Elgaton: /* The script */ Script beautified&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Quotes-logo-200x200.png|thumb]]&lt;br /&gt;
[[File:Instant-cquotes-firefox.png|thumb|Instant-Cquotes script in Firefox]]&lt;br /&gt;
&lt;br /&gt;
[[File:Ref-only-quotes.png|thumb|Instant-Cquotes screenshot prototyping runtime format selection]]&lt;br /&gt;
&lt;br /&gt;
The '''Instant-Cquotes''' script is a browser addon (user script) implemented in JavaScript in order to convert excerpts (created via copy&amp;amp;paste) from FlightGear forum or [[mailing list]] postings into MediaWiki markup/quotes to be used on the FlightGear wiki. It is supported by Firefox, Google Chrome/Chromium, Opera and Safari. It is being developed and maintained by a group of volunteers involved in maintaining the wiki and in trying to provide more up-to-date information to end-users who may not be as involved in the various FlightGear-related communication channels.&lt;br /&gt;
&lt;br /&gt;
== Background and motivation ==&lt;br /&gt;
FlightGear's development is, at best, &amp;quot;self-coordinated&amp;quot;, meaning that contributors discuss ideas and make proposals to contribute in a certain fashion and then team up to implement certain features and building blocks, often just temporarily.&lt;br /&gt;
&lt;br /&gt;
Unfortunately, due to a lack of development manpower, many ideas are not implemented immediately; it is, thus, important to know their pros and cons, as well as who originally proposed them and/or might help with their implementation, even after a long time, preferably with links to the original discussions so that new contributors can decide whether to get involved in some effort or not. The project documentation, however, is in great need of improvement&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
| url    = http://sourceforge.net/p/flightgear/mailman/message/15444440/&lt;br /&gt;
| title  = &amp;lt;nowiki&amp;gt;[Flightgear-devel] development process (was:  chaos...)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| author = &amp;lt;nowiki&amp;gt;John Denker&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| date   = Jul 16th, 2007&lt;br /&gt;
| added   = Jul 16th, 2007&lt;br /&gt;
| script_version = 0.23&lt;br /&gt;
}}&amp;lt;/ref&amp;gt; and usually significantly lacking behind:&amp;lt;ref name=&amp;quot;OlsonStateThingsFG&amp;quot;&amp;gt;{{cite web&lt;br /&gt;
| url    = http://sourceforge.net/p/flightgear/mailman/message/27861667/&lt;br /&gt;
| title  = &amp;lt;nowiki&amp;gt;Re: [Flightgear-devel] The state of things in Flight Gear&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| author = &amp;lt;nowiki&amp;gt;Curtis Olson&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| date   = Jul 27th, 2011&lt;br /&gt;
| added   = Jul 27th, 2011&lt;br /&gt;
| script_version = 0.23&lt;br /&gt;
}}&amp;lt;/ref&amp;gt; many core developers update it seldomly, if not anymore, as it takes time to write it, as well as an understanding of the inner workings of a complex system such as FlightGear. Furthermore, this task might not be attractive due to its short term impact on the project,&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
| url    = http://sourceforge.net/p/flightgear/mailman/message/27861562/&lt;br /&gt;
| title  = &amp;lt;nowiki&amp;gt;Re: [Flightgear-devel] The state of things in Flight Gear&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| author = &amp;lt;nowiki&amp;gt;Hal V. Engel&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| date   = Jul 27th, 2011&lt;br /&gt;
| added   = Jul 27th, 2011&lt;br /&gt;
| script_version = 0.23&lt;br /&gt;
}}&amp;lt;/ref&amp;gt; and it is overwhelming to think about creating documentation that would address the needs of many different kinds of contributors with different backgrounds, experience levels and goals.&amp;lt;ref name=&amp;quot;OlsonStateThingsFG&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Forum and mailing lists discussions have therefore become the only up-to-date (albeit difficult to filter)&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
| url    = http://forum.flightgear.org/viewtopic.php?p=280058#p280058&lt;br /&gt;
| title  = &amp;lt;nowiki&amp;gt;Re: quoting on the wiki&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| author = &amp;lt;nowiki&amp;gt;Thorsten&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| date   = Mar 21st, 2016&lt;br /&gt;
| added   = Mar 21st, 2016&lt;br /&gt;
| script_version = 0.25&lt;br /&gt;
}}&amp;lt;/ref&amp;gt; source of information about recent development progress; this makes it tricky to know what is going on, what needs fixing, what were the decisions taken by the developers.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
| url    = https://www.mail-archive.com/flightgear-devel%40lists.sourceforge.net/msg17198.html&lt;br /&gt;
| title  = &amp;lt;nowiki&amp;gt;[Flightgear-devel] Project tracking&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| author = &amp;lt;nowiki&amp;gt;James Turner&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| date   = Mon, 28 Jul 2008 10:06:05 -0700&lt;br /&gt;
}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The aim of the Instant-Cquotes script is to help wiki editors to copy relevant excerpts from such sources, formatting them as proper [[Template:Cquote|quotations]], and bootstrap new articles collecting them until a dedicated rewrite is made. It can also be used to reuse announcements to update the changelogs, [[Next newsletter|newsletter]] or the [[Release plan/Lessons learned]] page.&lt;br /&gt;
&lt;br /&gt;
After being away from the wiki system for some time it becomes more of an effort to re-learn how to start a new file and figure out how to format it , with what headings, etc. Sometimes it is almost too much to do the original write up of the original post and all the work of that layout and effort to have to also duplicate it in a wiki article. If I was a little more current and affluent with the wiki editor, I might not be so hesitant to create the work there instead of the forum.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=284698#p284698 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Breaking down NLCD raster image &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; wlbragg &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  May 9th, 2016 &lt;br /&gt;
  |added  =  May 9th, 2016 &lt;br /&gt;
  |script_version = 0.38 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In a few cases, such collections of quotes helped not only create bootstrap new articles, but even actual features.&lt;br /&gt;
&lt;br /&gt;
In other cases, quotes have been used to update documentation of features (e.g. [[Rembrandt]]) whose maintainers may not be actively involved in FlightGear, to help document discussions that are taking place in the meantime, and provide some background information for people interested in the corresponding feature.&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
# Install a user script manager. On Firefox, you can use [https://addons.mozilla.org/en-US/firefox/addon/greasemonkey/ Greasemonkey]; on Chrome/Chromium, Opera or Safari, you can use [https://tampermonkey.net/ Tampermonkey] (download links: [https://tampermonkey.net/index.php?ext=dhdg&amp;amp;browser=chrome Chrome/Chromium], [https://tampermonkey.net/index.php?ext=dhdg&amp;amp;browser=opera Opera], [https://tampermonkey.net/index.php?ext=dhdg&amp;amp;browser=safari Safari]).&lt;br /&gt;
# Visit [https://greasyfork.org/en/scripts/19331-instant-cquotes the Instant-Cquotes page on GreasyFork] and click on {{button|Install this script}} (green button). If Greasemonkey/Tampermonkey prompts you to confirm the installation, agree to do so.&lt;br /&gt;
&lt;br /&gt;
[[File:Howto-install-instant-cquotes.png|thumb|Click the green button to install the script]]&lt;br /&gt;
&lt;br /&gt;
=== Manual installation ===&lt;br /&gt;
{{note|This will install the most recent development version of the script, which might contain bugs. Also, GreaseMonkey/TamperMonkey will not update it automatically whenever a new version is released.}}&lt;br /&gt;
&lt;br /&gt;
* '''Firefox'''&lt;br /&gt;
# Install Greasemonkey.&lt;br /&gt;
# Save [[#The Script|the script]] below as &amp;lt;code&amp;gt;instant_cquotes.user.js&amp;lt;/code&amp;gt;, then drag-and-drop it into Firefox.&lt;br /&gt;
[[File:Greasemonkey-setup-on-firefox.png|thumb|Screenshot showing the Greasemonkey setup dialog (on Firefox)]]&lt;br /&gt;
&lt;br /&gt;
* '''Chrome/Chromium''', '''Opera''', or '''Safari'''&lt;br /&gt;
# Install Tampermonkey.&lt;br /&gt;
# Navigate to '''Add a new Script'''.&lt;br /&gt;
# Copy and paste [[#The Script|the script]] below into the editing window.&lt;br /&gt;
# Click the {{button|Save}} button (just above the {{button|Search}} button).&lt;br /&gt;
&lt;br /&gt;
=== Mobile installation ===&lt;br /&gt;
As of May 2016, there is no separate version available for mobile use. Your best chance is installing a userscript addon on Android, like one of those:&lt;br /&gt;
* [https://play.google.com/store/apps/details?id=net.biniok.tampermonkey Tampermonkey (Google Play Store)]&lt;br /&gt;
* [http://oilcan.jsharkey.org/ OilCan: Greasemonkey on steroids for Android]&lt;br /&gt;
&lt;br /&gt;
For installation instructions, refer to [https://openuserjs.org/about/Tampermonkey-for-Android Tampermonkey for Android] or [http://www.blogtechnika.com/how-to-access-greasemonkey-scripts-on-android-phones/ How To Access Greasemonkey Scripts on Android Phones].&lt;br /&gt;
&lt;br /&gt;
Testing/feedback would obviously be appreciated - if in doubt, feel free to just edit the wiki page to add your findings/questions.&lt;br /&gt;
&lt;br /&gt;
=== Configuration ===&lt;br /&gt;
[[File:User-script-menu.png|thumb|GreaseMonkey menu shown in FireFox with instanct cquotes menu items]]&lt;br /&gt;
&lt;br /&gt;
[[File:Config-dialog-instant-cquotes.png|thumb|The configuration dialog for the Instant-Cquotes script]]&lt;br /&gt;
&lt;br /&gt;
As of version 0.30, a dedicated configuration dialog is in the process of being added, so that certain script features can be dynamically configured, without having to edit the script. For now, this is merely a placeholder that provides a checkbox to easily enable/disable the debug mode. In the future, we are hoping to also expose other features this way.&lt;br /&gt;
&lt;br /&gt;
== Usage ==&lt;br /&gt;
[[File:Updated-cquotes-script-by-redleader.png|thumb|Instant-Cquotes script, with updates contributed by Red Leader]]&lt;br /&gt;
&lt;br /&gt;
[[File:New-cquotes.png|thumb|Screenshot showing Instant-Cquotes 0.30 at work]]&lt;br /&gt;
&lt;br /&gt;
# Go to some [[mailing list]] archive URL, for example [http://sourceforge.net/p/flightgear/mailman/message/32400727/] or any forum message, such as {{forumref|title=Re: Get objects to show up on Map/Radar|t=23299|label=p212558|f=71}}.&lt;br /&gt;
# Select the relevant portion of text.&lt;br /&gt;
# When you release the mouse button, a box will appear containing the converted text (for now, mainly properly-referenced quotes for the wiki).&lt;br /&gt;
# The text will be automatically selected and copied to the clipboard.&lt;br /&gt;
# Paste the text into the desired wiki page.&lt;br /&gt;
&lt;br /&gt;
For example, by selecting part of the forum post in the link above you can get the following quotation:&lt;br /&gt;
&lt;br /&gt;
{{FGCquote&lt;br /&gt;
|1= The upcoming FlightGear version (3.2) will contain a canvas-based map dialog, including a modular &amp;quot;plugin&amp;quot; system for creating custom map layers and charts with roughly ~50 lines of code, most of it boilerplate. &lt;br /&gt;
This is entirely XML/Nasal based (scripted) - symbols can be pretty much anything, raster or vector images (png or svg), but even animated. Styling can be customied, too.&lt;br /&gt;
For more info, I suggest to check out:&lt;br /&gt;
[[MapStructure#Porting the map dialog]]&lt;br /&gt;
&lt;br /&gt;
[[File:MapStructureDialog.png|250px]]&lt;br /&gt;
|2= {{cite web&lt;br /&gt;
  | url    = http://forum.flightgear.org/viewtopic.php?p=212558#p212558&lt;br /&gt;
  | title  = &amp;lt;nowiki&amp;gt;Re: Get objects to show up on Map/Radar&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  | author = &amp;lt;nowiki&amp;gt;Hooray&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  | date   = Jun 14th, 2014&lt;br /&gt;
  }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== On quoting ===&lt;br /&gt;
{{Main article|FlightGear wiki:Quoting Guidelines}}&lt;br /&gt;
&lt;br /&gt;
Using the Instant-Cquotes script is a good way to bootstrap and write some preliminary notes; however, while quotes might be useful to understand how undocumented subsystems and features work and are definitely better than nothing, they are not meant to replace proper, structured and well-written wiki articles.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
| url    = http://forum.flightgear.org/viewtopic.php?p=282800#p282800&lt;br /&gt;
| title  = &amp;lt;nowiki&amp;gt;Re: What is the QT launcher?&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| author = &amp;lt;nowiki&amp;gt;bugman&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| date   = Apr 17th, 2016&lt;br /&gt;
| added   = Apr 17th, 2016&lt;br /&gt;
| script_version = 0.25&lt;br /&gt;
}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One way to convert pages bootstrapped using quotes is to extract relevant information from them and keep citations only as references; in case important details are missing, they can be asked for on the [[Mailing lists|mailing lists]] (on the forum, the chance to get a complete answer might be lower).&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
| url    = http://sourceforge.net/p/flightgear/mailman/message/34954385/&lt;br /&gt;
| title  = &amp;lt;nowiki&amp;gt;Re: [Flightgear-devel] Wiki Quotes&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| author = &amp;lt;nowiki&amp;gt;James Turner&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| date   = Mar 21st, 2016&lt;br /&gt;
| added   = Mar 21st, 2016&lt;br /&gt;
| script_version = 0.25&lt;br /&gt;
}}&amp;lt;/ref&amp;gt; Another option might be moving the quotes to the Talk page for each entry, which would preserve the sources without clogging up the articles.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
| url    = http://sourceforge.net/p/flightgear/mailman/message/34948989/&lt;br /&gt;
| title  = &amp;lt;nowiki&amp;gt;Re: [Flightgear-devel] Wiki Quotes&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| author = &amp;lt;nowiki&amp;gt;Stuart Buchanan&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| date   = Mar 19th, 2016&lt;br /&gt;
| added   = Mar 19th, 2016&lt;br /&gt;
| script_version = 0.25&lt;br /&gt;
}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As a matter of fact, the whole paragraph above was assembled using this approach; to see for yourself, look up the references at the end of this page. For another example, see [[TerraSync#News]].&lt;br /&gt;
&lt;br /&gt;
== Development ==&lt;br /&gt;
{{Note|A Chrome/Chromium-specific extension that will not need Tampermonkey installed is under development.}}&lt;br /&gt;
&lt;br /&gt;
=== Resources ===&lt;br /&gt;
* https://www.mediawiki.org/wiki/API:Changing_wiki_content&lt;br /&gt;
* https://www.mediawiki.org/wiki/API:Edit&lt;br /&gt;
&lt;br /&gt;
=== Adding sources ===&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
{{WIP}}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
Adding a new source is pretty straightforward if you understand how xpath and regexes work - basically, you only need an archive (e.g. gmane), and then determine the xpath of each relevant field, as well as the regular expression to process the extracted fields (optional).&lt;br /&gt;
&lt;br /&gt;
The basic steps are these:&lt;br /&gt;
# open the user script in an editor&lt;br /&gt;
# navigate to the meta header of the user script&lt;br /&gt;
# add a new URL to the top of the script, e.g. by copying/adapting an existing line like this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// @match       https://sourceforge.net/p/flightgear/mailman/*&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once copied, add the new URL:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// @match       http://thread.gmane.org/gmane.games.flightgear.devel/*&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next, you need to navigate to the configuration hash to add a new website to it. &lt;br /&gt;
&lt;br /&gt;
Again, it makes sense to simply take an existing configuration hash and adapt it as needed (ignore/omit the tests vector for now by keeping it empty):&lt;br /&gt;
&lt;br /&gt;
{{Caution|the following example may meanwhile be outdated, so be sure to look at the actual code instead}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  'Sourceforge Mailing list': {&lt;br /&gt;
    enabled: true,&lt;br /&gt;
    type: 'archive',&lt;br /&gt;
    event: 'document.onmouseup', // when to invoke the event handler&lt;br /&gt;
    event_handler: instantCquote, // the event handler to be invoked&lt;br /&gt;
    url_reg: '^(http|https)://sourceforge.net/p/flightgear/mailman/.*/',&lt;br /&gt;
    content: {&lt;br /&gt;
      xpath: 'tbody/tr[2]/td/pre/text()',&lt;br /&gt;
      selection: getSelectedText,&lt;br /&gt;
      idStyle: /msg[0-9]{8}/,&lt;br /&gt;
      parentTag: [&lt;br /&gt;
        'tagName',&lt;br /&gt;
        'PRE'&lt;br /&gt;
      ],&lt;br /&gt;
    transform: [] // vector with transformation callbacks&lt;br /&gt;
    }, // content recipe&lt;br /&gt;
    // vector with tests to be executed for sanity checks (unit testing)&lt;br /&gt;
    tests: [&lt;br /&gt;
    ], // end of vector with self-tests&lt;br /&gt;
    // regex/xpath and transformations for extracting various required fields&lt;br /&gt;
    author: {&lt;br /&gt;
      xpath: 'tbody/tr[1]/td/div/small/text()',&lt;br /&gt;
      transform: [extract(/From: (.*) &amp;lt;.*@.*&amp;gt;/)]&lt;br /&gt;
    },&lt;br /&gt;
    title: {&lt;br /&gt;
      xpath: 'tbody/tr[1]/td/div/div[1]/b/a/text()'&lt;br /&gt;
      transform: []&lt;br /&gt;
    },&lt;br /&gt;
    date: {&lt;br /&gt;
      xpath: 'tbody/tr[1]/td/div/small/text()',&lt;br /&gt;
      transform: [extract(/- (.*-.*-.*) /)]&lt;br /&gt;
    },&lt;br /&gt;
    url: {&lt;br /&gt;
      xpath: 'tbody/tr[1]/td/div/div[1]/b/a/@href',&lt;br /&gt;
      transform: [prepend('https://sourceforge.net')]&lt;br /&gt;
    }&lt;br /&gt;
  }, // end of mailing list profile&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, we need to review/adapt the profile according to the new archive we'd like to see supported. &lt;br /&gt;
&lt;br /&gt;
for starters, that means:&lt;br /&gt;
* changing the name of the profile, e.g. to read gmane (instead of sourceforge)&lt;br /&gt;
* change the '''url_reg''' field to the gmane URL (this can be a regular expression)&lt;br /&gt;
&lt;br /&gt;
Next, it makes sense to use an [https://addons.mozilla.org/de/firefox/addon/xpath-checker/ XPath checker], so that we can look up the xpath expression for various HTML elements, and add those to the configuration hash above.&lt;br /&gt;
&lt;br /&gt;
For testing purposes, you will probably go to the setup dialog and enable the DEBUG mode, and use your browser's console to see what is going on.&lt;br /&gt;
&lt;br /&gt;
=== Getting involved ===&lt;br /&gt;
While having some experience with JavaScript/HTML and jQuery will definitely be useful, JavaScript is close enough to FlightGear scripting ([[Nasal]]), so that people can get involved pretty easily. &lt;br /&gt;
&lt;br /&gt;
Most maintenance work will typically involve reviewing/maintaining a few configuration hashes, that contain meta information for each supported archive (mailing list/forum).&lt;br /&gt;
&lt;br /&gt;
Usually, each hash contains a combination of xpath/regex expressions to look up the relevant information, as well as vector of optional transformations that are applied (in order) to convert contents to a different format (e.g. dates).&lt;br /&gt;
&lt;br /&gt;
In addition, there is growing library of utility functions, a handful wrappers for useful stuff, for example:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;Host.dbLog(message_string)&amp;lt;/code&amp;gt; - log a message to the console if the DEBUG flag is set&lt;br /&gt;
* &amp;lt;code&amp;gt;Host.download(url, callback, method='GET')&amp;lt;/code&amp;gt; - will download the URL and pass the downloaded content to the callback specified&lt;br /&gt;
* &amp;lt;code&amp;gt;Host.downloadPosting(url, callback)&amp;lt;/code&amp;gt; - will download the posting URL and pass the extracted and transformed author/content and date fields in a hash to the callback specified, the URL must be one supported in the CONFIG hash (i.e. forum/sourceforge for now)&lt;br /&gt;
* &amp;lt;code&amp;gt;Host.make_doc(string, type=&amp;quot;text/html&amp;quot;)&amp;lt;/code&amp;gt; - will turn a string/blob into a DOM that can be queried&lt;br /&gt;
* &amp;lt;code&amp;gt;Host.eval_xpath(document, xpath_expression, type=XPathResult.STRING_TYPE)&amp;lt;/code&amp;gt; - will apply the xpath expression to the document specified, returning the requested type (defaulted to string) &lt;br /&gt;
* &amp;lt;code&amp;gt;Host.set_persistent(key,value)&amp;lt;/code&amp;gt;  - stores a key/value pair&lt;br /&gt;
* &amp;lt;code&amp;gt;Host.get_persistent(key,default_value)&amp;lt;/code&amp;gt; - retrieves a values using the key specified, falling back to the default value&lt;br /&gt;
&lt;br /&gt;
=== Porting ===&lt;br /&gt;
[[File:Instant-cquote-firefox-addon-mode.png|thumb|Prototyping a dedicated instant-cquote mode for use as a firefox addon]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Porting the script to support other browsers/script engines is greatly appreciated. Typically, this should be pretty self-contained, because all main APIs are intended to be encapsulated in a so called &amp;quot;Environment&amp;quot; hash, where APIs that are specific to a particular browser/script engine should be provided with a wrapper. As of mid 2016, most APIs are now kept inside such an Environment hash (look at the GreaseMonkey hash for reference/details), so that it is now even possible to turn the script into a standalone FireFox addon without having to change much of the underlying code.&lt;br /&gt;
&lt;br /&gt;
=== Self checks (unit testing) ===&lt;br /&gt;
For regression testing purposes, there's a dedicated &amp;quot;self check&amp;quot; dialog that will be extended over time. For now it will download a few profile/website specific postings using a vector called &amp;quot;tests&amp;quot; and then log the posting's title, author and date to the console.&lt;br /&gt;
&lt;br /&gt;
The next step will be  actually showing that information in the dialog itself - there's a separate helper function to accomplish that, so that the corresponding div layer can be updated with the results.&lt;br /&gt;
&lt;br /&gt;
[[File:Sanity-check-cquotes-dialog.png|thumb|automatically executed sanity checks]]&lt;br /&gt;
&lt;br /&gt;
=== Debug mode ===&lt;br /&gt;
[[File:Instant-cquotes-debug-mode.png|thumb|Instant-Cquotes debug mode]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== AJAX (live page editing) ===&lt;br /&gt;
{{WIP}}&lt;br /&gt;
&lt;br /&gt;
* http://wiki.flightgear.org/api.php&lt;br /&gt;
* http://wiki.flightgear.org/api.php?action=parse&amp;amp;page=Frequently%20asked%20questions&amp;amp;prop=sections&lt;br /&gt;
&lt;br /&gt;
For now, the setup dialog will try to obtain a login token for the wiki and show a message if successful.&lt;br /&gt;
&lt;br /&gt;
In addition, the profile/website hash also contains a new wiki entry for the FlightGear wiki, whose '''event_handler''' callback will be invoked once the FG wiki is visited - the console/log will show a greeting, so that is where other code can be added - e.g. to help clean up/rewrite FGCquote-based articles automatically etc.&lt;br /&gt;
&lt;br /&gt;
There is a vector of &amp;quot;modes&amp;quot;, whose members are a hash containing trigger/handler fields, linked to two callbacks - the trigger callback can be used to check some condition, while the handler will be invoked if the trigger returns true.&lt;br /&gt;
&lt;br /&gt;
This can be used to support an arbitrary number of modes, whose triggers are evaluated during page load - all triggers that return true, will have their handlers invoked, which is how the following snippet works to rewrite/augment wiki edit handles:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;gt;&lt;br /&gt;
 'FlightGear.wiki': {&lt;br /&gt;
    type: 'wiki',&lt;br /&gt;
    enabled: false,&lt;br /&gt;
    event: 'document.onmouseup', // when to invoke the event handler&lt;br /&gt;
    event_handler: function () {&lt;br /&gt;
      console.log('FlightGear wiki handler active (waiting to be populated)');&lt;br /&gt;
      // this is where the logic for a wiki mode can be added over time (for now, it's a NOP)&lt;br /&gt;
    &lt;br /&gt;
    //for each supported mode, invoke the trigger and call the corresponding handler&lt;br /&gt;
    [].forEach.call(CONFIG['FlightGear.wiki'].modes, function(mode) {&lt;br /&gt;
      //dbLog(&amp;quot;Checking trigger:&amp;quot;+mode.name);&lt;br /&gt;
      if(mode.trigger) {&lt;br /&gt;
        mode.handler();&lt;br /&gt;
      }&lt;br /&gt;
    });&lt;br /&gt;
      &lt;br /&gt;
    }, // the event handler to be invoked&lt;br /&gt;
    url_reg: '^(http|https)://wiki.flightgear.org', // ignore for now: not currently used by the wiki mode&lt;br /&gt;
    &lt;br /&gt;
    modes: [&lt;br /&gt;
      { name:'process-editSections',&lt;br /&gt;
        trigger: function() {return true;}, // match URL regex - return true for always match&lt;br /&gt;
       &lt;br /&gt;
        // the code implementing the mode&lt;br /&gt;
        handler: function() {&lt;br /&gt;
                &lt;br /&gt;
    var editSections = document.getElementsByClassName('mw-editsection');&lt;br /&gt;
    console.log('FlightGear wiki article, number of edit sections: '+editSections.length);&lt;br /&gt;
   &lt;br /&gt;
    // for now, just rewrite edit sections and add a note to them&lt;br /&gt;
   &lt;br /&gt;
     [].forEach.call(editSections, function (sec) {&lt;br /&gt;
       sec.appendChild(&lt;br /&gt;
         document.createTextNode(' (instant-cquotes is lurking) ')&lt;br /&gt;
       );&lt;br /&gt;
     }); //forEach section&lt;br /&gt;
        } // handler&lt;br /&gt;
       &lt;br /&gt;
       &lt;br /&gt;
      } // process-editSections&lt;br /&gt;
      // TODO: add other wiki modes below &lt;br /&gt;
      &lt;br /&gt;
    ] // modes&lt;br /&gt;
    &lt;br /&gt;
  }, // end of wiki profile&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See [[User:Red Leader/Sandbox/AJAX test]]&lt;br /&gt;
&lt;br /&gt;
* https://www.mediawiki.org/wiki/API:Changing_wiki_content&lt;br /&gt;
* https://www.mediawiki.org/wiki/Extension:VisualEditor&lt;br /&gt;
* https://en.wikipedia.org/wiki/Wikipedia:Creating_a_bot&lt;br /&gt;
&lt;br /&gt;
=== Mobile edition ===&lt;br /&gt;
{{Note|As of 02/2016, Hooray is contemplating to make this available as an addon for Android phones.}}&lt;br /&gt;
&lt;br /&gt;
=== Issues/limitations ===&lt;br /&gt;
==== Bugs ====&lt;br /&gt;
* It's eating characters, apparently related to regex/xpath handling - e.g. words like &amp;quot;analyzing&amp;quot; are turned into &amp;quot;analying&amp;quot; [http://forum.flightgear.org/viewtopic.php?f=6&amp;amp;t=28378&amp;amp;p=270735&amp;amp;hilit=analyzing#p270735]&lt;br /&gt;
==== Non working URLs ====&lt;br /&gt;
* image matching/extraction: http://forum.flightgear.org/viewtopic.php?p=276221#p276221&lt;br /&gt;
* http://sourceforge.net/p/flightgear/mailman/message/34754961/&lt;br /&gt;
* http://forum.flightgear.org/viewtopic.php?f=18&amp;amp;t=27054&amp;amp;start=90#p273972 → selecting from “As promised, two sample installation sessions on Linux” to “That's it.” towards the end of the message causes Iceweasel (Firefox) 44.0.2 to display a dialog box reading “A script on this page may be busy, or it may have stopped responding. You can stop the script now, open the script in the debugger, or let the script continue.” The line below reads “Script: chrome://greasemonkey-modules/...quotes/instant_cquotes.user.js:544”. Choosing ''Continue'' doesn't help: the same message reappears a few seconds afterwards.&lt;br /&gt;
&lt;br /&gt;
=== Feature requests &amp;amp; ideas ===&lt;br /&gt;
* try to recognize list items [https://sourceforge.net/p/flightgear/mailman/message/35095319/] (heuristics: look for colon/asterisk, dashes and CR/LF)&lt;br /&gt;
* should add [[Template:News]] to the article dropdown for announcements [http://wiki.flightgear.org/index.php?title=Template:News&amp;amp;oldid=98266]&lt;br /&gt;
* add a mode that will download screenshots from forum postings and automatically upload/categorize them, see [[Birds]]&lt;br /&gt;
* split the article dropdown into sections, and also populate it with the user's watchlist [https://www.mediawiki.org/wiki/API:Watchlist] {{Progressbar|60}}&lt;br /&gt;
* mailing list templates, listed at [http://wiki.flightgear.org/Template_talk:Project_infrastructure#Related_mailing_list_templates]&lt;br /&gt;
* expose the cquote/ref markup via the UI so that it can be edited/customized and treated like a template {{Done}} (0.36+)&lt;br /&gt;
* identify common/repeated links and automatically create [[Template:Project infrastructure|link/infrastructure templates]] and use those (should be straightforward using the AJAX mode) [http://wiki.flightgear.org/index.php?title=Mailing_lists&amp;amp;curid=2038&amp;amp;diff=97876&amp;amp;oldid=85252]&lt;br /&gt;
* add a devel/maintainer mode where it will return the xpath for a selection [http://stackoverflow.com/questions/361130/get-selected-text-and-selected-nodes-on-a-page] [http://stackoverflow.com/questions/12485334/get-surrounding-dom-node-of-selection]&lt;br /&gt;
* move openlink,dblog helpers to Environment hash {{Done}}&lt;br /&gt;
* identify CLI arguments like --aircraft=c172p and wrap them in between code tags &amp;lt;code&amp;gt;--aircraft=c172p&amp;lt;/code&amp;gt; [https://sourceforge.net/p/flightgear/mailman/message/35063277/] (note that we can simply download [https://sourceforge.net/p/flightgear/fgdata/ci/next/tree/options.xml options.xml] via openlink() and use that, which is kinda of neat...) {{Progressbar|60}} (see downloadOptionsXML() in the code)&lt;br /&gt;
* introduce &amp;quot;layouts&amp;quot; (templates) for different purposes: newsletter, changelog, wiki article, [[The Manual]] (LaTex)  ? {{Progressbar|40}}&lt;br /&gt;
* use wikipedia template if possible [https://sourceforge.net/p/flightgear/mailman/message/35057670/]&lt;br /&gt;
* the new '''tests''' vector could also contain vectors for tests to test the extract/transform* utilities, see Environment.APITests {{Progressbar|50}}&lt;br /&gt;
* move environment specific APIs (browser, script host etc) into some kind of Environment hash to encapsulate things (Red Leader was working on a pure Chrome-only version at some point IIRC) {{Progressbar|80}}&lt;br /&gt;
* encode script settings in created markup, for future processing/updating of quotes&lt;br /&gt;
* look up &amp;lt;code&amp;gt;[x]&amp;lt;/code&amp;gt; references and replace with the corresponding link (titled) [https://sourceforge.net/p/flightgear/mailman/message/35055331/] [https://sourceforge.net/p/flightgear/mailman/message/35062598/]&lt;br /&gt;
** convert footnotes into Abbr templates [http://article.gmane.org/gmane.games.flightgear.devel/78971]&lt;br /&gt;
* support named refs for combining identical refs [http://wiki.flightgear.org/index.php?title=FlightGear_Qt_launcher&amp;amp;curid=13693&amp;amp;diff=97562&amp;amp;oldid=97551]&lt;br /&gt;
* adopt [[Template:Forumref]]&lt;br /&gt;
* implement a less obnoxious quoting mode, without quotes, where only the ref part would be added, e.g. see the example at [[Graphics Card Profiles]] (it's still 99% quotes, but much less annoying) {{Done}}&lt;br /&gt;
* attachment support: identify attachments and link to them: [https://sourceforge.net/p/flightgear/mailman/message/11683451/] [https://sourceforge.net/p/flightgear/mailman/message/23906620/] [https://sourceforge.net/p/flightgear/mailman/message/35059842/] [https://sourceforge.net/p/flightgear/mailman/message/35067087/]&lt;br /&gt;
* bulletin points: if there is a colon (:) followed by at least two dashes (-), split up everything after the colon to turn each dash into an asterisk (wiki markup for bulletin points), followed by a newline [http://sourceforge.net/p/flightgear/mailman/message/34760165/]   &lt;br /&gt;
* generic URL/template matching, e.g. for for sourceforge commit IDs&lt;br /&gt;
* make filters/conversions configurable via checkboxes (nowiki, wrap in alert/note boxes)&lt;br /&gt;
* make syntax highlighting configurable (language, mode) ?&lt;br /&gt;
* consider using something like the Roles template to turn contributor names into tooltips where contributor roles are shown (core dev, fgdata committer etc)&lt;br /&gt;
* introduce support for tag clouds to help categorize/classify related quotes&lt;br /&gt;
* consider making transformations optional/configurable using check boxes in the jQuery dialog&lt;br /&gt;
* add new input method, for quotes that need to be updated/converted (added script version specifically for this purpose), should also add extraction/processing date&lt;br /&gt;
* investigate why not all mailing list archives/postings are supported correctly: http://sourceforge.net/p/flightgear/mailman/message/8090479/ (problem traced to &amp;lt;code&amp;gt;getPostID()&amp;lt;/code&amp;gt;)&lt;br /&gt;
* explore having a ref-only mode without using cquotes, i.e. just copy/paste quotes with proper ref tags and a references section, to rewrite the whole thing (possibly with templates for different purposes, e.g. newsletter/changelog) {{Done}}&lt;br /&gt;
* should use Template:Forumref (category:link templates)&lt;br /&gt;
* should be updated to use the new repo/flightgear file templates created by Johan &amp;amp; RedLeader {{Not done}}&lt;br /&gt;
* resolve links to forum threads to look up the title for the topic/posting, so that the posting's title can be used for those links, instead of just the URL - we can probably do that by making an AJAX call to open URLs asynchronously and extract the title for the thread/posting to come up with something like &amp;lt;code&amp;gt;[http://forum.flightgear.org/viewtopic.php?f=4&amp;amp;t=24421 A call to developers-Lockheed -L188 Electra]&amp;lt;/code&amp;gt; ([http://forum.flightgear.org/viewtopic.php?f=4&amp;amp;t=26562&amp;amp;p=247325&amp;amp;hilit=links#p247347]) {{Progressbar|50}}&lt;br /&gt;
* convert quoted bug tracker URLs to use the issue template on the wiki {{not done}}&lt;br /&gt;
* do regex/xpath validation, and display any errors (e.g. template/theme changes on the forum would currently break the script) {{Progressbar|60}}&lt;br /&gt;
* increased focus on supporting different output formats, maybe using a simple [http://www.jquery-steps.com/ jQuery based wizard] (wiki, forum, newsletter, changelog) {{Not done}}&lt;br /&gt;
* token matching for keywords/acronyms to link to the corresponding wiki articles (e.g. Nasal, Canvas, FG_ROOT, FG_HOME etc) {{Not done}}&lt;br /&gt;
* Add support for [http://sourceforge.net/p/flightgear/codetickets/ tickets], merge requests comments and [http://www.fguk.eu/index.php/forum/index FGUK forum]. (also see [[FlightGear wiki talk:Instant-Cquotes#more sources]])&lt;br /&gt;
* GET-encoded SID arguments should be stripped from forum URLs. {{Not done}}&lt;br /&gt;
* Links to repositories should be converted to use wiki templates. {{Not done}}&lt;br /&gt;
* The {{Abbr|regexes|regular expressions}} used may fail if the HTML DOM of the source changes (e.g., phpBB/theme update)&lt;br /&gt;
** Show a warning when that's the case. {{Progressbar|70}} (see the self-check dialog)&lt;br /&gt;
** Try multiple regexes in order. {{Progressbar|30}} (see the self-check dialog)&lt;br /&gt;
* Use the script to update previously created Cquotes automatically&lt;br /&gt;
** Instead of using the &amp;lt;code&amp;gt;getSelection()&amp;lt;/code&amp;gt; helper, we could register a match for &amp;lt;tt&amp;gt;wiki.flightgear.org&amp;lt;/tt&amp;gt; with &amp;lt;code&amp;gt;action=edit&amp;lt;/code&amp;gt; set, so that we can directly process all text of an edited page, using AJAX calls to open the URL in the background. {{Progressbar|40}} (see the self-check dialog, available via the greasemonkey menu)&lt;br /&gt;
** See [https://www.mediawiki.org/wiki/API:Edit#Editing_via_Ajax MW:API:Edit § Editing via Ajax]&lt;br /&gt;
&lt;br /&gt;
=== Changelog ===&lt;br /&gt;
{{Note|Contributors are invited to document their changes here, please also add your wiki handle so that others can more easily get in touch.}}&lt;br /&gt;
&lt;br /&gt;
* first stab at implementing unit tests by adding a vector with URLS to be downloaded and fields to be matched (WIP), shown in a jQuery dialog&lt;br /&gt;
* support for persistent settings and a jQuery setup dialog with persistence&lt;br /&gt;
* hosting is moved, to allow auto-updates [http://www.greasespot.net/2012/02/automatic-script-updates-come-to.html] [https://wiki.greasespot.net/Metadata_Block#.40updateURL] [http://stackoverflow.com/questions/15095055/why-isnt-my-greasemonkey-script-updating]&lt;br /&gt;
* changed to ref-only quotes for now, not using the FGCquote template anymore, due to its obnoxious appearance on quote-heavy pages (should probably become a runtime option instead)&lt;br /&gt;
* updated to use https for forum postings&lt;br /&gt;
* add version info to each created quote, i.e. for future updates&lt;br /&gt;
* add helper for opening websites asynchronously using AJAX (also via GM helper API)&lt;br /&gt;
* display version number in output dialog&lt;br /&gt;
* begin using the GreaseMonkey API for setting clipboard content&lt;br /&gt;
&lt;br /&gt;
== The script ==&lt;br /&gt;
&amp;lt;gallery mode=packed widths=230px heights=230px&amp;gt;&lt;br /&gt;
Instant-cquotes-revamped.png|Instant cquotes: Revamped user interface exposes script internals to make the script better configurable at runtime&lt;br /&gt;
Instant-cquotes-template-editor.png|Instant cquotes now features a simple built-in template editor with support for variable substitution, so that wiki templates can be more easily customized&lt;br /&gt;
Instant-cquotes-with-wikimedia-API-integration.png|Screenshot showing instant-cquotes with wikimedia API integration to fetch articles/sections and populate dropdown menus accordingly&lt;br /&gt;
Instant-cquotes-on-steroids-with-watchlist-support.png|Screenshot showing the JQuery-mode of the instant cquotes script with built-in support for fetching a user's wiki/watchlist to edit/update articles in a semi-automated fashion&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
{{PD-author|FlightGear contributors}}&lt;br /&gt;
&lt;br /&gt;
{{Note|Anybody interested in contributing to the code is invited to directly edit this wiki article. From 05/2016, the script is hosted on GreasyFork to allow automatic updates. If you'd like to see your changes applied, please bump the version number and [[User:Elgaton|Elgaton]] will upload it in the state it was when the version number was bumped. ''Make sure to perform thorough testing'' before the bump to prevent unexpected breakage; it is generally a good idea to validate your changes using an online syntax checker, e.g.:&lt;br /&gt;
* http://jshint.com/ &lt;br /&gt;
* http://esprima.org/demo/validate.html&lt;br /&gt;
* http://codebeautify.org/jsvalidate&lt;br /&gt;
&amp;lt;p/&amp;gt;Thank you!}}&lt;br /&gt;
&lt;br /&gt;
Changes that should be mentioned in the changelog, should be added below (and moved to the [[#Changelog]] section subsequently:&lt;br /&gt;
&lt;br /&gt;
* preparations for adding support to download fgdata related files like options.xml to automatically regex known CLI commands&lt;br /&gt;
* preparatory work for adding a speech-rewrite engine to assist in converting 1st person speech to 3rd person&lt;br /&gt;
* framework for encapsulating userscript specifics in an environment hash to provide better updating/porting support&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;// ==UserScript==&lt;br /&gt;
// @name        Instant-Cquotes&lt;br /&gt;
// @name:it     Instant-Cquotes&lt;br /&gt;
// @license     public domain&lt;br /&gt;
// @version     0.39&lt;br /&gt;
// @date        2016-05-20&lt;br /&gt;
// @description Automatically converts selected FlightGear mailing list and forum quotes into post-processed MediaWiki markup (i.e. cquotes).&lt;br /&gt;
// @description:it Converte automaticamente citazioni dalla mailing list e dal forum di FlightGear in marcatori MediaWiki (cquote).&lt;br /&gt;
// @author      Hooray, bigstones, Philosopher, Red Leader &amp;amp; Elgaton (2013-2016)&lt;br /&gt;
// @supportURL  http://wiki.flightgear.org/FlightGear_wiki:Instant-Cquotes&lt;br /&gt;
// @icon        http://wiki.flightgear.org/images/2/25/Quotes-logo-200x200.png&lt;br /&gt;
// @match       https://sourceforge.net/p/flightgear/mailman/*&lt;br /&gt;
// @match       http://sourceforge.net/p/flightgear/mailman/*&lt;br /&gt;
// @match       https://forum.flightgear.org/*&lt;br /&gt;
// @match       http://wiki.flightgear.org/*&lt;br /&gt;
// @namespace   http://wiki.flightgear.org/FlightGear_wiki:Instant-Cquotes&lt;br /&gt;
// @run-at      document-start&lt;br /&gt;
// @require     https://code.jquery.com/jquery-1.10.2.js&lt;br /&gt;
// @require     https://code.jquery.com/ui/1.11.4/jquery-ui.js&lt;br /&gt;
// @require     https://cdn.jsdelivr.net/genetic.js/0.1.14/genetic.js&lt;br /&gt;
// @require     https://cdn.jsdelivr.net/synaptic/1.0.4/synaptic.min.js&lt;br /&gt;
// @resource    jQUI_CSS https://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css&lt;br /&gt;
// @resource    myLogo http://wiki.flightgear.org/images/2/25/Quotes-logo-200x200.png&lt;br /&gt;
// @grant       GM_registerMenuCommand&lt;br /&gt;
// @grant       GM_setValue&lt;br /&gt;
// @grant       GM_getValue&lt;br /&gt;
// @grant       GM_addStyle&lt;br /&gt;
// @grant       GM_getResourceText&lt;br /&gt;
// @grant       GM_getResourceURL&lt;br /&gt;
// @grant       GM_setClipboard&lt;br /&gt;
// @grant       GM_xmlhttpRequest&lt;br /&gt;
// @noframes&lt;br /&gt;
// ==/UserScript==&lt;br /&gt;
&lt;br /&gt;
// This work has been released into the public domain by their authors. This&lt;br /&gt;
// applies worldwide.&lt;br /&gt;
// In some countries this may not be legally possible; if so:&lt;br /&gt;
// The authors grant anyone the right to use this work for any purpose, without&lt;br /&gt;
// any conditions, unless such conditions are required by law.&lt;br /&gt;
&lt;br /&gt;
// This script has a number of dependencies that are implicitly satisfied when&lt;br /&gt;
// run as a user script via GreaseMonkey/TamperMonkey; however, these need to&lt;br /&gt;
// be explicitly handled when using a different mode (e.g. Firefox/Android):&lt;br /&gt;
//&lt;br /&gt;
// - jQuery - user interface (REQUIRED)&lt;br /&gt;
// - genetic-js - genetic programming (OPTIONAL/EXPERIMENTAL)&lt;br /&gt;
// - synaptic - neural networks (OPTIONAL/EXPERIMENTAL)&lt;br /&gt;
&lt;br /&gt;
/* Here are some TODOs&lt;br /&gt;
 * - support RSS feeds http://dir.gmane.org/gmane.games.flightgear.devel/&lt;br /&gt;
 * - move event handling/processing to the CONFIG hash&lt;br /&gt;
 * - use try/catch more widely&lt;br /&gt;
 * - wrap function calls in try/call for better debugging/diagnostics&lt;br /&gt;
 * - add helpers for [].forEach.call, map, apply and call&lt;br /&gt;
 * - replace for/in, for/of, let statements for better compatibility (dont require ES6)&lt;br /&gt;
 * - for the same reason, replace use of functions with default params&lt;br /&gt;
 * - isolate UI (e.g. JQUERY) code in UserInterface hash&lt;br /&gt;
 * - expose regex/transformations via the UI&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
/*jslint&lt;br /&gt;
    devel&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
'use strict';&lt;br /&gt;
&lt;br /&gt;
// prevent conflicts with jQuery used on webpages:&lt;br /&gt;
// https://wiki.greasespot.net/Third-Party_Libraries#jQuery&lt;br /&gt;
// http://stackoverflow.com/a/5014220&lt;br /&gt;
// TODO: move to GreaseMonkey/UI host&lt;br /&gt;
this.$ = this.jQuery = jQuery.noConflict(true);&lt;br /&gt;
&lt;br /&gt;
// this hash is just intended to help isolate UI specifics so that we don't&lt;br /&gt;
// need to maintain/port tons of code&lt;br /&gt;
var UserInterface = {&lt;br /&gt;
    get: function () {&lt;br /&gt;
        return UserInterface.DEFAULT;&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
    CONSOLE: {&lt;br /&gt;
    }, // CONSOLE (shell, mainly useful for testing)&lt;br /&gt;
&lt;br /&gt;
    DEFAULT: {&lt;br /&gt;
        alert: function (msg) {&lt;br /&gt;
            return window.alert(msg);&lt;br /&gt;
        },&lt;br /&gt;
        prompt: function (msg) {&lt;br /&gt;
            return window.prompt(msg);&lt;br /&gt;
        },&lt;br /&gt;
        confirm: function (msg) {&lt;br /&gt;
            return window.confirm(msg);&lt;br /&gt;
        },&lt;br /&gt;
        dialog: null,&lt;br /&gt;
        selection: null,&lt;br /&gt;
        populateWatchlist: function () {&lt;br /&gt;
        },&lt;br /&gt;
        populateEditSections: function () {&lt;br /&gt;
        }&lt;br /&gt;
    }, // default UI mapping (Browser/User script)&lt;br /&gt;
&lt;br /&gt;
    JQUERY: {&lt;br /&gt;
    } // JQUERY&lt;br /&gt;
}; // UserInterface&lt;br /&gt;
&lt;br /&gt;
var UI = UserInterface.get(); // DEFAULT for now&lt;br /&gt;
&lt;br /&gt;
// This hash is intended to help encapsulate platform specifics (browser/&lt;br /&gt;
// scripting host). Ideally, all APIs that are platform specific should be&lt;br /&gt;
// kept here. This should make it much easier to update/port and maintain the&lt;br /&gt;
// script in the future.&lt;br /&gt;
var Environment = {&lt;br /&gt;
    getHost: function (xpi = false) {&lt;br /&gt;
&lt;br /&gt;
        if (xpi) {&lt;br /&gt;
            Environment.scriptEngine = 'firefox addon';&lt;br /&gt;
            console.log('in firefox xpi/addon mode');&lt;br /&gt;
            return Environment.FirefoxAddon; // HACK for testing the xpi mode (firefox addon)&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // This will determine the script engine in use: http://stackoverflow.com/questions/27487828/how-to-detect-if-a-userscript-is-installed-from-the-chrome-store&lt;br /&gt;
        if (typeof (GM_info) === 'undefined') {&lt;br /&gt;
            Environment.scriptEngine =&lt;br /&gt;
                &amp;quot;plain Chrome (Or Opera, or scriptish, or Safari, or rarer)&amp;quot;;&lt;br /&gt;
            // See http://stackoverflow.com/a/2401861/331508 for optional browser sniffing code.&lt;br /&gt;
        } else {&lt;br /&gt;
            Environment.scriptEngine = GM_info.scriptHandler ||&lt;br /&gt;
                &amp;quot;Greasemonkey&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        console.log('Instant cquotes is running on ' + Environment.scriptEngine +&lt;br /&gt;
            '.');&lt;br /&gt;
&lt;br /&gt;
        // console.log(&amp;quot;not in firefox addon mode...&amp;quot;);&lt;br /&gt;
        // See also: https://wiki.greasespot.net/Cross-browser_userscripting&lt;br /&gt;
        return Environment.GreaseMonkey; // return the only/default host (for now)&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
    validate: function (host) {&lt;br /&gt;
        if (host.get_persistent('startup.disable_validation', false))&lt;br /&gt;
            return;&lt;br /&gt;
&lt;br /&gt;
        if (Environment.scriptEngine !== &amp;quot;Greasemonkey&amp;quot;)&lt;br /&gt;
            console.log(&lt;br /&gt;
                &amp;quot;NOTE: This script has not been tested with script engines&amp;quot;&lt;br /&gt;
                + &amp;quot; other than GreaseMonkey recently!&amp;quot;&lt;br /&gt;
            );&lt;br /&gt;
&lt;br /&gt;
        var dependencies = [{&lt;br /&gt;
            name: 'jQuery',&lt;br /&gt;
            test: function () {}&lt;br /&gt;
        }, {&lt;br /&gt;
            name: 'genetic.js',&lt;br /&gt;
            test: function () {}&lt;br /&gt;
        }, {&lt;br /&gt;
            name: 'synaptic',&lt;br /&gt;
            test: function () {}&lt;br /&gt;
        }, ];&lt;br /&gt;
&lt;br /&gt;
        [].forEach.call(dependencies, function (dep) {&lt;br /&gt;
            console.log(&amp;quot;Checking for dependency:&amp;quot; + dep.name);&lt;br /&gt;
            var status = false;&lt;br /&gt;
            try {&lt;br /&gt;
                dep.test.call(undefined);&lt;br /&gt;
                status = true;&lt;br /&gt;
            } catch (e) {&lt;br /&gt;
                status = false;&lt;br /&gt;
            } finally {&lt;br /&gt;
                var success = (status) ? '==&amp;gt; success' :&lt;br /&gt;
                    '==&amp;gt; failed';&lt;br /&gt;
                console.log(success);&lt;br /&gt;
                return status;&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }, // validate&lt;br /&gt;
&lt;br /&gt;
    // this contains unit tests for checking crucial APIs that must work for&lt;br /&gt;
    // the script to work correctly&lt;br /&gt;
    // for the time being, most of these are stubs waiting to be filled in&lt;br /&gt;
    // for a working example, refer to the JSON test at the end&lt;br /&gt;
    // TODO: add jQuery tests&lt;br /&gt;
    APITests: [{&lt;br /&gt;
            name: 'download',&lt;br /&gt;
            test: function (recipient) {&lt;br /&gt;
                recipient(true);&lt;br /&gt;
            }&lt;br /&gt;
        }, {&lt;br /&gt;
            name: 'make_doc',&lt;br /&gt;
            test: function (recipient) {&lt;br /&gt;
                recipient(true);&lt;br /&gt;
            }&lt;br /&gt;
        }, {&lt;br /&gt;
            name: 'eval_xpath',&lt;br /&gt;
            test: function (recipient) {&lt;br /&gt;
                recipient(true);&lt;br /&gt;
            }&lt;br /&gt;
        }, {&lt;br /&gt;
            name: 'JSON de/serialization',&lt;br /&gt;
            test: function (recipient) {&lt;br /&gt;
                    //console.log(&amp;quot;running json test&amp;quot;);&lt;br /&gt;
                    var identifier = 'unit_tests.json_serialization';&lt;br /&gt;
                    var hash1 = {&lt;br /&gt;
                        x: 1,&lt;br /&gt;
                        y: 2,&lt;br /&gt;
                        z: 3&lt;br /&gt;
                    };&lt;br /&gt;
                    Host.set_persistent(identifier, hash1, true);&lt;br /&gt;
                    var hash2 = Host.get_persistent(identifier, null,&lt;br /&gt;
                        true);&lt;br /&gt;
&lt;br /&gt;
                    recipient(JSON.stringify(hash1) === JSON.stringify(&lt;br /&gt;
                        hash2));&lt;br /&gt;
                } // callback&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
        // downloads a posting and tries to transform it to 3rd person speech ...&lt;br /&gt;
        // TODO: add another test to check forum postings&lt;br /&gt;
        {&lt;br /&gt;
            name: 'text/speech transformation',&lt;br /&gt;
            test: function (recipient) {&lt;br /&gt;
&lt;br /&gt;
                    // the posting we want to download&lt;br /&gt;
                    var url =&lt;br /&gt;
                        'https://sourceforge.net/p/flightgear/mailman/message/35066974/';&lt;br /&gt;
                    Host.downloadPosting(url, function (result) {&lt;br /&gt;
&lt;br /&gt;
                        // only process the first sentence by using comma/dot as&lt;br /&gt;
                        // delimiter&lt;br /&gt;
                        var firstSentence = result.content.substring(&lt;br /&gt;
                            result.content.indexOf(',') + 1,&lt;br /&gt;
                            result.content.indexOf('.'));&lt;br /&gt;
&lt;br /&gt;
                        var transformed = transformSpeech(&lt;br /&gt;
                            firstSentence, result.author,&lt;br /&gt;
                            null, speechTransformations);&lt;br /&gt;
                        console.log(&lt;br /&gt;
                            &amp;quot;3rd person speech transformation:\n&amp;quot; +&lt;br /&gt;
                            transformed);&lt;br /&gt;
&lt;br /&gt;
                        recipient(true);&lt;br /&gt;
                    }); // downloadPosting()&lt;br /&gt;
&lt;br /&gt;
                } // test()&lt;br /&gt;
        }, // end of speech transform test&lt;br /&gt;
        {&lt;br /&gt;
            name: &amp;quot;download $FG_ROOT/options.xml&amp;quot;,&lt;br /&gt;
            test: function (recipient) {&lt;br /&gt;
                    downloadOptionsXML();&lt;br /&gt;
                    recipient(true);&lt;br /&gt;
                } // test&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    ], // end of APITests&lt;br /&gt;
&lt;br /&gt;
    runAPITests: function (host, recipient) {&lt;br /&gt;
        console.log(&amp;quot;Running API tests&amp;quot;);&lt;br /&gt;
        for (let test of Environment.APITests) {&lt;br /&gt;
            //var test = Environment.APITests[t];&lt;br /&gt;
            // invoke the callback passed, with the hash containing the test&lt;br /&gt;
            // specs, so that the console/log or a div can be updated showing&lt;br /&gt;
            // the test results&lt;br /&gt;
            recipient.call(undefined, test);&lt;br /&gt;
&lt;br /&gt;
        } // foreach test&lt;br /&gt;
    }, // runAPITests&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * ========================================================================&lt;br /&gt;
     */&lt;br /&gt;
&lt;br /&gt;
    // NOTE: This mode/environment is WIP and highly experimental ...&lt;br /&gt;
    // To see this working, you need to package up the whole file as a Firefox&lt;br /&gt;
    // XPI using &amp;quot;jpm xpi&amp;quot; and then start the whole thing via &amp;quot;jpm run&amp;quot;, to do&lt;br /&gt;
    // that, you also need a matching package.json (i.e. via jpm init)&lt;br /&gt;
    // ALSO: you will have to explicitly install any dependencies using jpm&lt;br /&gt;
    FirefoxAddon: {&lt;br /&gt;
        init: function () {&lt;br /&gt;
            console.log(&amp;quot;Firefox addon mode ...&amp;quot;);&lt;br /&gt;
        },&lt;br /&gt;
        getScriptVersion: function () {&lt;br /&gt;
            return '0.36'; // FIXME&lt;br /&gt;
        },&lt;br /&gt;
        dbLog: function (msg) {&lt;br /&gt;
            console.log(msg);&lt;br /&gt;
        },&lt;br /&gt;
        addEventListener: function (ev, cb) {&lt;br /&gt;
&lt;br /&gt;
            require(&amp;quot;sdk/tabs&amp;quot;).on(&amp;quot;ready&amp;quot;, logURL);&lt;br /&gt;
&lt;br /&gt;
            function logURL(tab) {&lt;br /&gt;
                console.log(&amp;quot;URL loaded:&amp;quot; + tab.url);&lt;br /&gt;
            }&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
        registerConfigurationOption: function (name, callback, hook) {&lt;br /&gt;
            // https://developer.mozilla.org/en-US/Add-ons/SDK/Tutorials/Add_a_Context_Menu_Item&lt;br /&gt;
            console.log(&amp;quot;config menu support n/a in firefox mode&amp;quot;);&lt;br /&gt;
            // https://developer.mozilla.org/en-US/Add-ons/SDK/Tutorials/Using_third-party_modules_%28jpm%29&lt;br /&gt;
            var menuitems = require(&amp;quot;menuitem&amp;quot;);&lt;br /&gt;
            var menuitem = menuitems.Menuitem({&lt;br /&gt;
                id: &amp;quot;clickme&amp;quot;,&lt;br /&gt;
                menuid: &amp;quot;menu_ToolsPopup&amp;quot;,&lt;br /&gt;
                label: name,&lt;br /&gt;
                onCommand: function () {&lt;br /&gt;
                    console.log(&amp;quot;menuitem clicked:&amp;quot;);&lt;br /&gt;
                    callback();&lt;br /&gt;
                },&lt;br /&gt;
                insertbefore: &amp;quot;menu_pageInfo&amp;quot;&lt;br /&gt;
            });&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
        registerTrigger: function () {&lt;br /&gt;
            // https://developer.mozilla.org/en-US/Add-ons/SDK/Tutorials/Add_a_Context_Menu_Item&lt;br /&gt;
            // https://developer.mozilla.org/en-US/Add-ons/SDK/High-Level_APIs/context-menu#Item%28options%29&lt;br /&gt;
            var contextMenu = require(&amp;quot;sdk/context-menu&amp;quot;);&lt;br /&gt;
            var menuItem = contextMenu.Item({&lt;br /&gt;
                label: &amp;quot;Instant Cquote&amp;quot;,&lt;br /&gt;
                context: contextMenu.SelectionContext(),&lt;br /&gt;
                // https://developer.mozilla.org/en/Add-ons/SDK/Guides/Two_Types_of_Scripts&lt;br /&gt;
                // https://developer.mozilla.org/en-US/Add-ons/SDK/Guides/Content_Scripts&lt;br /&gt;
                contentScript: 'self.on(&amp;quot;click&amp;quot;, function () {' +&lt;br /&gt;
                    '  var text = window.getSelection().toString();' +&lt;br /&gt;
                    '  self.postMessage(text);' +&lt;br /&gt;
                    '});',&lt;br /&gt;
                onMessage: function (selectionText) {&lt;br /&gt;
                    console.log(selectionText);&lt;br /&gt;
                    instantCquote(selectionText);&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            // for selection handling stuff, see: https://developer.mozilla.org/en-US/Add-ons/SDK/High-Level_APIs/selection&lt;br /&gt;
&lt;br /&gt;
            function myListener() {&lt;br /&gt;
                console.log(&amp;quot;A selection has been made.&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            var selection = require(&amp;quot;sdk/selection&amp;quot;);&lt;br /&gt;
            selection.on('select', myListener);&lt;br /&gt;
&lt;br /&gt;
        }, //registerTrigger&lt;br /&gt;
&lt;br /&gt;
        get_persistent: function (key, default_value) {&lt;br /&gt;
            // https://developer.mozilla.org/en-US/Add-ons/SDK/High-Level_APIs/simple-storage&lt;br /&gt;
            var ss = require(&amp;quot;sdk/simple-storage&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
            console.log(&lt;br /&gt;
                &amp;quot;firefox mode does not yet have persistence support&amp;quot;&lt;br /&gt;
            );&lt;br /&gt;
            return default_value;&lt;br /&gt;
        },&lt;br /&gt;
        set_persistent: function (key, value) {&lt;br /&gt;
            console.log(&amp;quot;firefox persistence stubs not yet filled in !&amp;quot;);&lt;br /&gt;
        },&lt;br /&gt;
        set_clipboard: function (content) {&lt;br /&gt;
            // https://developer.mozilla.org/en-US/Add-ons/SDK/High-Level_APIs/clipboard&lt;br /&gt;
&lt;br /&gt;
            //console.log('clipboard stub not yet filled in ...');&lt;br /&gt;
            var clipboard = require(&amp;quot;sdk/clipboard&amp;quot;);&lt;br /&gt;
            clipboard.set(content);&lt;br /&gt;
        } //set_cliipboard&lt;br /&gt;
&lt;br /&gt;
    }, // end of FireFox addon config&lt;br /&gt;
&lt;br /&gt;
    // placeholder for now ...&lt;br /&gt;
    Android: {&lt;br /&gt;
        // NOP&lt;br /&gt;
    }, // Android&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    ///////////////////////////////////////&lt;br /&gt;
    // supported  script engines:&lt;br /&gt;
    ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
    GreaseMonkey: {&lt;br /&gt;
        // TODO: move environment specific initialization code here&lt;br /&gt;
        init: function () {&lt;br /&gt;
            // Check if Greasemonkey/Tampermonkey is available&lt;br /&gt;
            try {&lt;br /&gt;
                // TODO: add version check for clipboard API and check for TamperMonkey/Scriptish equivalents?&lt;br /&gt;
                GM_addStyle(GM_getResourceText('jQUI_CSS'));&lt;br /&gt;
            } // try&lt;br /&gt;
            catch (error) {&lt;br /&gt;
                console.log(&lt;br /&gt;
                    'Could not add style or determine script version'&lt;br /&gt;
                );&lt;br /&gt;
            } // catch&lt;br /&gt;
&lt;br /&gt;
            var commands = [{&lt;br /&gt;
                name: 'Setup quotes',&lt;br /&gt;
                callback: setupDialog,&lt;br /&gt;
                hook: 'S'&lt;br /&gt;
            }, {&lt;br /&gt;
                name: 'Check quotes',&lt;br /&gt;
                callback: selfCheckDialog,&lt;br /&gt;
                hook: 'C'&lt;br /&gt;
            }];&lt;br /&gt;
&lt;br /&gt;
            for (let c of commands) {&lt;br /&gt;
                this.registerConfigurationOption(c.name, c.callback, c.hook);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
        }, // init()&lt;br /&gt;
&lt;br /&gt;
        getScriptVersion: function () {&lt;br /&gt;
            return GM_info.script.version;&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
        dbLog: function (message) {&lt;br /&gt;
            if (Boolean(DEBUG)) {&lt;br /&gt;
                console.log('Instant cquotes:' + message);&lt;br /&gt;
            }&lt;br /&gt;
        }, // dbLog()&lt;br /&gt;
&lt;br /&gt;
        registerConfigurationOption: function (name, callback, hook) {&lt;br /&gt;
            // https://wiki.greasespot.net/GM_registerMenuCommand&lt;br /&gt;
            // https://wiki.greasespot.net/Greasemonkey_Manual:Monkey_Menu#The_Menu&lt;br /&gt;
            GM_registerMenuCommand(name, callback, hook);&lt;br /&gt;
        }, //registerMenuCommand()&lt;br /&gt;
&lt;br /&gt;
        registerTrigger: function () {&lt;br /&gt;
&lt;br /&gt;
            // TODO: we can use the following callback non-interactively, i.e. to trigger background tasks&lt;br /&gt;
            // http://javascript.info/tutorial/onload-ondomcontentloaded&lt;br /&gt;
            document.addEventListener(&amp;quot;DOMContentLoaded&amp;quot;, function (&lt;br /&gt;
                event) {&lt;br /&gt;
                console.log(&lt;br /&gt;
                    &amp;quot;Instant Cquotes: DOM fully loaded and parsed&amp;quot;&lt;br /&gt;
                );&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            window.addEventListener('load', init); // page fully loaded&lt;br /&gt;
            Host.dbLog('Instant Cquotes: page load handler registered');&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            // Initialize (matching page loaded)&lt;br /&gt;
            function init() {&lt;br /&gt;
                console.log(&lt;br /&gt;
                    'Instant Cquotes: page load handler invoked');&lt;br /&gt;
                var profile = getProfile();&lt;br /&gt;
&lt;br /&gt;
                Host.dbLog(&amp;quot;Profile type is:&amp;quot; + profile.type);&lt;br /&gt;
&lt;br /&gt;
                // Dispatch to correct event handler (depending on website/URL)&lt;br /&gt;
                // TODO: this stuff could/should be moved into the config hash itself&lt;br /&gt;
&lt;br /&gt;
                if (profile.type == 'wiki') {&lt;br /&gt;
                    profile.event_handler(); // just for testing&lt;br /&gt;
                    return;&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                Host.dbLog('using default mode');&lt;br /&gt;
                document.onmouseup = instantCquote;&lt;br /&gt;
                // HACK: preparations for moving the the event/handler logic also into the profile hash, so that the wiki (edit mode) can be handled equally&lt;br /&gt;
                //eval(profile.event+&amp;quot;=instantCquote&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
            } // init()&lt;br /&gt;
&lt;br /&gt;
        }, // registerTrigger&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        download: function (url, callback, method = 'GET') {&lt;br /&gt;
            // http://wiki.greasespot.net/GM_xmlhttpRequest&lt;br /&gt;
            try {&lt;br /&gt;
                GM_xmlhttpRequest({&lt;br /&gt;
                    method: method,&lt;br /&gt;
                    url: url,&lt;br /&gt;
                    onload: callback&lt;br /&gt;
                });&lt;br /&gt;
            } catch (e) {&lt;br /&gt;
                console.log(&amp;quot;download did not work&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
        }, // download()&lt;br /&gt;
&lt;br /&gt;
        // is only intended to work with archives supported by the  hash&lt;br /&gt;
        downloadPosting: function (url, EventHandler) {&lt;br /&gt;
&lt;br /&gt;
            Host.download(url, function (response) {&lt;br /&gt;
                var profile = getProfile(url);&lt;br /&gt;
                var blob = response.responseText;&lt;br /&gt;
                var doc = Host.make_doc(blob, 'text/html');&lt;br /&gt;
                var result = {}; // hash to be returned&lt;br /&gt;
&lt;br /&gt;
                [].forEach.call(['author', 'date', 'title',&lt;br /&gt;
                    'content'&lt;br /&gt;
                ], function (field) {&lt;br /&gt;
                    var xpath_query = '//' + profile[&lt;br /&gt;
                        field].xpath;&lt;br /&gt;
                    try {&lt;br /&gt;
                        var value = Host.eval_xpath(doc,&lt;br /&gt;
                            xpath_query).stringValue;&lt;br /&gt;
                        //UI.alert(&amp;quot;extracted field value:&amp;quot;+value);&lt;br /&gt;
&lt;br /&gt;
                        // now apply all transformations, if any&lt;br /&gt;
                        value = applyTransformations(&lt;br /&gt;
                            value, profile[field].transform&lt;br /&gt;
                        );&lt;br /&gt;
&lt;br /&gt;
                        result[field] = value; // store the extracted/transormed value in the hash that we pass on&lt;br /&gt;
                    } // try&lt;br /&gt;
                    catch (e) {&lt;br /&gt;
                        UI.alert(&lt;br /&gt;
                            &amp;quot;downloadPosting failed:\n&amp;quot; +&lt;br /&gt;
                            e.message);&lt;br /&gt;
                    } // catch&lt;br /&gt;
                }); // forEach field&lt;br /&gt;
&lt;br /&gt;
                EventHandler(result); // pass the result to the handler&lt;br /&gt;
            }); // call to Host.download()&lt;br /&gt;
&lt;br /&gt;
        }, // downloadPosting()&lt;br /&gt;
&lt;br /&gt;
        // TODO: add makeAJAXCall, and makeWikiCall here&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        // turn a string/text blob into a DOM tree that can be queried (e.g. for xpath expressions)&lt;br /&gt;
        // FIXME: this is browser specific not GM specific ...&lt;br /&gt;
        make_doc: function (text, type = 'text/html') {&lt;br /&gt;
            // to support other browsers, see: https://developer.mozilla.org/en/docs/Web/API/DOMParser&lt;br /&gt;
            return new DOMParser().parseFromString(text, type);&lt;br /&gt;
        }, // make DOM document&lt;br /&gt;
&lt;br /&gt;
        // xpath handling may be handled separately depending on browser/platform, so better encapsulate this&lt;br /&gt;
        // FIXME: this is browser specific not GM specific ...&lt;br /&gt;
        eval_xpath: function (doc, xpath, type = XPathResult.STRING_TYPE) {&lt;br /&gt;
            return doc.evaluate(xpath, doc, null, type, null);&lt;br /&gt;
        }, // eval_xpath&lt;br /&gt;
&lt;br /&gt;
        set_persistent: function (key, value, json = false) {&lt;br /&gt;
            // transparently stringify to json&lt;br /&gt;
            if (json) {&lt;br /&gt;
                // http://stackoverflow.com/questions/16682150/store-a-persistent-list-between-sessions&lt;br /&gt;
                value = JSON.stringify(value);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // https://wiki.greasespot.net/GM_setValue&lt;br /&gt;
            GM_setValue(key, value);&lt;br /&gt;
            //UI.alert('Saved value for key\n'+key+':'+value);&lt;br /&gt;
        }, // set_persistent&lt;br /&gt;
&lt;br /&gt;
        get_persistent: function (key, default_value, json = false) {&lt;br /&gt;
            // https://wiki.greasespot.net/GM_getValue&lt;br /&gt;
&lt;br /&gt;
            var value = GM_getValue(key, default_value);&lt;br /&gt;
            // transparently support JSON: http://stackoverflow.com/questions/16682150/store-a-persistent-list-between-sessions&lt;br /&gt;
            if (json) {&lt;br /&gt;
                value = JSON.parse(value) || {};&lt;br /&gt;
            }&lt;br /&gt;
            return value;&lt;br /&gt;
        }, // get_persistent&lt;br /&gt;
&lt;br /&gt;
        setClipboard: function (msg) {&lt;br /&gt;
            // this being a greasemonkey user-script, we are not&lt;br /&gt;
            // subject to usual browser restrictions&lt;br /&gt;
            // http://wiki.greasespot.net/GM_setClipboard&lt;br /&gt;
            GM_setClipboard(msg);&lt;br /&gt;
        }, // setClipboard()&lt;br /&gt;
&lt;br /&gt;
        getTemplate: function () {&lt;br /&gt;
&lt;br /&gt;
                // hard-coded default template&lt;br /&gt;
                var template = '$CONTENT&amp;lt;ref&amp;gt;{{cite web\n' +&lt;br /&gt;
                    '  |url    =  $URL \n' +&lt;br /&gt;
                    '  |title  =  &amp;lt;nowiki&amp;gt; $TITLE &amp;lt;/nowiki&amp;gt; \n' +&lt;br /&gt;
                    '  |author =  &amp;lt;nowiki&amp;gt; $AUTHOR &amp;lt;/nowiki&amp;gt; \n' +&lt;br /&gt;
                    '  |date   =  $DATE \n' +&lt;br /&gt;
                    '  |added  =  $ADDED \n' +&lt;br /&gt;
                    '  |script_version = $SCRIPT_VERSION \n' +&lt;br /&gt;
                    '  }}&amp;lt;/ref&amp;gt;\n';&lt;br /&gt;
&lt;br /&gt;
                // return a saved template if found, fall back to hard-coded one above otherwise&lt;br /&gt;
                return Host.get_persistent('default_template', template);&lt;br /&gt;
&lt;br /&gt;
            } // getTemplate&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    } // end of GreaseMonkey environment, add other environments below&lt;br /&gt;
&lt;br /&gt;
}; // Environment hash - intended to help encapsulate host specific stuff (APIs)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// the first thing we need to do is to determine what APIs are available&lt;br /&gt;
// and store everything in a Host hash, which is subsequently used for API lookups&lt;br /&gt;
// the Host hash contains all platform/browser-specific APIs&lt;br /&gt;
var Host = Environment.getHost();&lt;br /&gt;
Environment.validate(Host); // this checks the obtained host to see if all required dependencies are available&lt;br /&gt;
Host.init(); // run environment specific initialization code (e.g. logic for GreaseMonkey setup)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// move DEBUG handling to a persistent configuration flag so that we can&lt;br /&gt;
// configure this using a jQuery dialog (defaulted to false)&lt;br /&gt;
// TODO: move DEBUG variable to Environment hash / init() routine&lt;br /&gt;
var DEBUG = Host.get_persistent('debug_mode_enabled', false);&lt;br /&gt;
Host.dbLog(&amp;quot;Debug mode is:&amp;quot; + DEBUG);&lt;br /&gt;
&lt;br /&gt;
function DEBUG_mode() {&lt;br /&gt;
    // reset script invocation counter for testing purposes&lt;br /&gt;
    Host.dbLog('Resetting script invocation counter');&lt;br /&gt;
    Host.set_persistent(GM_info.script.version, 0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if (DEBUG)&lt;br /&gt;
    DEBUG_mode();&lt;br /&gt;
&lt;br /&gt;
// hash with supported websites/URLs,  includes xpath and regex expressions to&lt;br /&gt;
// extract certain fields, and a vector with optional transformations for&lt;br /&gt;
// post-processing each field&lt;br /&gt;
&lt;br /&gt;
var CONFIG = {&lt;br /&gt;
    // WIP: the first entry is special, i.e. it's not an actual list archive (source), but only added here so that the same script can be used&lt;br /&gt;
    // for editing the FlightGear wiki&lt;br /&gt;
&lt;br /&gt;
    'FlightGear.wiki': {&lt;br /&gt;
        type: 'wiki',&lt;br /&gt;
        enabled: false,&lt;br /&gt;
        event: 'document.onmouseup', // when to invoke the event handler&lt;br /&gt;
        // TODO: move downloadWatchlist() etc here&lt;br /&gt;
        event_handler: function () {&lt;br /&gt;
            console.log(&lt;br /&gt;
                'FlightGear wiki handler active (waiting to be populated)'&lt;br /&gt;
            );&lt;br /&gt;
            // this is where the logic for a wiki mode can be added over time (for now, it's a NOP)&lt;br /&gt;
&lt;br /&gt;
            //for each supported mode, invoke the trigger and call the corresponding handler&lt;br /&gt;
            [].forEach.call(CONFIG['FlightGear.wiki'].modes, function (&lt;br /&gt;
                mode) {&lt;br /&gt;
                //dbLog(&amp;quot;Checking trigger:&amp;quot;+mode.name);&lt;br /&gt;
                if (mode.trigger()) {&lt;br /&gt;
                    mode.handler();&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
        }, // the event handler to be invoked&lt;br /&gt;
        url_reg: '^(http|https)://wiki.flightgear.org', // ignore for now: not currently used by the wiki mode&lt;br /&gt;
&lt;br /&gt;
        modes: [{&lt;br /&gt;
                    name: 'process-editSections',&lt;br /&gt;
                    trigger: function () {&lt;br /&gt;
                        return true;&lt;br /&gt;
                    }, // match URL regex - return true for always match&lt;br /&gt;
&lt;br /&gt;
                    // the code implementing the mode&lt;br /&gt;
                    handler: function () {&lt;br /&gt;
&lt;br /&gt;
                            var editSections = document.getElementsByClassName(&lt;br /&gt;
                                'mw-editsection');&lt;br /&gt;
                            console.log(&lt;br /&gt;
                                'FlightGear wiki article, number of edit sections: ' +&lt;br /&gt;
                                editSections.length);&lt;br /&gt;
&lt;br /&gt;
                            // for now, just rewrite edit sections and add a note to them&lt;br /&gt;
&lt;br /&gt;
                            [].forEach.call(editSections, function (sec) {&lt;br /&gt;
                                sec.appendChild(&lt;br /&gt;
                                    document.createTextNode(&lt;br /&gt;
                                        ' (instant-cquotes is lurking) '&lt;br /&gt;
                                    )&lt;br /&gt;
                                );&lt;br /&gt;
                            }); //forEach section&lt;br /&gt;
                        } // handler&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                } // process-editSections&lt;br /&gt;
                // TODO: add other wiki modes below&lt;br /&gt;
&lt;br /&gt;
            ] // modes&lt;br /&gt;
&lt;br /&gt;
    }, // end of wiki profile&lt;br /&gt;
&lt;br /&gt;
    'Sourceforge Mailing list': {&lt;br /&gt;
        enabled: true,&lt;br /&gt;
        type: 'archive',&lt;br /&gt;
        event: 'document.onmouseup', // when to invoke the event handler&lt;br /&gt;
        event_handler: instantCquote, // the event handler to be invoked&lt;br /&gt;
        url_reg: '^(http|https)://sourceforge.net/p/flightgear/mailman/.*/',&lt;br /&gt;
        content: {&lt;br /&gt;
            xpath: 'tbody/tr[2]/td/pre/text()', // NOTE this is only used by the downloadPosting  helper to retrieve the posting without having a selection (TODO:add content xpath to forum hash)&lt;br /&gt;
            selection: getSelectedText,&lt;br /&gt;
            idStyle: /msg[0-9]{8}/,&lt;br /&gt;
            parentTag: [&lt;br /&gt;
                'tagName',&lt;br /&gt;
                'PRE'&lt;br /&gt;
            ],&lt;br /&gt;
            transform: [],&lt;br /&gt;
        }, // content recipe&lt;br /&gt;
        // vector with tests to be executed for sanity checks (unit testing)&lt;br /&gt;
        tests: [{&lt;br /&gt;
                url: 'https://sourceforge.net/p/flightgear/mailman/message/35059454/',&lt;br /&gt;
                author: 'Erik Hofman',&lt;br /&gt;
                date: 'May 3rd, 2016', // NOTE: using the transformed date here&lt;br /&gt;
                title: 'Re: [Flightgear-devel] Auto altimeter setting at startup (?)'&lt;br /&gt;
            }, {&lt;br /&gt;
                url: 'https://sourceforge.net/p/flightgear/mailman/message/35059961/',&lt;br /&gt;
                author: 'Ludovic Brenta',&lt;br /&gt;
                date: 'May 3rd, 2016',&lt;br /&gt;
                title: 'Re: [Flightgear-devel] dual-control-tools and the limit on packet size'&lt;br /&gt;
            }, {&lt;br /&gt;
                url: 'https://sourceforge.net/p/flightgear/mailman/message/20014126/',&lt;br /&gt;
                author: 'Tim Moore',&lt;br /&gt;
                date: 'Aug 4th, 2008',&lt;br /&gt;
                title: 'Re: [Flightgear-devel] Cockpit displays (rendering, modelling)'&lt;br /&gt;
            }, {&lt;br /&gt;
                url: 'https://sourceforge.net/p/flightgear/mailman/message/23518343/',&lt;br /&gt;
                author: 'Tim Moore',&lt;br /&gt;
                date: 'Sep 10th, 2009',&lt;br /&gt;
                title: '[Flightgear-devel] Atmosphere patch from John Denker'&lt;br /&gt;
            } // add other tests below&lt;br /&gt;
&lt;br /&gt;
        ], // end of vector with self-tests&lt;br /&gt;
        // regex/xpath and transformations for extracting various required fields&lt;br /&gt;
        author: {&lt;br /&gt;
            xpath: 'tbody/tr[1]/td/div/small/text()',&lt;br /&gt;
            transform: [extract(/From: (.*) &amp;lt;.*@.*&amp;gt;/)]&lt;br /&gt;
        },&lt;br /&gt;
        title: {&lt;br /&gt;
            xpath: 'tbody/tr[1]/td/div/div[1]/b/a/text()',&lt;br /&gt;
            transform: []&lt;br /&gt;
        },&lt;br /&gt;
        date: {&lt;br /&gt;
            xpath: 'tbody/tr[1]/td/div/small/text()',&lt;br /&gt;
            transform: [extract(/- (.*-.*-.*) /)]&lt;br /&gt;
        },&lt;br /&gt;
        url: {&lt;br /&gt;
            xpath: 'tbody/tr[1]/td/div/div[1]/b/a/@href',&lt;br /&gt;
            transform: [prepend('https://sourceforge.net')]&lt;br /&gt;
        }&lt;br /&gt;
    }, // end of mailing list profile&lt;br /&gt;
    // next website/URL (forum)&lt;br /&gt;
    'FlightGear forum': {&lt;br /&gt;
        enabled: true,&lt;br /&gt;
        type: 'archive',&lt;br /&gt;
        event: 'document.onmouseup', // when to invoke the event handler (not used atm)&lt;br /&gt;
        event_handler: null, // the event handler to be invoked (not used atm)&lt;br /&gt;
        url_reg: /https:\/\/forum\.flightgear\.org\/.*/,&lt;br /&gt;
        content: {&lt;br /&gt;
            xpath: '', //TODO: this must be added for downloadPosting() to work, or it cannot extract contents&lt;br /&gt;
            selection: getSelectedHtml,&lt;br /&gt;
            idStyle: /p[0-9]{6}/,&lt;br /&gt;
            parentTag: [&lt;br /&gt;
                'className',&lt;br /&gt;
                'content',&lt;br /&gt;
                'postbody'&lt;br /&gt;
            ],&lt;br /&gt;
            transform: [&lt;br /&gt;
                removeComments,&lt;br /&gt;
                forum_quote2cquote,&lt;br /&gt;
                forum_smilies2text,&lt;br /&gt;
                forum_fontstyle2wikistyle,&lt;br /&gt;
                forum_code2syntaxhighlight,&lt;br /&gt;
                img2link,&lt;br /&gt;
                a2wikilink,&lt;br /&gt;
                vid2wiki,&lt;br /&gt;
                list2wiki,&lt;br /&gt;
                forum_br2newline&lt;br /&gt;
            ]&lt;br /&gt;
        },&lt;br /&gt;
        // vector with tests to be executed for sanity checks (unit testing)&lt;br /&gt;
        // postings will be downloaded using the URL specified, and then the author/title&lt;br /&gt;
        // fields extracted using the outer regex and matched against what is expected&lt;br /&gt;
        // NOTE: forum postings can be edited, so that these tests would fail - thus, it makes sense to pick locked topics/postings for such tests&lt;br /&gt;
        tests: [{&lt;br /&gt;
                url: 'https://forum.flightgear.org/viewtopic.php?f=18&amp;amp;p=284108#p284108',&lt;br /&gt;
                author: 'mickybadia',&lt;br /&gt;
                date: 'May 3rd, 2016',&lt;br /&gt;
                title: 'OSM still PNG maps'&lt;br /&gt;
            }, {&lt;br /&gt;
                url: 'https://forum.flightgear.org/viewtopic.php?f=19&amp;amp;p=284120#p284120',&lt;br /&gt;
                author: 'Thorsten',&lt;br /&gt;
                date: 'May 3rd, 2016',&lt;br /&gt;
                title: 'Re: FlightGear\'s Screenshot Of The Month MAY 2016'&lt;br /&gt;
            }, {&lt;br /&gt;
                url: 'https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;t=29279&amp;amp;p=283455#p283446',&lt;br /&gt;
                author: 'Hooray',&lt;br /&gt;
                date: 'Apr 25th, 2016',&lt;br /&gt;
                title: 'Re: Best way to learn Canvas?'&lt;br /&gt;
            }, {&lt;br /&gt;
                url: 'https://forum.flightgear.org/viewtopic.php?f=4&amp;amp;t=1460&amp;amp;p=283994#p283994',&lt;br /&gt;
                author: 'bugman',&lt;br /&gt;
                date: 'May 2nd, 2016',&lt;br /&gt;
                title: 'Re: eurofighter typhoon'&lt;br /&gt;
            } // add other tests below&lt;br /&gt;
&lt;br /&gt;
        ], // end of vector with self-tests&lt;br /&gt;
        author: {&lt;br /&gt;
            xpath: 'div/div[1]/p/strong/a/text()',&lt;br /&gt;
            transform: [] // no transformations applied&lt;br /&gt;
        },&lt;br /&gt;
        title: {&lt;br /&gt;
            xpath: 'div/div[1]/h3/a/text()',&lt;br /&gt;
            transform: [] // no transformations applied&lt;br /&gt;
        },&lt;br /&gt;
        date: {&lt;br /&gt;
            xpath: 'div/div[1]/p/text()[2]',&lt;br /&gt;
            transform: [extract(/» (.*?[0-9]{4})/)]&lt;br /&gt;
        },&lt;br /&gt;
        url: {&lt;br /&gt;
            xpath: 'div/div[1]/p/a/@href',&lt;br /&gt;
            transform: [&lt;br /&gt;
                    extract(/\.(.*)/),&lt;br /&gt;
                    prepend('https://forum.flightgear.org')&lt;br /&gt;
                ] // transform vector&lt;br /&gt;
        } // url&lt;br /&gt;
    } // forum&lt;br /&gt;
}; // CONFIG has&lt;br /&gt;
&lt;br /&gt;
// hash to map URLs (wiki article, issue tracker, sourceforge link, forum thread etc) to existing wiki templates&lt;br /&gt;
var MatchURL2Templates = [&lt;br /&gt;
    // placeholder for now&lt;br /&gt;
    {&lt;br /&gt;
        name: 'rewrite sourceforge code links',&lt;br /&gt;
        url_reg: '',&lt;br /&gt;
        handler: function () {&lt;br /&gt;
&lt;br /&gt;
            } // handler&lt;br /&gt;
&lt;br /&gt;
    } // add other templates below&lt;br /&gt;
&lt;br /&gt;
]; // MatchURL2Templates&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// output methods (alert and jQuery for now)&lt;br /&gt;
var OUTPUT = {&lt;br /&gt;
    // Shows a window.prompt() message box&lt;br /&gt;
    msgbox: function (msg) {&lt;br /&gt;
        UI.prompt('Copy to clipboard ' + Host.getScriptVersion(), msg);&lt;br /&gt;
        Host.setClipboard(msg);&lt;br /&gt;
    }, // msgbox&lt;br /&gt;
&lt;br /&gt;
    // this is currently work-in-progress, and will need to be refactored sooner or later&lt;br /&gt;
    // for now, functionality matters more than elegant design/code :)&lt;br /&gt;
    jQueryTabbed: function (msg, original) {&lt;br /&gt;
            // FIXME: using backtics here makes the whole thing require ES6  ....&lt;br /&gt;
            var markup = $(&lt;br /&gt;
                `&amp;lt;div id=&amp;quot;tabs&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;ul&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#selection&amp;quot;&amp;gt;Selection&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#articles&amp;quot;&amp;gt;Articles&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#templates&amp;quot;&amp;gt;Templates&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#development&amp;quot;&amp;gt;Development&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#settings&amp;quot;&amp;gt;Settings&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#help&amp;quot;&amp;gt;Help&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#about&amp;quot;&amp;gt;About&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;/ul&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;selection&amp;quot;&amp;gt;This tab contains your extracted and post-processed selection, converted to proper wikimedia markup, including proper attribution.&lt;br /&gt;
  &amp;lt;div id=&amp;quot;content&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;label for=&amp;quot;template_select&amp;quot;&amp;gt;Select a template&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;select name=&amp;quot;template_select&amp;quot; id=&amp;quot;template_select&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;option&amp;gt;default&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option&amp;gt;cquote&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;/select&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;options&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Note this is work-in-progress, i.e. not yet fully functional&amp;lt;/b&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
    &amp;lt;label for=&amp;quot;article_select&amp;quot;&amp;gt;Select an article to update&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;select name=&amp;quot;article_select&amp;quot; id=&amp;quot;article_select&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;news&amp;quot; label=&amp;quot;News&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;support&amp;quot; label=&amp;quot;Support&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;release&amp;quot; label=&amp;quot;Release&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;develop&amp;quot; label=&amp;quot;Development&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;watchlist&amp;quot; label=&amp;quot;Watchlist&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;/select&amp;gt;&lt;br /&gt;
    &amp;lt;p/&amp;gt;&lt;br /&gt;
    &amp;lt;label for=&amp;quot;section_select&amp;quot;&amp;gt;Select section:&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;select name=&amp;quot;section_select&amp;quot; id=&amp;quot;section_select&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;/select&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;articles&amp;quot;&amp;gt;This tab contains articles that you can directly access/edit using the mediawiki API&amp;lt;br/&amp;gt;&lt;br /&gt;
  Note: The watchlist is retrieved dynamically, so does not need to be edited here&amp;lt;br/&amp;gt;&lt;br /&gt;
    &amp;lt;label for=&amp;quot;article_select&amp;quot;&amp;gt;Select an article&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;select name=&amp;quot;article_select&amp;quot; id=&amp;quot;article_select&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;news&amp;quot; label=&amp;quot;News&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;support&amp;quot; label=&amp;quot;Support&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;develop&amp;quot; label=&amp;quot;Development&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;release&amp;quot; label=&amp;quot;Release&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;!-- the watchlist is retrieved dynamically, so omit it here&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;watchlist&amp;quot; label=&amp;quot;Watchlist&amp;quot;/&amp;gt;&lt;br /&gt;
    --&amp;gt;&lt;br /&gt;
    &amp;lt;/select&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;button id=&amp;quot;article_new&amp;quot;&amp;gt;New&amp;lt;/button&amp;gt;&lt;br /&gt;
   &amp;lt;button id=&amp;quot;article_remove&amp;quot;&amp;gt;Remove&amp;lt;/button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div id=&amp;quot;edit_article&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;label for=&amp;quot;article_name&amp;quot;&amp;gt;Article&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;text&amp;quot; id=&amp;quot;article_name&amp;quot; name=&amp;quot;article_name&amp;quot;&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;label for=&amp;quot;article_url&amp;quot;&amp;gt;Link&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;text&amp;quot; id=&amp;quot;article_url&amp;quot; name=&amp;quot;article_url&amp;quot;&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;button id=&amp;quot;article_save&amp;quot;&amp;gt;Save&amp;lt;/button&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;templates&amp;quot;&amp;gt;This tab contains templates for different types of articles (newsletter, changelog, release plan etc)&amp;lt;p/&amp;gt;&lt;br /&gt;
  For now, this is WIP - in the future, there will be a dropdown menu added and all templates will be editable.&amp;lt;p/&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;template_header&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;label for=&amp;quot;template_select&amp;quot;&amp;gt;Select a template&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;select name=&amp;quot;template_select&amp;quot; id=&amp;quot;template_select&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;option&amp;gt;default&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option&amp;gt;cquote&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;/select&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;template_area&amp;quot;/&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;template_controls&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;button id=&amp;quot;template_save&amp;quot;&amp;gt;Save&amp;lt;/button&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;development&amp;quot;&amp;gt;This tab is a placeholder for features currently under development&amp;lt;p/&amp;gt;&lt;br /&gt;
  &amp;lt;button id=&amp;quot;evolve_regex&amp;quot;&amp;gt;Evolve regex&amp;lt;/button&amp;gt;&amp;lt;p/&amp;gt;&lt;br /&gt;
  &amp;lt;button id=&amp;quot;test_perceptron&amp;quot;&amp;gt;Test Perceptron&amp;lt;/button&amp;gt;&amp;lt;p/&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;output&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table id=&amp;quot;results&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;thead&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
     &amp;lt;th&amp;gt;Generation&amp;lt;/th&amp;gt;&lt;br /&gt;
     &amp;lt;th&amp;gt;Fitness&amp;lt;/th&amp;gt;&lt;br /&gt;
     &amp;lt;th&amp;gt;Expression&amp;lt;/th&amp;gt;&lt;br /&gt;
     &amp;lt;th&amp;gt;Result&amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
  &amp;lt;/thead&amp;gt;&lt;br /&gt;
  &amp;lt;tbody&amp;gt;&lt;br /&gt;
  &amp;lt;/tbody&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;!--&lt;br /&gt;
   &amp;lt;textarea id=&amp;quot;devel_output&amp;quot; lines=&amp;quot;10&amp;quot;&amp;gt;&amp;lt;/textarea&amp;gt;&amp;lt;p/&amp;gt;&lt;br /&gt;
  --&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div id=&amp;quot;settings&amp;quot;&amp;gt;This tab will contain script specific settings&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;help&amp;quot;&amp;gt;One day, this tab may contain help....&amp;lt;p/&amp;gt;&amp;lt;button id=&amp;quot;helpButton&amp;quot;&amp;gt;Instant Cquotes&amp;lt;/button&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;about&amp;quot;&amp;gt;show some  script related information here&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;`&lt;br /&gt;
            ); // tabs div&lt;br /&gt;
&lt;br /&gt;
            var evolve_regex = $('div#development button#evolve_regex',&lt;br /&gt;
                markup);&lt;br /&gt;
            evolve_regex.click(function () {&lt;br /&gt;
                //alert(&amp;quot;Evolve regex&amp;quot;);&lt;br /&gt;
                evolve_expression_test();&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            var test_perceptron = $(&lt;br /&gt;
                'div#development button#test_perceptron', markup);&lt;br /&gt;
            test_perceptron.click(function () {&lt;br /&gt;
                alert(&amp;quot;Test perceptron&amp;quot;);&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            // add dynamic elements to each tab&lt;br /&gt;
&lt;br /&gt;
            // NOTE: this affects all template selectors, on all tabs&lt;br /&gt;
            $('select#template_select', markup).change(function () {&lt;br /&gt;
                UI.alert(&lt;br /&gt;
                    &amp;quot;Sorry, templates are not yet fully implemented (WIP)&amp;quot;&lt;br /&gt;
                );&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            var help = $('#helpButton', markup);&lt;br /&gt;
            help.button();&lt;br /&gt;
            help.click(function () {&lt;br /&gt;
                window.open(&lt;br /&gt;
                    &amp;quot;http://wiki.flightgear.org/FlightGear_wiki:Instant-Cquotes&amp;quot;&lt;br /&gt;
                );&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            // rows=&amp;quot;10&amp;quot;cols=&amp;quot;80&amp;quot; style=&amp;quot; width: 420px; height: 350px&amp;quot;&lt;br /&gt;
            var textarea = $(&lt;br /&gt;
                '&amp;lt;textarea id=&amp;quot;quotedtext&amp;quot; rows=&amp;quot;20&amp;quot; cols=&amp;quot;70&amp;quot;/&amp;gt;');&lt;br /&gt;
            textarea.val(msg);&lt;br /&gt;
            $('#selection #content', markup).append(textarea);&lt;br /&gt;
&lt;br /&gt;
            var templateArea = $(&lt;br /&gt;
                '&amp;lt;textarea id=&amp;quot;template-edit&amp;quot; rows=&amp;quot;20&amp;quot; cols=&amp;quot;70&amp;quot;/&amp;gt;');&lt;br /&gt;
            templateArea.val(Host.getTemplate());&lt;br /&gt;
            $('div#templates div#template_area', markup).append(&lt;br /&gt;
                templateArea);&lt;br /&gt;
&lt;br /&gt;
            //$('#templates', markup).append($('&amp;lt;button&amp;gt;'));&lt;br /&gt;
            $('div#templates div#template_controls button#template_save',&lt;br /&gt;
                markup).button().click(function () {&lt;br /&gt;
                //UI.alert(&amp;quot;Saving template:\n&amp;quot;+templateArea.val() );&lt;br /&gt;
&lt;br /&gt;
                Host.set_persistent('default_template',&lt;br /&gt;
                    templateArea.val());&lt;br /&gt;
            }); // save template&lt;br /&gt;
&lt;br /&gt;
            // TODO: Currently, this is hard-coded, but should be made customizable via the &amp;quot;articles&amp;quot; tab at some point ...&lt;br /&gt;
            var articles = [&lt;br /&gt;
                // NOTE: category must match an existing &amp;lt;optgroup&amp;gt; above, title must match an existing wiki article&lt;br /&gt;
                {&lt;br /&gt;
                    category: 'support',&lt;br /&gt;
                    name: 'Frequently asked questions',&lt;br /&gt;
                    url: ''&lt;br /&gt;
                }, {&lt;br /&gt;
                    category: 'support',&lt;br /&gt;
                    name: 'Asking for help',&lt;br /&gt;
                    url: ''&lt;br /&gt;
                }, {&lt;br /&gt;
                    category: 'news',&lt;br /&gt;
                    name: 'Next newsletter',&lt;br /&gt;
                    url: ''&lt;br /&gt;
                }, {&lt;br /&gt;
                    category: 'news',&lt;br /&gt;
                    name: 'Next changelog',&lt;br /&gt;
                    url: ''&lt;br /&gt;
                }, {&lt;br /&gt;
                    category: 'release',&lt;br /&gt;
                    name: 'Release plan/Lessons learned',&lt;br /&gt;
                    url: ''&lt;br /&gt;
                }, // TODO: use wikimedia template&lt;br /&gt;
                {&lt;br /&gt;
                    category: 'develop',&lt;br /&gt;
                    name: 'Nasal library',&lt;br /&gt;
                    url: ''&lt;br /&gt;
                }, {&lt;br /&gt;
                    category: 'develop',&lt;br /&gt;
                    name: 'Canvas Snippets',&lt;br /&gt;
                    url: ''&lt;br /&gt;
                },&lt;br /&gt;
&lt;br /&gt;
            ];&lt;br /&gt;
&lt;br /&gt;
            // TODO: this should be moved elsewhere&lt;br /&gt;
            function updateArticleList(selector) {&lt;br /&gt;
                $.each(articles, function (i, article) {&lt;br /&gt;
                    $(selector + ' optgroup#' + article.category,&lt;br /&gt;
                        markup).append($('&amp;lt;option&amp;gt;', {&lt;br /&gt;
                        value: article.name, // FIXME: just a placeholder for now&lt;br /&gt;
                        text: article.name&lt;br /&gt;
                    })); //append option&lt;br /&gt;
                }); // foreach&lt;br /&gt;
            } // updateArticleList&lt;br /&gt;
&lt;br /&gt;
            // add the article list to the corresponding dropdown menus&lt;br /&gt;
            updateArticleList('select#article_select');&lt;br /&gt;
&lt;br /&gt;
            // populate watchlist (prototype for now)&lt;br /&gt;
            // TODO: generalize &amp;amp; refactor: url, format&lt;br /&gt;
&lt;br /&gt;
            // https://www.mediawiki.org/wiki/API:Watchlist&lt;br /&gt;
            // http://wiki.flightgear.org/api.php?action=query&amp;amp;list=watchlist&lt;br /&gt;
            var watchlist_url =&lt;br /&gt;
                'http://wiki.flightgear.org/api.php?action=query&amp;amp;list=watchlist&amp;amp;format=json';&lt;br /&gt;
            Host.download(watchlist_url, function (response) {&lt;br /&gt;
                try {&lt;br /&gt;
                    var watchlist = JSON.parse(response.responseText);&lt;br /&gt;
&lt;br /&gt;
                    //$('div#options select#section_select', markup).empty(); // delete all sections&lt;br /&gt;
&lt;br /&gt;
                    $.each(watchlist.query.watchlist, function (i,&lt;br /&gt;
                        article) {&lt;br /&gt;
                        $(&lt;br /&gt;
                            'div#options select#article_select optgroup#watchlist',&lt;br /&gt;
                            markup).append($('&amp;lt;option&amp;gt;', {&lt;br /&gt;
                            value: article.title, //FIXME just a placeholder for now&lt;br /&gt;
                            text: article.title&lt;br /&gt;
                        }));&lt;br /&gt;
                    }); //foreach section&lt;br /&gt;
&lt;br /&gt;
                } catch (e) {&lt;br /&gt;
                    UI.alert(e.message);&lt;br /&gt;
                }&lt;br /&gt;
            }); // download &amp;amp; populate watchlist&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            // register an event handler for the main tab, so that article specific sections can be retrieved&lt;br /&gt;
            $('div#options select#article_select', markup).change(function () {&lt;br /&gt;
                var article = this.value;&lt;br /&gt;
&lt;br /&gt;
                // HACK: try to get a login token (actually not needed just for reading ...)&lt;br /&gt;
                Host.download(&lt;br /&gt;
                    'http://wiki.flightgear.org/api.php?action=query&amp;amp;prop=info|revisions&amp;amp;intoken=edit&amp;amp;rvprop=timestamp&amp;amp;titles=Main%20Page',&lt;br /&gt;
                    function (response) {&lt;br /&gt;
                        var message =&lt;br /&gt;
                            'FlightGear wiki login status (AJAX):';&lt;br /&gt;
                        var status = response.statusText;&lt;br /&gt;
&lt;br /&gt;
                        // populate dropdown menu with article sections&lt;br /&gt;
                        if (status === 'OK') {&lt;br /&gt;
&lt;br /&gt;
                            // Resolve redirects: https://www.mediawiki.org/wiki/API:Query#Resolving_redirects&lt;br /&gt;
                            var section_url =&lt;br /&gt;
                                'http://wiki.flightgear.org/api.php?action=parse&amp;amp;page=' +&lt;br /&gt;
                                encodeURIComponent(article) +&lt;br /&gt;
                                '&amp;amp;prop=sections&amp;amp;format=json&amp;amp;redirects';&lt;br /&gt;
                            Host.download(section_url, function (&lt;br /&gt;
                                response) {&lt;br /&gt;
                                try {&lt;br /&gt;
                                    var sections = JSON&lt;br /&gt;
                                        .parse(response&lt;br /&gt;
                                            .responseText&lt;br /&gt;
                                        );&lt;br /&gt;
&lt;br /&gt;
                                    $(&lt;br /&gt;
                                        'div#options select#section_select',&lt;br /&gt;
                                        markup).empty(); // delete all sections&lt;br /&gt;
&lt;br /&gt;
                                    $.each(sections.parse&lt;br /&gt;
                                        .sections,&lt;br /&gt;
                                        function (i,&lt;br /&gt;
                                            section&lt;br /&gt;
                                        ) {&lt;br /&gt;
                                            $(&lt;br /&gt;
                                                'div#options select#section_select',&lt;br /&gt;
                                                markup&lt;br /&gt;
                                            ).append(&lt;br /&gt;
                                                $(&lt;br /&gt;
                                                    '&amp;lt;option&amp;gt;', {&lt;br /&gt;
                                                        value: section&lt;br /&gt;
                                                            .line, //FIXME just a placeholder for now&lt;br /&gt;
                                                        text: section&lt;br /&gt;
                                                            .line&lt;br /&gt;
                                                    }&lt;br /&gt;
                                                )&lt;br /&gt;
                                            );&lt;br /&gt;
                                        }); //foreach section&lt;br /&gt;
&lt;br /&gt;
                                } catch (e) {&lt;br /&gt;
                                    UI.alert(e.message);&lt;br /&gt;
                                }&lt;br /&gt;
&lt;br /&gt;
                            }); //download sections&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                        } // login status is OK&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    }); // Host.download() call, i.e. we have a login token&lt;br /&gt;
&lt;br /&gt;
            }); // on select change&lt;br /&gt;
&lt;br /&gt;
            // init the tab stuff&lt;br /&gt;
            markup.tabs();&lt;br /&gt;
&lt;br /&gt;
            var diagParam = {&lt;br /&gt;
                title: 'Instant Cquotes ' + Host.getScriptVersion(),&lt;br /&gt;
                modal: true,&lt;br /&gt;
                width: 700,&lt;br /&gt;
                buttons: [{&lt;br /&gt;
                        text: 'reported speech',&lt;br /&gt;
                        click: function () {&lt;br /&gt;
                            textarea.val(createCquote(original,&lt;br /&gt;
                                true));&lt;br /&gt;
                        }&lt;br /&gt;
                    },&lt;br /&gt;
&lt;br /&gt;
                    {&lt;br /&gt;
                        text: 'Copy',&lt;br /&gt;
                        click: function () {&lt;br /&gt;
                            Host.setClipboard(msg);&lt;br /&gt;
                            $(this).dialog('close');&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
&lt;br /&gt;
                ]&lt;br /&gt;
            };&lt;br /&gt;
&lt;br /&gt;
            // actually show our tabbed dialog using the params above&lt;br /&gt;
            markup.dialog(diagParam);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        } // jQueryTabbed()&lt;br /&gt;
&lt;br /&gt;
}; // output methods&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// TODO: we can use an online API to  help with some of this: http://www.eslnow.org/reported-speech-converter/&lt;br /&gt;
// See also: http://blog.mashape.com/list-of-25-natural-language-processing-apis/&lt;br /&gt;
// http://text-processing.com/docs/phrases.html&lt;br /&gt;
// http://www.alchemyapi.com/&lt;br /&gt;
// https://words.bighugelabs.com/api.php&lt;br /&gt;
// https://www.wordsapi.com/&lt;br /&gt;
// http://www.dictionaryapi.com/&lt;br /&gt;
// https://www.textrazor.com/&lt;br /&gt;
// http://www.programmableweb.com/news/how-5-natural-language-processing-apis-stack/analysis/2014/07/28&lt;br /&gt;
&lt;br /&gt;
var speechTransformations = [&lt;br /&gt;
    // TODO: support aliasing using vectors: would/should&lt;br /&gt;
    // ordering is crucial here (most specific first, least specific/most generic last)&lt;br /&gt;
&lt;br /&gt;
    // first, we start off  by expanding short forms: http://www.learnenglish.de/grammar/shortforms.html&lt;br /&gt;
    // http://www.macmillandictionary.com/thesaurus-category/british/short-forms&lt;br /&gt;
&lt;br /&gt;
    {&lt;br /&gt;
        query: /couldn\'t/gi,&lt;br /&gt;
        replacement: 'could not'&lt;br /&gt;
    }, {&lt;br /&gt;
        query: /I could not/gi,&lt;br /&gt;
        replacement: '$author could not'&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
    {&lt;br /&gt;
        query: /I\'m/gi,&lt;br /&gt;
        replacement: 'I am'&lt;br /&gt;
    }, {&lt;br /&gt;
        query: /I am/gi,&lt;br /&gt;
        replacement: '$author is'&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
    {&lt;br /&gt;
        query: /I\'ve/,&lt;br /&gt;
        replacement: 'I have'&lt;br /&gt;
    }, {&lt;br /&gt;
        query: /I have had/,&lt;br /&gt;
        replacement: '$author had'&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    {&lt;br /&gt;
        query: /can(\'|\’)t/gi,&lt;br /&gt;
        replacement: 'cannot'&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
    {&lt;br /&gt;
        query: /I(\'|\’)ll/gi,&lt;br /&gt;
        replacement: '$author will'&lt;br /&gt;
    }, {&lt;br /&gt;
        query: /I(\'|\’)d/gi,&lt;br /&gt;
        replacement: '$author would'&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
    {&lt;br /&gt;
        query: /I have done/gi,&lt;br /&gt;
        replacement: '$author has done'&lt;br /&gt;
    }, {&lt;br /&gt;
        query: /I\'ve done/gi,&lt;br /&gt;
        replacement: '$author has done'&lt;br /&gt;
    }, //FIXME. queries should really be vectors ...&lt;br /&gt;
&lt;br /&gt;
    {&lt;br /&gt;
        query: /I believe/gi,&lt;br /&gt;
        replacement: '$author suggested'&lt;br /&gt;
    }, {&lt;br /&gt;
        query: /I think/gi,&lt;br /&gt;
        replacement: '$author suggested'&lt;br /&gt;
    }, {&lt;br /&gt;
        query: /I guess/gi,&lt;br /&gt;
        replacement: '$author believes'&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
    {&lt;br /&gt;
        query: /I can see that/gi,&lt;br /&gt;
        replacement: '$author suggested that'&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    {&lt;br /&gt;
        query: /I have got/gi,&lt;br /&gt;
        replacement: '$author has got'&lt;br /&gt;
    }, {&lt;br /&gt;
        query: /I\'ve got/gi,&lt;br /&gt;
        replacement: '$author has got'&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
    {&lt;br /&gt;
        query: /I\'d suggest/gi,&lt;br /&gt;
        replacement: '$author would suggest'&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
    {&lt;br /&gt;
        query: /I\’m prototyping/gi,&lt;br /&gt;
        replacement: '$author is prototyping'&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
    {&lt;br /&gt;
        query: /I myself/gi,&lt;br /&gt;
        replacement: '$author himself'&lt;br /&gt;
    }, {&lt;br /&gt;
        query: /I am/gi,&lt;br /&gt;
        replacement: ' $author is'&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
    {&lt;br /&gt;
        query: /I can see/gi,&lt;br /&gt;
        replacement: '$author can see'&lt;br /&gt;
    }, {&lt;br /&gt;
        query: /I can/gi,&lt;br /&gt;
        replacement: '$author can'&lt;br /&gt;
    }, {&lt;br /&gt;
        query: /I have/gi,&lt;br /&gt;
        replacement: '$author has'&lt;br /&gt;
    }, {&lt;br /&gt;
        query: /I should/g,&lt;br /&gt;
        replacement: '$author should'&lt;br /&gt;
    }, {&lt;br /&gt;
        query: /I shall/gi,&lt;br /&gt;
        replacement: '$author shall'&lt;br /&gt;
    }, {&lt;br /&gt;
        query: /I may/gi,&lt;br /&gt;
        replacement: '$author may'&lt;br /&gt;
    }, {&lt;br /&gt;
        query: /I will/gi,&lt;br /&gt;
        replacement: '$author will'&lt;br /&gt;
    }, {&lt;br /&gt;
        query: /I would/gi,&lt;br /&gt;
        replacement: '$author would'&lt;br /&gt;
    }, {&lt;br /&gt;
        query: /by myself/gi,&lt;br /&gt;
        replacement: 'by $author'&lt;br /&gt;
    }, {&lt;br /&gt;
        query: /and I/gi,&lt;br /&gt;
        replacement: 'and $author'&lt;br /&gt;
    }, {&lt;br /&gt;
        query: /and me/gi,&lt;br /&gt;
        replacement: 'and $author'&lt;br /&gt;
    }, {&lt;br /&gt;
        query: /and myself/gi,&lt;br /&gt;
        replacement: 'and $author'&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    // least specific stuff last (broad/generic stuff is kept as is, with author clarification added in parentheses)&lt;br /&gt;
    /*&lt;br /&gt;
    {query:/I/, replacement:'I ($author)'},&lt;br /&gt;
    {query:/me/, replacement:'me ($author)'},&lt;br /&gt;
    {query:/my/, replacement:'my ($author)'},&lt;br /&gt;
    {query:/myself/, replacement:'myself ($author)'},&lt;br /&gt;
    {query:/mine/, replacement:'$author'}&lt;br /&gt;
    */&lt;br /&gt;
];&lt;br /&gt;
&lt;br /&gt;
// try to assist in transforming speech using the transformation vector passed in&lt;br /&gt;
// still needs to be exposed via the UI&lt;br /&gt;
function transformSpeech(text, author, gender, transformations) {&lt;br /&gt;
    // WIP: foreach transformation in vector, replace the search pattern with the matched string (replacing author/gender as applicable)&lt;br /&gt;
    //alert(&amp;quot;text to be transformed:\n&amp;quot;+text);&lt;br /&gt;
    for (var i = 0; i &amp;lt; transformations.length; i++) {&lt;br /&gt;
        var token = transformations[i];&lt;br /&gt;
        // patch the replacement string using the correct author name&lt;br /&gt;
        var replacement = token.replacement.replace(/\$author/gi, author);&lt;br /&gt;
        text = text.replace(token.query, replacement);&lt;br /&gt;
    } // end of token transformation&lt;br /&gt;
    console.log(&amp;quot;transformed text is:&amp;quot; + text);&lt;br /&gt;
    return text;&lt;br /&gt;
} // transformSpeech&lt;br /&gt;
&lt;br /&gt;
// run a self-test&lt;br /&gt;
&lt;br /&gt;
(function () {&lt;br /&gt;
    var author = &amp;quot;John Doe&amp;quot;;&lt;br /&gt;
    var transformed = transformSpeech(&lt;br /&gt;
        &amp;quot;I have decided to commit a new feature&amp;quot;, author, null,&lt;br /&gt;
        speechTransformations);&lt;br /&gt;
    if (transformed !== author + &amp;quot; has decided to commit a new feature&amp;quot;)&lt;br /&gt;
        Host.dbLog(&lt;br /&gt;
            &amp;quot;FIXME: Speech transformations are not working correctly&amp;quot;);&lt;br /&gt;
})();&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
var MONTHS = [&lt;br /&gt;
    'Jan',&lt;br /&gt;
    'Feb',&lt;br /&gt;
    'Mar',&lt;br /&gt;
    'Apr',&lt;br /&gt;
    'May',&lt;br /&gt;
    'Jun',&lt;br /&gt;
    'Jul',&lt;br /&gt;
    'Aug',&lt;br /&gt;
    'Sep',&lt;br /&gt;
    'Oct',&lt;br /&gt;
    'Nov',&lt;br /&gt;
    'Dec'&lt;br /&gt;
];&lt;br /&gt;
// Conversion for forum emoticons&lt;br /&gt;
var EMOTICONS = [&lt;br /&gt;
    [/:shock:/g,&lt;br /&gt;
        'O_O'&lt;br /&gt;
    ],&lt;br /&gt;
    [&lt;br /&gt;
        /:lol:/g,&lt;br /&gt;
        '(lol)'&lt;br /&gt;
    ],&lt;br /&gt;
    [&lt;br /&gt;
        /:oops:/g,&lt;br /&gt;
        ':$'&lt;br /&gt;
    ],&lt;br /&gt;
    [&lt;br /&gt;
        /:cry:/g,&lt;br /&gt;
        ';('&lt;br /&gt;
    ],&lt;br /&gt;
    [&lt;br /&gt;
        /:evil:/g,&lt;br /&gt;
        '&amp;gt;:)'&lt;br /&gt;
    ],&lt;br /&gt;
    [&lt;br /&gt;
        /:twisted:/g,&lt;br /&gt;
        '3:)'&lt;br /&gt;
    ],&lt;br /&gt;
    [&lt;br /&gt;
        /:roll:/g,&lt;br /&gt;
        '(eye roll)'&lt;br /&gt;
    ],&lt;br /&gt;
    [&lt;br /&gt;
        /:wink:/g,&lt;br /&gt;
        ';)'&lt;br /&gt;
    ],&lt;br /&gt;
    [&lt;br /&gt;
        /:!:/g,&lt;br /&gt;
        '(!)'&lt;br /&gt;
    ],&lt;br /&gt;
    [&lt;br /&gt;
        /:\?:/g,&lt;br /&gt;
        '(?)'&lt;br /&gt;
    ],&lt;br /&gt;
    [&lt;br /&gt;
        /:idea:/g,&lt;br /&gt;
        '(idea)'&lt;br /&gt;
    ],&lt;br /&gt;
    [&lt;br /&gt;
        /:arrow:/g,&lt;br /&gt;
        '(-&amp;gt;)'&lt;br /&gt;
    ],&lt;br /&gt;
    [&lt;br /&gt;
        /:mrgreen:/g,&lt;br /&gt;
        'xD'&lt;br /&gt;
    ]&lt;br /&gt;
];&lt;br /&gt;
// ##################&lt;br /&gt;
// # Main functions #&lt;br /&gt;
// ##################&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// the required trigger is host specific (userscript vs. addon vs. android etc)&lt;br /&gt;
// for now, this merely wraps window.load mapping to the instantCquote callback&lt;br /&gt;
// below&lt;br /&gt;
Host.registerTrigger();&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// FIXME: function is currently referenced in CONFIG hash - event_handler, so&lt;br /&gt;
// cannot be easily moved across&lt;br /&gt;
// The main function&lt;br /&gt;
// TODO: split up, so that we can reuse the code elsewhere&lt;br /&gt;
function instantCquote(sel) {&lt;br /&gt;
    var profile = getProfile();&lt;br /&gt;
&lt;br /&gt;
    // TODO: use config hash here&lt;br /&gt;
    var selection = document.getSelection(),&lt;br /&gt;
        post_id = 0;&lt;br /&gt;
&lt;br /&gt;
    try {&lt;br /&gt;
        post_id = getPostId(selection, profile);&lt;br /&gt;
    } catch (error) {&lt;br /&gt;
        Host.dbLog('Failed extracting post id\nProfile:' + profile);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    if (selection.toString() === '') {&lt;br /&gt;
        Host.dbLog('No text is selected, aborting function');&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    if (!checkValid(selection, profile)) {&lt;br /&gt;
        Host.dbLog('Selection is not valid, aborting function');&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    try {&lt;br /&gt;
        transformationLoop(profile, post_id);&lt;br /&gt;
    } catch (e) {&lt;br /&gt;
        UI.alert(&amp;quot;Transformation loop:\n&amp;quot; + e.message);&lt;br /&gt;
    }&lt;br /&gt;
} // instantCquote&lt;br /&gt;
&lt;br /&gt;
// TODO: this needs to be refactored so that it can be also reused by the async/AJAX mode&lt;br /&gt;
// to extract fields in the background (i.e. move to a separate function)&lt;br /&gt;
function transformationLoop(profile, post_id) {&lt;br /&gt;
    var output = {},&lt;br /&gt;
        field;&lt;br /&gt;
    Host.dbLog(&amp;quot;Starting extraction/transformation loop&amp;quot;);&lt;br /&gt;
    for (field in profile) {&lt;br /&gt;
        if (field === 'name') continue;&lt;br /&gt;
        if (field === 'type' || field === 'event' || field === 'event_handler')&lt;br /&gt;
            continue; // skip fields that don't contain xpath expressions&lt;br /&gt;
        Host.dbLog(&amp;quot;Extracting field using field id:&amp;quot; + post_id);&lt;br /&gt;
        var fieldData = extractFieldInfo(profile, post_id, field);&lt;br /&gt;
        var transform = profile[field].transform;&lt;br /&gt;
        if (transform !== undefined) {&lt;br /&gt;
            Host.dbLog('Field \'' + field + '\' before transformation:\n\'' +&lt;br /&gt;
                fieldData + '\'');&lt;br /&gt;
            fieldData = applyTransformations(fieldData, transform);&lt;br /&gt;
            Host.dbLog('Field \'' + field + '\' after transformation:\n\'' +&lt;br /&gt;
                fieldData + '\'');&lt;br /&gt;
        }&lt;br /&gt;
        output[field] = fieldData;&lt;br /&gt;
    } // extract and transform all fields for the current profile (website)&lt;br /&gt;
    Host.dbLog(&amp;quot;extraction and transformation loop finished&amp;quot;);&lt;br /&gt;
    output.content = stripWhitespace(output.content);&lt;br /&gt;
&lt;br /&gt;
    var outputPlain = createCquote(output);&lt;br /&gt;
    outputText(outputPlain, output);&lt;br /&gt;
} // transformationLoop()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/// #############&lt;br /&gt;
&lt;br /&gt;
function runProfileTests() {&lt;br /&gt;
&lt;br /&gt;
    for (var profile in CONFIG) {&lt;br /&gt;
        if (CONFIG[profile].type != 'archive' || !CONFIG[profile].enabled)&lt;br /&gt;
            continue; // skip the wiki entry, because it's not an actual archive that we need to test&lt;br /&gt;
        // should be really moved to downloadPostign&lt;br /&gt;
        if (CONFIG[profile].content.xpath === '') console.log(&lt;br /&gt;
            &amp;quot;xpath for content extraction is empty, cannot procedurally extract contents&amp;quot;&lt;br /&gt;
        );&lt;br /&gt;
        for (var test in CONFIG[profile].tests) {&lt;br /&gt;
            var required_data = CONFIG[profile].tests[test];&lt;br /&gt;
            var title = required_data.title;&lt;br /&gt;
            //dbLog('Running test for posting titled:' + title);&lt;br /&gt;
            // fetch posting via getPostingDataAJAX() and compare to the fields we are looking for (author, title, date)&lt;br /&gt;
            //getPostingDataAJAX(profile, required_data.url);&lt;br /&gt;
            //alert(&amp;quot;required title:&amp;quot;+title);&lt;br /&gt;
        } // foreach test&lt;br /&gt;
&lt;br /&gt;
    } // foreach profile (website)&lt;br /&gt;
&lt;br /&gt;
} //runProfileTests&lt;br /&gt;
&lt;br /&gt;
function selfCheckDialog() {&lt;br /&gt;
    var sections = '&amp;lt;h3&amp;gt;Important APIs:&amp;lt;/h3&amp;gt;&amp;lt;div id=&amp;quot;api_checks&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;';&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    try {&lt;br /&gt;
        runProfileTests.call(undefined); // check website profiles&lt;br /&gt;
    } catch (e) {&lt;br /&gt;
        UI.alert(e.message);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (var profile in CONFIG) {&lt;br /&gt;
        // TODO: also check if enabled or not&lt;br /&gt;
        if (CONFIG[profile].type != 'archive') continue; // skip the wiki entry, because it's not an actual archive that we need to test&lt;br /&gt;
        var test_results = '';&lt;br /&gt;
        for (var test in CONFIG[profile].tests) {&lt;br /&gt;
            // var fieldData = extractFieldInfo(profile, post_id, 'author');&lt;br /&gt;
            test_results += CONFIG[profile].tests[test].title + '&amp;lt;p/&amp;gt;';&lt;br /&gt;
        }&lt;br /&gt;
        sections += '&amp;lt;h3&amp;gt;' + profile + ':&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;' + CONFIG[profile]&lt;br /&gt;
            .url_reg + '&amp;lt;/font&amp;gt;&amp;lt;/h3&amp;gt;&amp;lt;div&amp;gt;&amp;lt;p&amp;gt;' + test_results + '&amp;lt;/p&amp;gt;&amp;lt;/div&amp;gt;\n';&lt;br /&gt;
    } // https://jqueryui.com/accordion/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    var checkDlg = $(&lt;br /&gt;
        '&amp;lt;div id=&amp;quot;selfCheck&amp;quot; title=&amp;quot;Self Check dialog&amp;quot;&amp;gt;&amp;lt;p&amp;gt;&amp;lt;div id=&amp;quot;accordion&amp;quot;&amp;gt;' +&lt;br /&gt;
        sections + '&amp;lt;/div&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;/div&amp;gt;');&lt;br /&gt;
&lt;br /&gt;
    // run all API tests, invoke the callback to obtain the status&lt;br /&gt;
    Environment.runAPITests(Host, function (meta) {&lt;br /&gt;
&lt;br /&gt;
        //console.log('Running API test '+meta.name);&lt;br /&gt;
&lt;br /&gt;
        meta.test(function (result) {&lt;br /&gt;
            var status = (result) ? 'success' : 'fail';&lt;br /&gt;
            var test = $(&amp;quot;&amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&amp;quot;).text('Running API test ' +&lt;br /&gt;
                meta.name + ':' + status);&lt;br /&gt;
            $('#api_checks', checkDlg).append(test);&lt;br /&gt;
        }); // update tests results&lt;br /&gt;
&lt;br /&gt;
    }); // runAPITests&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
    [].forEach.call(CONFIG, function(profile) {&lt;br /&gt;
      alert(&amp;quot;profile is:&amp;quot;+profile);&lt;br /&gt;
    [].forEach.call(CONFIG[profile].tests, function(test) {&lt;br /&gt;
&lt;br /&gt;
      //UI.alert(test.url);&lt;br /&gt;
      Host.downloadPosting(test.url, function(downloaded) {&lt;br /&gt;
        alert(&amp;quot;downloaded:&amp;quot;);&lt;br /&gt;
        //if (test.title == downloaded.title) alert(&amp;quot;titles match:&amp;quot;+test.title);&lt;br /&gt;
      }); //downloadPosting&lt;br /&gt;
    }); //forEach test&lt;br /&gt;
    }); //forEach profile&lt;br /&gt;
    */&lt;br /&gt;
&lt;br /&gt;
    //$('#accordion',checkDlg).accordion();&lt;br /&gt;
    checkDlg.dialog({&lt;br /&gt;
        width: 700,&lt;br /&gt;
        height: 500,&lt;br /&gt;
        open: function () {&lt;br /&gt;
            // http://stackoverflow.com/questions/2929487/putting-a-jquery-ui-accordion-in-a-jquery-ui-dialog&lt;br /&gt;
            $('#accordion').accordion({&lt;br /&gt;
                autoHeight: true&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }); // show dialog&lt;br /&gt;
} // selfCheckDialog&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// show a simple configuration dialog (WIP)&lt;br /&gt;
function setupDialog() {&lt;br /&gt;
    //alert(&amp;quot;configuration dialog is not yet implemented&amp;quot;);&lt;br /&gt;
    var checked = (Host.get_persistent('debug_mode_enabled', false) === true) ?&lt;br /&gt;
        'checked' : '';&lt;br /&gt;
    //dbLog(&amp;quot;value is:&amp;quot;+get_persistent(&amp;quot;debug_mode_enabled&amp;quot;));&lt;br /&gt;
    //dbLog(&amp;quot;persistent debug flag is:&amp;quot;+checked);&lt;br /&gt;
    var setupDiv = $(&lt;br /&gt;
        '&amp;lt;div id=&amp;quot;setupDialog&amp;quot; title=&amp;quot;Setup dialog&amp;quot;&amp;gt;NOTE: this configuration dialog is still work-in-progress&amp;lt;/p&amp;gt;&amp;lt;label&amp;gt;&amp;lt;input id=&amp;quot;debugcb&amp;quot; type=&amp;quot;checkbox&amp;quot;' +&lt;br /&gt;
        checked +&lt;br /&gt;
        '&amp;gt;Enable Debug mode&amp;lt;/label&amp;gt;&amp;lt;p/&amp;gt;&amp;lt;div id=&amp;quot;progressbar&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;');&lt;br /&gt;
    setupDiv.click(function () {&lt;br /&gt;
        //alert(&amp;quot;changing persistent debug state&amp;quot;);&lt;br /&gt;
        Host.set_persistent('debug_mode_enabled', $('#debugcb').is(&lt;br /&gt;
            ':checked'));&lt;br /&gt;
    });&lt;br /&gt;
    //MediaWiki editing stub, based on: https://www.mediawiki.org/wiki/API:Edit#Editing_via_Ajax&lt;br /&gt;
    //only added here to show some status info in the setup dialog&lt;br /&gt;
    Host.download(&lt;br /&gt;
        'http://wiki.flightgear.org/api.php?action=query&amp;amp;prop=info|revisions&amp;amp;intoken=edit&amp;amp;rvprop=timestamp&amp;amp;titles=Main%20Page',&lt;br /&gt;
        function (response) {&lt;br /&gt;
            var message = 'FlightGear wiki login status (AJAX):';&lt;br /&gt;
            var status = response.statusText;&lt;br /&gt;
            var color = (status == 'OK') ? 'green' : 'red';&lt;br /&gt;
            Host.dbLog(message + status);&lt;br /&gt;
            var statusDiv = $('&amp;lt;p&amp;gt;' + message + status + '&amp;lt;/p&amp;gt;').css(&lt;br /&gt;
                'color', color);&lt;br /&gt;
            setupDiv.append(statusDiv);&lt;br /&gt;
        });&lt;br /&gt;
    setupDiv.dialog();&lt;br /&gt;
} // setupDialog&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// this  can be used to download/cache $FG_ROOT/options.xml so that fgfs CLI arguments can be recognized and post-processed automatically&lt;br /&gt;
// which can help transforming postings correctly&lt;br /&gt;
function downloadOptionsXML() {&lt;br /&gt;
&lt;br /&gt;
    // download $FG_ROOT/options.xml&lt;br /&gt;
    Host.download(&lt;br /&gt;
        &amp;quot;https://sourceforge.net/p/flightgear/fgdata/ci/next/tree/options.xml?format=raw&amp;quot;,&lt;br /&gt;
        function (response) {&lt;br /&gt;
            var xml = response.responseText;&lt;br /&gt;
            var doc = Host.make_doc(xml, 'text/xml');&lt;br /&gt;
            // https://developer.mozilla.org/en-US/docs/Web/API/XPathResult&lt;br /&gt;
            var options = Host.eval_xpath(doc, '//*/option', XPathResult.ORDERED_NODE_SNAPSHOT_TYPE);&lt;br /&gt;
&lt;br /&gt;
            // http://help.dottoro.com/ljgnejkp.php&lt;br /&gt;
            Host.dbLog(&amp;quot;Number of options found in options.xml:&amp;quot; + options.snapshotLength);&lt;br /&gt;
&lt;br /&gt;
            // http://help.dottoro.com/ljtfvvpx.php&lt;br /&gt;
&lt;br /&gt;
            // https://sourceforge.net/p/flightgear/fgdata/ci/next/tree/options.xml&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        }); // end of options.xml download&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
} // downloadOptionsXML&lt;br /&gt;
&lt;br /&gt;
function getProfile(url = undefined) {&lt;br /&gt;
&lt;br /&gt;
    if (url === undefined)&lt;br /&gt;
        url = window.location.href;&lt;br /&gt;
    else&lt;br /&gt;
        url = url;&lt;br /&gt;
&lt;br /&gt;
    Host.dbLog(&amp;quot;getProfile call URL is:&amp;quot; + url);&lt;br /&gt;
&lt;br /&gt;
    for (var profile in CONFIG) {&lt;br /&gt;
        if (url.match(CONFIG[profile].url_reg) !== null) {&lt;br /&gt;
            Host.dbLog('Matching website profile found');&lt;br /&gt;
            var invocations = Host.get_persistent(Host.getScriptVersion(), 0);&lt;br /&gt;
            Host.dbLog('Number of script invocations for version ' + Host.getScriptVersion() +&lt;br /&gt;
                ' is:' + invocations);&lt;br /&gt;
&lt;br /&gt;
            // determine if we want to show a config dialog&lt;br /&gt;
            if (invocations === 0) {&lt;br /&gt;
                Host.dbLog(&amp;quot;ask for config dialog to be shown&amp;quot;);&lt;br /&gt;
                var response = UI.confirm(&lt;br /&gt;
                    'This is your first time running version ' + Host.getScriptVersion() +&lt;br /&gt;
                    '\nConfigure now?');&lt;br /&gt;
                if (response) {&lt;br /&gt;
&lt;br /&gt;
                    // show configuration dialog (jQuery)&lt;br /&gt;
                    setupDialog();&lt;br /&gt;
                } else {} // don't configure&lt;br /&gt;
&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // increment number of invocations, use the script's version number as the key, to prevent the config dialog from showing up again (except for updated scripts)&lt;br /&gt;
            // FIXME: this is triggered/incremented by each click ...&lt;br /&gt;
            Host.dbLog(&amp;quot;increment number of script invocations&amp;quot;);&lt;br /&gt;
            Host.set_persistent(Host.getScriptVersion(), invocations + 1);&lt;br /&gt;
            return CONFIG[profile];&lt;br /&gt;
        } // matched website profile&lt;br /&gt;
        Host.dbLog('Could not find matching URL in getProfile() call!');&lt;br /&gt;
    } // for each profile&lt;br /&gt;
} // Get the HTML code that is selected&lt;br /&gt;
&lt;br /&gt;
function getSelectedHtml() {&lt;br /&gt;
    // From http://stackoverflow.com/a/6668159&lt;br /&gt;
    var html = '',&lt;br /&gt;
        selection = document.getSelection();&lt;br /&gt;
    if (selection.rangeCount) {&lt;br /&gt;
        var container = document.createElement('div');&lt;br /&gt;
        for (var i = 0; i &amp;lt; selection.rangeCount; i++) {&lt;br /&gt;
            container.appendChild(selection.getRangeAt(i).cloneContents());&lt;br /&gt;
        }&lt;br /&gt;
        html = container.innerHTML;&lt;br /&gt;
    }&lt;br /&gt;
    Host.dbLog('instantCquote(): Unprocessed HTML\n\'' + html + '\'');&lt;br /&gt;
    return html;&lt;br /&gt;
} // Gets the selected text&lt;br /&gt;
&lt;br /&gt;
function getSelectedText() {&lt;br /&gt;
    return document.getSelection().toString();&lt;br /&gt;
} // Get the ID of the post&lt;br /&gt;
// (this needs some work so that it can be used by the AJAX mode, without an actual selection)&lt;br /&gt;
&lt;br /&gt;
function getPostId(selection, profile, focus) {&lt;br /&gt;
    if (focus !== undefined) {&lt;br /&gt;
        Host.dbLog(&amp;quot;Trying to get PostId with defined focus&amp;quot;);&lt;br /&gt;
        selection = selection.focusNode.parentNode;&lt;br /&gt;
    } else {&lt;br /&gt;
        Host.dbLog(&amp;quot;Trying to get PostId with undefined focus&amp;quot;);&lt;br /&gt;
        selection = selection.anchorNode.parentNode;&lt;br /&gt;
    }&lt;br /&gt;
    while (selection.id.match(profile.content.idStyle) === null) {&lt;br /&gt;
        selection = selection.parentNode;&lt;br /&gt;
    }&lt;br /&gt;
    Host.dbLog(&amp;quot;Selection id is:&amp;quot; + selection.id);&lt;br /&gt;
    return selection.id;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Checks that the selection is valid&lt;br /&gt;
function checkValid(selection, profile) {&lt;br /&gt;
    var ret = true,&lt;br /&gt;
        selection_cp = {},&lt;br /&gt;
        tags = profile.content.parentTag;&lt;br /&gt;
    for (var n = 0; n &amp;lt; 2; n++) {&lt;br /&gt;
        if (n === 0) {&lt;br /&gt;
            selection_cp = selection.anchorNode.parentNode;&lt;br /&gt;
        } else {&lt;br /&gt;
            selection_cp = selection.focusNode.parentNode;&lt;br /&gt;
        }&lt;br /&gt;
        while (true) {&lt;br /&gt;
            if (selection_cp.tagName === 'BODY') {&lt;br /&gt;
                ret = false;&lt;br /&gt;
                break;&lt;br /&gt;
            } else {&lt;br /&gt;
                var cont = false;&lt;br /&gt;
                for (var i = 0; i &amp;lt; tags.length; i++) {&lt;br /&gt;
                    if (selection_cp[tags[0]] === tags[i]) {&lt;br /&gt;
                        cont = true;&lt;br /&gt;
                        break;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                if (cont) {&lt;br /&gt;
                    break;&lt;br /&gt;
                } else {&lt;br /&gt;
                    selection_cp = selection_cp.parentNode;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    ret = ret &amp;amp;&amp;amp; (getPostId(selection, profile) === getPostId(selection,&lt;br /&gt;
        profile, 1));&lt;br /&gt;
    return ret;&lt;br /&gt;
} // Extracts the raw text from a certain place, using an XPath&lt;br /&gt;
&lt;br /&gt;
function extractFieldInfo(profile, id, field) {&lt;br /&gt;
&lt;br /&gt;
    if (field === 'content') {&lt;br /&gt;
        Host.dbLog(&amp;quot;Returning content (selection)&amp;quot;);&lt;br /&gt;
        return profile[field].selection();&lt;br /&gt;
    } else {&lt;br /&gt;
        Host.dbLog(&amp;quot;Extracting field via xpath:&amp;quot; + field);&lt;br /&gt;
        var xpath = '//*[@id=&amp;quot;' + id + '&amp;quot;]/' + profile[field].xpath;&lt;br /&gt;
        return Host.eval_xpath(document, xpath).stringValue; // document.evaluate(xpath, document, null, XPathResult.STRING_TYPE, null).stringValue;&lt;br /&gt;
    }&lt;br /&gt;
} // Change the text using specified transformations&lt;br /&gt;
&lt;br /&gt;
function applyTransformations(fieldInfo, trans) {&lt;br /&gt;
    for (var i = 0; i &amp;lt; trans.length; i++) {&lt;br /&gt;
        fieldInfo = trans[i](fieldInfo);&lt;br /&gt;
        Host.dbLog(&lt;br /&gt;
            'applyTransformations(): Multiple transformation, transformation after loop #' +&lt;br /&gt;
            (i + 1) + ':\n\'' + fieldInfo + '\'');&lt;br /&gt;
    }&lt;br /&gt;
    return fieldInfo;&lt;br /&gt;
&lt;br /&gt;
} //applyTransformations&lt;br /&gt;
&lt;br /&gt;
// Formats the quote&lt;br /&gt;
&lt;br /&gt;
function createCquote(data, indirect_speech = false) {&lt;br /&gt;
    if (!indirect_speech)&lt;br /&gt;
        return nonQuotedRef(data); // conventional/verbatim selection&lt;br /&gt;
    else {&lt;br /&gt;
        // pattern match the content using a vector of regexes&lt;br /&gt;
        data.content = transformSpeech(data.content, data.author, null,&lt;br /&gt;
            speechTransformations);&lt;br /&gt;
        return nonQuotedRef(data);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function nonQuotedRef(data) { //TODO: rename&lt;br /&gt;
    var template = Host.getTemplate();&lt;br /&gt;
&lt;br /&gt;
    var substituted = template&lt;br /&gt;
        .replace('$CONTENT', data.content)&lt;br /&gt;
        .replace('$URL', data.url)&lt;br /&gt;
        .replace('$TITLE', data.title)&lt;br /&gt;
        .replace('$AUTHOR', data.author)&lt;br /&gt;
        .replace('$DATE', datef(data.date))&lt;br /&gt;
        .replace('$ADDED', datef(data.date))&lt;br /&gt;
        .replace('$SCRIPT_VERSION', Host.getScriptVersion());&lt;br /&gt;
&lt;br /&gt;
    return substituted;&lt;br /&gt;
} // &lt;br /&gt;
&lt;br /&gt;
// Output the text.&lt;br /&gt;
// Tries the jQuery dialog, and falls back to window.prompt()&lt;br /&gt;
&lt;br /&gt;
function outputText(msg, original) {&lt;br /&gt;
    try {&lt;br /&gt;
        OUTPUT.jQueryTabbed(msg, original);&lt;br /&gt;
    } catch (err) {&lt;br /&gt;
        msg = msg.replace(/&amp;amp;lt;\/syntaxhighligh(.)&amp;gt;/g, '&amp;lt;/syntaxhighligh$1');&lt;br /&gt;
        OUTPUT.msgbox(msg);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// #############&lt;br /&gt;
// # Utilities #&lt;br /&gt;
// #############&lt;br /&gt;
&lt;br /&gt;
function extract(regex) {&lt;br /&gt;
    return function (text) {&lt;br /&gt;
        return text.match(regex)[1];&lt;br /&gt;
    };&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function prepend(prefix) {&lt;br /&gt;
    return function (text) {&lt;br /&gt;
        return prefix + text;&lt;br /&gt;
    };&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function removeComments(html) {&lt;br /&gt;
    return html.replace(/&amp;lt;!--.*?--&amp;gt;/g, '');&lt;br /&gt;
} // Not currently used (as of June 2015), but kept just in case&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// currently unused&lt;br /&gt;
function escapePipes(html) {&lt;br /&gt;
    html = html.replace(/\|\|/g, '{{!!}n}');&lt;br /&gt;
    html = html.replace(/\|\-/g, '{{!-}}');&lt;br /&gt;
    return html.replace(/\|/g, '{{!}}');&lt;br /&gt;
} // Converts HTML &amp;lt;a href=&amp;quot;...&amp;quot;&amp;gt;...&amp;lt;/a&amp;gt; tags to wiki links, internal if possible.&lt;br /&gt;
&lt;br /&gt;
function a2wikilink(html) {&lt;br /&gt;
    // Links to wiki images, because&lt;br /&gt;
    // they need special treatment, or else they get displayed.&lt;br /&gt;
    html = html.replace(&lt;br /&gt;
        /&amp;lt;a.*?href=&amp;quot;http:\/\/wiki\.flightgear\.org\/File:(.*?)&amp;quot;.*?&amp;gt;(.*?)&amp;lt;\/a&amp;gt;/g,&lt;br /&gt;
        '[[Media:$1|$2]]');&lt;br /&gt;
    // Wiki links without custom text.&lt;br /&gt;
    html = html.replace(&lt;br /&gt;
        /&amp;lt;a.*?href=&amp;quot;http:\/\/wiki\.flightgear\.org\/(.*?)&amp;quot;.*?&amp;gt;http:\/\/wiki\.flightgear\.org\/.*?&amp;lt;\/a&amp;gt;/g,&lt;br /&gt;
        '[[$1]]');&lt;br /&gt;
    // Links to the wiki with custom text&lt;br /&gt;
    html = html.replace(&lt;br /&gt;
        /&amp;lt;a.*?href=&amp;quot;http:\/\/wiki\.flightgear\.org\/(.*?)&amp;quot;.*?&amp;gt;(.*?)&amp;lt;\/a&amp;gt;/g,&lt;br /&gt;
        '[[$1|$2]]');&lt;br /&gt;
    // Remove underscores from all wiki links&lt;br /&gt;
    var list = html.match(/\[\[.*?\]\]/g);&lt;br /&gt;
    if (list !== null) {&lt;br /&gt;
        for (var i = 0; i &amp;lt; list.length; i++) {&lt;br /&gt;
            html = html.replace(list[i], underscore2Space(list[i]));&lt;br /&gt;
        }&lt;br /&gt;
    } // Convert non-wiki links&lt;br /&gt;
    // TODO: identify forum/devel list links, and use the AJAX/Host.download helper to get a title/subject for unnamed links (using the existing xpath/regex helpers for that)&lt;br /&gt;
&lt;br /&gt;
    html = html.replace(/&amp;lt;a.*?href=&amp;quot;(.*?)&amp;quot;.*?&amp;gt;(.*?)&amp;lt;\/a&amp;gt;/g, '[$1 $2]');&lt;br /&gt;
    // Remove triple dots from external links.&lt;br /&gt;
    // Replace with raw URL (MediaWiki converts it to a link).&lt;br /&gt;
    list = html.match(/\[.*?(\.\.\.).*?\]/g);&lt;br /&gt;
    if (list !== null) {&lt;br /&gt;
        for (var i = 0; i &amp;lt; list.length; i++) {&lt;br /&gt;
            html = html.replace(list[i], list[i].match(/\[(.*?) .*?\]/)[1]);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return html;&lt;br /&gt;
} // Converts images, including images in &amp;lt;a&amp;gt; links&lt;br /&gt;
&lt;br /&gt;
function img2link(html) {&lt;br /&gt;
    html = html.replace(&lt;br /&gt;
        /&amp;lt;a[^&amp;lt;]*?href=&amp;quot;([^&amp;lt;]*?)&amp;quot;[^&amp;lt;]*?&amp;gt;&amp;lt;img.*?src=&amp;quot;http:\/\/wiki\.flightgear\.org\/images\/.*?\/.*?\/(.*?)&amp;quot;.*?&amp;gt;&amp;lt;\/a&amp;gt;/g,&lt;br /&gt;
        '[[File:$2|250px|link=$1]]');&lt;br /&gt;
    html = html.replace(&lt;br /&gt;
        /&amp;lt;img.*?src=&amp;quot;http:\/\/wiki\.flightgear\.org\/images\/.*?\/.*?\/(.*?)&amp;quot;.*?&amp;gt;/g,&lt;br /&gt;
        '[[File:$1|250px]]');&lt;br /&gt;
    html = html.replace(&lt;br /&gt;
        /&amp;lt;a[^&amp;lt;]*?href=&amp;quot;([^&amp;lt;]*?)&amp;quot;[^&amp;lt;]*?&amp;gt;&amp;lt;img.*?src=&amp;quot;(.*?)&amp;quot;.*?&amp;gt;&amp;lt;\/a&amp;gt;/g,&lt;br /&gt;
        '(see [$2 image], links to [$1 here])');&lt;br /&gt;
    return html.replace(/&amp;lt;img.*?src=&amp;quot;(.*?)&amp;quot;.*?&amp;gt;/g,&lt;br /&gt;
        '(see the [$1 linked image])');&lt;br /&gt;
} // Converts smilies&lt;br /&gt;
&lt;br /&gt;
function forum_smilies2text(html) {&lt;br /&gt;
    html = html.replace(&lt;br /&gt;
        /&amp;lt;img src=&amp;quot;\.\/images\/smilies\/icon_.*?\.gif&amp;quot; alt=&amp;quot;(.*?)&amp;quot;.*?&amp;gt;/g,&lt;br /&gt;
        '$1');&lt;br /&gt;
    for (var i = 0; i &amp;lt; EMOTICONS.length; i++) {&lt;br /&gt;
        html = html.replace(EMOTICONS[i][0], EMOTICONS[i][1]);&lt;br /&gt;
    }&lt;br /&gt;
    return html;&lt;br /&gt;
} // Converts font formatting&lt;br /&gt;
&lt;br /&gt;
function forum_fontstyle2wikistyle(html) {&lt;br /&gt;
    html = html.replace(/&amp;lt;span style=&amp;quot;font-weight: bold&amp;quot;&amp;gt;(.*?)&amp;lt;\/span&amp;gt;/g,&lt;br /&gt;
        '\'\'\'$1\'\'\'');&lt;br /&gt;
    html = html.replace(&lt;br /&gt;
        /&amp;lt;span style=&amp;quot;text-decoration: underline&amp;quot;&amp;gt;(.*?)&amp;lt;\/span&amp;gt;/g,&lt;br /&gt;
        '&amp;lt;u&amp;gt;$1&amp;lt;/u&amp;gt;');&lt;br /&gt;
    html = html.replace(/&amp;lt;span style=&amp;quot;font-style: italic&amp;quot;&amp;gt;(.*?)&amp;lt;\/span&amp;gt;/g,&lt;br /&gt;
        '\'\'$1\'\'');&lt;br /&gt;
    return html.replace(/&amp;lt;span class=&amp;quot;posthilit&amp;quot;&amp;gt;(.*?)&amp;lt;\/span&amp;gt;/g, '$1');&lt;br /&gt;
} // Converts code blocks&lt;br /&gt;
&lt;br /&gt;
function forum_code2syntaxhighlight(html) {&lt;br /&gt;
    var list = html.match(&lt;br /&gt;
            /&amp;lt;dl class=&amp;quot;codebox&amp;quot;&amp;gt;.*?&amp;lt;code&amp;gt;(.*?)&amp;lt;\/code&amp;gt;.*?&amp;lt;\/dl&amp;gt;/g),&lt;br /&gt;
        data = [];&lt;br /&gt;
    if (list === null) return html;&lt;br /&gt;
    for (var n = 0; n &amp;lt; list.length; n++) {&lt;br /&gt;
        data = html.match(/&amp;lt;dl class=&amp;quot;codebox&amp;quot;&amp;gt;.*?&amp;lt;code&amp;gt;(.*?)&amp;lt;\/code&amp;gt;.*?&amp;lt;\/dl&amp;gt;/);&lt;br /&gt;
        html = html.replace(data[0], processCode(data));&lt;br /&gt;
    }&lt;br /&gt;
    return html;&lt;br /&gt;
} // Strips any whitespace from the beginning and end of a string&lt;br /&gt;
&lt;br /&gt;
function stripWhitespace(html) {&lt;br /&gt;
    html = html.replace(/^\s*?(\S)/, '$1');&lt;br /&gt;
    return html.replace(/(\S)\s*?\z/, '$1');&lt;br /&gt;
} // Process code, including basic detection of language&lt;br /&gt;
&lt;br /&gt;
function processCode(data) {&lt;br /&gt;
    var lang = '',&lt;br /&gt;
        code = data[1];&lt;br /&gt;
    code = code.replace(/&amp;amp;nbsp;/g, ' ');&lt;br /&gt;
    if (code.match(/=?.*?\(?.*?\)?;/) !== null) lang = 'nasal';&lt;br /&gt;
    if (code.match(/&amp;amp;lt;.*?&amp;amp;gt;.*?&amp;amp;lt;\/.*?&amp;amp;gt;/) !== null || code.match(&lt;br /&gt;
            /&amp;amp;lt;!--.*?--&amp;amp;gt;/) !== null) lang = 'xml';&lt;br /&gt;
    code = code.replace(/&amp;lt;br\/?&amp;gt;/g, '\n');&lt;br /&gt;
    return '&amp;lt;syntaxhighlight lang=&amp;quot;' + lang + '&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;\n' + code +&lt;br /&gt;
        '\n&amp;amp;lt;/syntaxhighlight&amp;gt;';&lt;br /&gt;
} // Converts quote blocks to Cquotes&lt;br /&gt;
&lt;br /&gt;
function forum_quote2cquote(html) {&lt;br /&gt;
    html = html.replace(&lt;br /&gt;
        /&amp;lt;blockquote class=&amp;quot;uncited&amp;quot;&amp;gt;&amp;lt;div&amp;gt;(.*?)&amp;lt;\/div&amp;gt;&amp;lt;\/blockquote&amp;gt;/g,&lt;br /&gt;
        '{{cquote|$1}}');&lt;br /&gt;
    if (html.match(/&amp;lt;blockquote&amp;gt;/g) === null) return html;&lt;br /&gt;
    var numQuotes = html.match(/&amp;lt;blockquote&amp;gt;/g).length;&lt;br /&gt;
    for (var n = 0; n &amp;lt; numQuotes; n++) {&lt;br /&gt;
        html = html.replace(&lt;br /&gt;
            /&amp;lt;blockquote&amp;gt;&amp;lt;div&amp;gt;&amp;lt;cite&amp;gt;(.*?) wrote.*?:&amp;lt;\/cite&amp;gt;(.*?)&amp;lt;\/div&amp;gt;&amp;lt;\/blockquote&amp;gt;/,&lt;br /&gt;
            '{{cquote|$2|$1}}');&lt;br /&gt;
    }&lt;br /&gt;
    return html;&lt;br /&gt;
} // Converts videos to wiki style&lt;br /&gt;
&lt;br /&gt;
function vid2wiki(html) {&lt;br /&gt;
    // YouTube&lt;br /&gt;
    html = html.replace(&lt;br /&gt;
        /&amp;lt;div class=&amp;quot;video-wrapper&amp;quot;&amp;gt;\s.*?&amp;lt;div class=&amp;quot;video-container&amp;quot;&amp;gt;\s*?&amp;lt;iframe class=&amp;quot;youtube-player&amp;quot;.*?width=&amp;quot;(.*?)&amp;quot; height=&amp;quot;(.*?)&amp;quot; src=&amp;quot;http:\/\/www\.youtube\.com\/embed\/(.*?)&amp;quot;.*?&amp;gt;&amp;lt;\/iframe&amp;gt;\s*?&amp;lt;\/div&amp;gt;\s*?&amp;lt;\/div&amp;gt;/g,&lt;br /&gt;
        '{{#ev:youtube|$3|$1x$2}}');&lt;br /&gt;
    // Vimeo&lt;br /&gt;
    html = html.replace(&lt;br /&gt;
        /&amp;lt;iframe src=&amp;quot;http:\/\/player\.vimeo\.com\/video\/(.*?)\?.*?&amp;quot; width=&amp;quot;(.*?)&amp;quot; height=&amp;quot;(.*?)&amp;quot;.*?&amp;gt;.*?&amp;lt;\/iframe&amp;gt;/g,&lt;br /&gt;
        '{{#ev:vimeo|$1|$2x$3}}');&lt;br /&gt;
    return html.replace(/\[.*? Watch on Vimeo\]/g, '');&lt;br /&gt;
} // Not currently used (as of June 2015), but kept just in case&lt;br /&gt;
&lt;br /&gt;
// currently unused&lt;br /&gt;
function escapeEquals(html) {&lt;br /&gt;
    return html.replace(/=/g, '{{=}}');&lt;br /&gt;
} // &amp;lt;br&amp;gt; to newline.&lt;br /&gt;
&lt;br /&gt;
function forum_br2newline(html) {&lt;br /&gt;
    html = html.replace(/&amp;lt;br\/?&amp;gt;&amp;lt;br\/?&amp;gt;/g, '\n');&lt;br /&gt;
    return html.replace(/&amp;lt;br\/?&amp;gt;/g, '\n\n');&lt;br /&gt;
} // Forum list to wiki style&lt;br /&gt;
&lt;br /&gt;
function list2wiki(html) {&lt;br /&gt;
    var list = html.match(/&amp;lt;ul&amp;gt;(.*?)&amp;lt;\/ul&amp;gt;/g);&lt;br /&gt;
    if (list !== null) {&lt;br /&gt;
        for (var i = 0; i &amp;lt; list.length; i++) {&lt;br /&gt;
            html = html.replace(/&amp;lt;li&amp;gt;(.*?)&amp;lt;\/li&amp;gt;/g, '* $1\n');&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    list = html.match(/&amp;lt;ol.*?&amp;gt;(.*?)&amp;lt;\/ol&amp;gt;/g);&lt;br /&gt;
    if (list !== null) {&lt;br /&gt;
        for (var i = 0; i &amp;lt; list.length; i++) {&lt;br /&gt;
            html = html.replace(/&amp;lt;li&amp;gt;(.*?)&amp;lt;\/li&amp;gt;/g, '# $1\n');&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    html = html.replace(/&amp;lt;\/?[uo]l&amp;gt;/g, '');&lt;br /&gt;
    return html;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function nowiki(text) {&lt;br /&gt;
    return '&amp;lt;nowiki&amp;gt;' + text + '&amp;lt;/nowiki&amp;gt;';&lt;br /&gt;
} // Returns the correct ordinal adjective&lt;br /&gt;
&lt;br /&gt;
function ordAdj(date) {&lt;br /&gt;
    date = date.toString();&lt;br /&gt;
    if (date == '11' || date == '12' || date == '13') {&lt;br /&gt;
        return 'th';&lt;br /&gt;
    } else if (date.substr(1) == '1' || date == '1') {&lt;br /&gt;
        return 'st';&lt;br /&gt;
    } else if (date.substr(1) == '2' || date == '2') {&lt;br /&gt;
        return 'nd';&lt;br /&gt;
    } else if (date.substr(1) == '3' || date == '3') {&lt;br /&gt;
        return 'rd';&lt;br /&gt;
    } else {&lt;br /&gt;
        return 'th';&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Formats the date to this format: Apr 26th, 2015&lt;br /&gt;
function datef(text) {&lt;br /&gt;
    var date = new Date(text);&lt;br /&gt;
    return MONTHS[date.getMonth()] + ' ' + date.getDate() + ordAdj(date.getDate()) +&lt;br /&gt;
        ', ' + date.getFullYear();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function underscore2Space(str) {&lt;br /&gt;
    return str.replace(/_/g, ' ');&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// IGNORE EVERYTHING THAT FOLLOWS: &lt;br /&gt;
// This is an experiment to use GA/GP (genetic programming) to help procedurally evolve xpath and regex expressions if/when the underlying websites change&lt;br /&gt;
// so that we don't have to manually update/edit the script accordingly (this would also work for mobile themes etc)&lt;br /&gt;
// For now, this is heavily based on the genetic.js framework/examples: http://subprotocol.com/system/genetic-hello-world.html&lt;br /&gt;
// The idea is to evolve the xpath/regex expression by evaluating its return value against the expected/desired value&lt;br /&gt;
// the most important thing here is having a suitable fitness function&lt;br /&gt;
// &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function evolve_expression_test() {&lt;br /&gt;
&lt;br /&gt;
    try {&lt;br /&gt;
        var genetic = Genetic.create();&lt;br /&gt;
&lt;br /&gt;
        // TODO: use minimizer: redundant_bytes + duration_msec + xpath.length&lt;br /&gt;
        genetic.optimize = Genetic.Optimize.Maximize;&lt;br /&gt;
        genetic.select1 = Genetic.Select1.Tournament2;&lt;br /&gt;
        genetic.select2 = Genetic.Select2.Tournament2;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        genetic.seed = function () {&lt;br /&gt;
&lt;br /&gt;
            function randomString(len) {&lt;br /&gt;
                var text = &amp;quot;&amp;quot;;&lt;br /&gt;
                var charset =&lt;br /&gt;
                    &amp;quot;\\abcdefghijklmnopqrstuvwxyz0123456789[] ()&amp;lt;&amp;gt;*.,&amp;quot;;&lt;br /&gt;
                for (var i = 0; i &amp;lt; len; i++)&lt;br /&gt;
                    text += charset.charAt(Math.floor(Math.random() *&lt;br /&gt;
                        charset.length));&lt;br /&gt;
&lt;br /&gt;
                return text;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // create random strings that are equal in length to solution&lt;br /&gt;
            return randomString(this.userData[&amp;quot;solution&amp;quot;].length);&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        genetic.mutate = function (entity) {&lt;br /&gt;
&lt;br /&gt;
            function replaceAt(str, index, character) {&lt;br /&gt;
                return str.substr(0, index) + character + str.substr(index +&lt;br /&gt;
                    character.length);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // chromosomal drift&lt;br /&gt;
            var i = Math.floor(Math.random() * entity.length);&lt;br /&gt;
            return replaceAt(entity, i, String.fromCharCode(entity.charCodeAt(&lt;br /&gt;
                i) + (Math.floor(Math.random() * 2) ? 1 : -1)));&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
        genetic.crossover = function (mother, father) {&lt;br /&gt;
&lt;br /&gt;
            // two-point crossover&lt;br /&gt;
            var len = mother.length;&lt;br /&gt;
            var ca = Math.floor(Math.random() * len);&lt;br /&gt;
            var cb = Math.floor(Math.random() * len);&lt;br /&gt;
            if (ca &amp;gt; cb) {&lt;br /&gt;
                var tmp = cb;&lt;br /&gt;
                cb = ca;&lt;br /&gt;
                ca = tmp;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            var son = father.substr(0, ca) + mother.substr(ca, cb - ca) +&lt;br /&gt;
                father.substr(cb);&lt;br /&gt;
            var daughter = mother.substr(0, ca) + father.substr(ca, cb - ca) +&lt;br /&gt;
                mother.substr(cb);&lt;br /&gt;
&lt;br /&gt;
            return [son, daughter];&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
        genetic.determineExcessBytes = function (text, needle) {&lt;br /&gt;
            return text.length - needle.length;&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
        genetic.containsText = function (text, needle) {&lt;br /&gt;
            return text.search(needle);&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
        genetic.isValid = function (exp) {&lt;br /&gt;
&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
        /* myFitness:&lt;br /&gt;
         * - must be a valid xpath/regex expression (try/call)&lt;br /&gt;
         * - must containsText the needle&lt;br /&gt;
         * - low relative offset in text (begin/end)&lt;br /&gt;
         * - excessBytes&lt;br /&gt;
         * - short expression  (expression length)&lt;br /&gt;
         * - expression footprint (runtime)&lt;br /&gt;
         */&lt;br /&gt;
&lt;br /&gt;
        // TODO: the fitness function should validate each xpath/regex first&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        genetic.fitness = function (entity) {&lt;br /&gt;
            var fitness = 0;&lt;br /&gt;
            var result;&lt;br /&gt;
            var validExp = 0.1;&lt;br /&gt;
            var hasToken = 0.1;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            var t = this.userData.tests[0].haystack;&lt;br /&gt;
            //var regex = new RegExp(this.userData.solution);&lt;br /&gt;
            //var output = t.match( new RegExp(&amp;quot;From: (.*) &amp;lt;.*@.*&amp;gt;&amp;quot;))[1];  &lt;br /&gt;
            // TODO: use search &amp;amp; match for improving the fitness&lt;br /&gt;
&lt;br /&gt;
            if (0)&lt;br /&gt;
                try {&lt;br /&gt;
                    var regex = new RegExp(entity);&lt;br /&gt;
                    var output = t.search(regex);&lt;br /&gt;
                    validExp = 10;&lt;br /&gt;
                }&lt;br /&gt;
            catch (e) {&lt;br /&gt;
                validExp = 2;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            var i;&lt;br /&gt;
            for (i = 0; i &amp;lt; entity.length; ++i) {&lt;br /&gt;
                // increase fitness for each character that matches&lt;br /&gt;
                if (entity[i] == this.userData[&amp;quot;solution&amp;quot;][i])&lt;br /&gt;
                    fitness += 1;&lt;br /&gt;
&lt;br /&gt;
                // award fractions of a point as we get warmer&lt;br /&gt;
                fitness += (127 - Math.abs(entity.charCodeAt(i) - this.userData[&lt;br /&gt;
                    &amp;quot;solution&amp;quot;].charCodeAt(i))) / 50;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            return fitness; // + (1*validExp + 1* hasToken);&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
        genetic.generation = function (pop, generation, stats) {&lt;br /&gt;
            // stop running once we've reached the solution&lt;br /&gt;
            return pop[0].entity != this.userData[&amp;quot;solution&amp;quot;];&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
        genetic.notification = function (pop, generation, stats, isFinished) {&lt;br /&gt;
&lt;br /&gt;
            function lerp(a, b, p) {&lt;br /&gt;
                return a + (b - a) * p;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            var value = pop[0].entity;&lt;br /&gt;
            this.last = this.last || value;&lt;br /&gt;
&lt;br /&gt;
            if (pop != 0 &amp;amp;&amp;amp; value == this.last)&lt;br /&gt;
                return;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            var solution = [];&lt;br /&gt;
            var i;&lt;br /&gt;
            for (i = 0; i &amp;lt; value.length; ++i) {&lt;br /&gt;
                var diff = value.charCodeAt(i) - this.last.charCodeAt(i);&lt;br /&gt;
                var style = &amp;quot;background: transparent;&amp;quot;;&lt;br /&gt;
                if (diff &amp;gt; 0) {&lt;br /&gt;
                    style = &amp;quot;background: rgb(0,200,50); color: #fff;&amp;quot;;&lt;br /&gt;
                } else if (diff &amp;lt; 0) {&lt;br /&gt;
                    style = &amp;quot;background: rgb(0,100,50); color: #fff;&amp;quot;;&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                solution.push(&amp;quot;&amp;lt;span style=\&amp;quot;&amp;quot; + style + &amp;quot;\&amp;quot;&amp;gt;&amp;quot; + value[i] +&lt;br /&gt;
                    &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            var t = this.userData.tests[0].haystack;&lt;br /&gt;
            //console.log(&amp;quot;haystack is:&amp;quot;+t);&lt;br /&gt;
            // &amp;quot;From: John Doe &amp;lt;John@do...&amp;gt; - 2020-07-02 17:36:03&amp;quot;, needle: &amp;quot;John Doe&amp;quot;}, /From: (.*) &amp;lt;.*@.*&amp;gt;/&lt;br /&gt;
            var regex = new RegExp(this.userData.solution);&lt;br /&gt;
            //var output = t.match( new RegExp(&amp;quot;From: (.*) &amp;lt;.*@.*&amp;gt;&amp;quot;))[1];  &lt;br /&gt;
            // TODO: use search &amp;amp; match for improving the fitness&lt;br /&gt;
            var output = t.search(new RegExp(value));&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
            var buf = &amp;quot;&amp;quot;;&lt;br /&gt;
            buf += &amp;quot;&amp;lt;tr&amp;gt;&amp;quot;;&lt;br /&gt;
            buf += &amp;quot;&amp;lt;td&amp;gt;&amp;quot; + generation + &amp;quot;&amp;lt;/td&amp;gt;&amp;quot;;&lt;br /&gt;
            buf += &amp;quot;&amp;lt;td&amp;gt;&amp;quot; + pop[0].fitness.toPrecision(5) + &amp;quot;&amp;lt;/td&amp;gt;&amp;quot;;&lt;br /&gt;
            buf += &amp;quot;&amp;lt;td&amp;gt;&amp;quot; + solution.join(&amp;quot;&amp;quot;) + &amp;quot;&amp;lt;/td&amp;gt;&amp;quot;;&lt;br /&gt;
            buf += &amp;quot;&amp;lt;td&amp;gt;&amp;quot; + output + &amp;quot;&amp;lt;/td&amp;gt;&amp;quot;;&lt;br /&gt;
            buf += &amp;quot;&amp;lt;/tr&amp;gt;&amp;quot;;&lt;br /&gt;
            $(&amp;quot;#results tbody&amp;quot;).prepend(buf);&lt;br /&gt;
&lt;br /&gt;
            this.last = value;&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        /*&lt;br /&gt;
genetic.notification2 = function(pop, generation, stats, isFinished) {&lt;br /&gt;
&lt;br /&gt;
    function lerp(a, b, p) {&lt;br /&gt;
        return a + (b-a)*p;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    var value = pop[0].entity;&lt;br /&gt;
    this.last = this.last||value;&lt;br /&gt;
    &lt;br /&gt;
    if (pop != 0 &amp;amp;&amp;amp; value == this.last)&lt;br /&gt;
        return;&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    var solution = [];&lt;br /&gt;
    var i;&lt;br /&gt;
    for (i=0;i&amp;lt;value.length;++i) {&lt;br /&gt;
    &lt;br /&gt;
    solution.push(value[i]);&lt;br /&gt;
 } &lt;br /&gt;
    console.log(&amp;quot;Generation:&amp;quot;+ generation + &amp;quot; Fitness:&amp;quot; + pop[0].fitness.toPrecision(5) + &amp;quot; Solution:&amp;quot; + solution.join(&amp;quot;&amp;quot;));&lt;br /&gt;
  &lt;br /&gt;
    this.last = value;&lt;br /&gt;
};&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        var config = {&lt;br /&gt;
            &amp;quot;iterations&amp;quot;: 4000,&lt;br /&gt;
            &amp;quot;size&amp;quot;: 250,&lt;br /&gt;
            &amp;quot;crossover&amp;quot;: 0.3,&lt;br /&gt;
            &amp;quot;mutation&amp;quot;: 0.4,&lt;br /&gt;
            &amp;quot;skip&amp;quot;: 30 // notifications&lt;br /&gt;
                //, &amp;quot;webWorkers&amp;quot;: false&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        /*&lt;br /&gt;
        var profile = CONFIG['Sourceforge Mailing list'];&lt;br /&gt;
        var posting = profile.tests[0];&lt;br /&gt;
        var author_xpath = profile.title.xpath;&lt;br /&gt;
        */&lt;br /&gt;
&lt;br /&gt;
        var regexTests = [{&lt;br /&gt;
            haystack: &amp;quot;From: John Doe &amp;lt;John@do...&amp;gt; - 2020-07-02 17:36:03&amp;quot;,&lt;br /&gt;
            needle: &amp;quot;John Doe&amp;quot;&lt;br /&gt;
        }, {&lt;br /&gt;
            haystack: &amp;quot;From: Marc Twain &amp;lt;Marc@ta...&amp;gt; - 2010-01-03 07:36:03&amp;quot;,&lt;br /&gt;
            needle: &amp;quot;Marc Twain&amp;quot;&lt;br /&gt;
        }, {&lt;br /&gt;
            haystack: &amp;quot;From: George W. Bush &amp;lt;GWB@wh...&amp;gt; - 2055-11-11 17:33:13&amp;quot;,&lt;br /&gt;
            needle: &amp;quot;George W. Bush&amp;quot;&lt;br /&gt;
        }];&lt;br /&gt;
&lt;br /&gt;
        // the regex we want to evolve&lt;br /&gt;
        var solution = &amp;quot;From: (.*) &amp;lt;.*@.*&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        // let's assume, we'd like to evolve a regex expression like this one&lt;br /&gt;
        var userData = {&lt;br /&gt;
            solution: solution,&lt;br /&gt;
            tests: regexTests&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
        genetic.evolve(config, userData);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        //console.log(&amp;quot;genetic.js is loaded and working, but disabled for now&amp;quot;);    &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    } // try&lt;br /&gt;
    catch (e) {&lt;br /&gt;
        console.log(&amp;quot;genetic.js error:\n&amp;quot; + e.message);&lt;br /&gt;
    } // catch&lt;br /&gt;
&lt;br /&gt;
} // evolveExpression_test()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if (0) //TODO: expose via development tab&lt;br /&gt;
    try {&lt;br /&gt;
    // https://github.com/cazala/synaptic&lt;br /&gt;
    var Neuron = synaptic.Neuron,&lt;br /&gt;
        Layer = synaptic.Layer,&lt;br /&gt;
        Network = synaptic.Network,&lt;br /&gt;
        Trainer = synaptic.Trainer,&lt;br /&gt;
        Architect = synaptic.Architect;&lt;br /&gt;
&lt;br /&gt;
    function Perceptron(input, hidden, output) {&lt;br /&gt;
        // create the layers&lt;br /&gt;
        var inputLayer = new Layer(input);&lt;br /&gt;
        var hiddenLayer = new Layer(hidden);&lt;br /&gt;
        var outputLayer = new Layer(output);&lt;br /&gt;
&lt;br /&gt;
        // connect the layers&lt;br /&gt;
        inputLayer.project(hiddenLayer);&lt;br /&gt;
        hiddenLayer.project(outputLayer);&lt;br /&gt;
&lt;br /&gt;
        // set the layers&lt;br /&gt;
        this.set({&lt;br /&gt;
            input: inputLayer,&lt;br /&gt;
            hidden: [hiddenLayer],&lt;br /&gt;
            output: outputLayer&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // extend the prototype chain&lt;br /&gt;
    Perceptron.prototype = new Network();&lt;br /&gt;
    Perceptron.prototype.constructor = Perceptron;&lt;br /&gt;
&lt;br /&gt;
    var myPerceptron = new Perceptron(2, 3, 1);&lt;br /&gt;
    var myTrainer = new Trainer(myPerceptron);&lt;br /&gt;
&lt;br /&gt;
    myTrainer.XOR(); // { error: 0.004998819355993572, iterations: 21871, time: 356 }&lt;br /&gt;
&lt;br /&gt;
    myPerceptron.activate([0, 0]); // 0.0268581547421616&lt;br /&gt;
    myPerceptron.activate([1, 0]); // 0.9829673642853368&lt;br /&gt;
    myPerceptron.activate([0, 1]); // 0.9831714267395621&lt;br /&gt;
    myPerceptron.activate([1, 1]); // 0.02128894618097928&lt;br /&gt;
&lt;br /&gt;
    console.log(&amp;quot;Syntaptic loaded&amp;quot;);&lt;br /&gt;
} catch (e) {&lt;br /&gt;
    UI.alert(e.message);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Appendix}}&lt;/div&gt;</summary>
		<author><name>Elgaton</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=FlightGear_wiki:Instant-Refs&amp;diff=98424</id>
		<title>FlightGear wiki:Instant-Refs</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=FlightGear_wiki:Instant-Refs&amp;diff=98424"/>
		<updated>2016-05-20T12:31:46Z</updated>

		<summary type="html">&lt;p&gt;Elgaton: /* The script */ Use Genetic.js instead of dist.js (which is meant to be used by NPM only)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Quotes-logo-200x200.png|thumb]]&lt;br /&gt;
[[File:Instant-cquotes-firefox.png|thumb|Instant-Cquotes script in Firefox]]&lt;br /&gt;
&lt;br /&gt;
[[File:Ref-only-quotes.png|thumb|Instant-Cquotes screenshot prototyping runtime format selection]]&lt;br /&gt;
&lt;br /&gt;
The '''Instant-Cquotes''' script is a browser addon (user script) implemented in JavaScript in order to convert excerpts (created via copy&amp;amp;paste) from FlightGear forum or [[mailing list]] postings into MediaWiki markup/quotes to be used on the FlightGear wiki. It is supported by Firefox, Google Chrome/Chromium, Opera and Safari. It is being developed and maintained by a group of volunteers involved in maintaining the wiki and in trying to provide more up-to-date information to end-users who may not be as involved in the various FlightGear-related communication channels.&lt;br /&gt;
&lt;br /&gt;
== Background and motivation ==&lt;br /&gt;
FlightGear's development is, at best, &amp;quot;self-coordinated&amp;quot;, meaning that contributors discuss ideas and make proposals to contribute in a certain fashion and then team up to implement certain features and building blocks, often just temporarily.&lt;br /&gt;
&lt;br /&gt;
Unfortunately, due to a lack of development manpower, many ideas are not implemented immediately; it is, thus, important to know their pros and cons, as well as who originally proposed them and/or might help with their implementation, even after a long time, preferably with links to the original discussions so that new contributors can decide whether to get involved in some effort or not. The project documentation, however, is in great need of improvement&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
| url    = http://sourceforge.net/p/flightgear/mailman/message/15444440/&lt;br /&gt;
| title  = &amp;lt;nowiki&amp;gt;[Flightgear-devel] development process (was:  chaos...)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| author = &amp;lt;nowiki&amp;gt;John Denker&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| date   = Jul 16th, 2007&lt;br /&gt;
| added   = Jul 16th, 2007&lt;br /&gt;
| script_version = 0.23&lt;br /&gt;
}}&amp;lt;/ref&amp;gt; and usually significantly lacking behind:&amp;lt;ref name=&amp;quot;OlsonStateThingsFG&amp;quot;&amp;gt;{{cite web&lt;br /&gt;
| url    = http://sourceforge.net/p/flightgear/mailman/message/27861667/&lt;br /&gt;
| title  = &amp;lt;nowiki&amp;gt;Re: [Flightgear-devel] The state of things in Flight Gear&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| author = &amp;lt;nowiki&amp;gt;Curtis Olson&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| date   = Jul 27th, 2011&lt;br /&gt;
| added   = Jul 27th, 2011&lt;br /&gt;
| script_version = 0.23&lt;br /&gt;
}}&amp;lt;/ref&amp;gt; many core developers update it seldomly, if not anymore, as it takes time to write it, as well as an understanding of the inner workings of a complex system such as FlightGear. Furthermore, this task might not be attractive due to its short term impact on the project,&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
| url    = http://sourceforge.net/p/flightgear/mailman/message/27861562/&lt;br /&gt;
| title  = &amp;lt;nowiki&amp;gt;Re: [Flightgear-devel] The state of things in Flight Gear&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| author = &amp;lt;nowiki&amp;gt;Hal V. Engel&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| date   = Jul 27th, 2011&lt;br /&gt;
| added   = Jul 27th, 2011&lt;br /&gt;
| script_version = 0.23&lt;br /&gt;
}}&amp;lt;/ref&amp;gt; and it is overwhelming to think about creating documentation that would address the needs of many different kinds of contributors with different backgrounds, experience levels and goals.&amp;lt;ref name=&amp;quot;OlsonStateThingsFG&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Forum and mailing lists discussions have therefore become the only up-to-date (albeit difficult to filter)&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
| url    = http://forum.flightgear.org/viewtopic.php?p=280058#p280058&lt;br /&gt;
| title  = &amp;lt;nowiki&amp;gt;Re: quoting on the wiki&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| author = &amp;lt;nowiki&amp;gt;Thorsten&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| date   = Mar 21st, 2016&lt;br /&gt;
| added   = Mar 21st, 2016&lt;br /&gt;
| script_version = 0.25&lt;br /&gt;
}}&amp;lt;/ref&amp;gt; source of information about recent development progress; this makes it tricky to know what is going on, what needs fixing, what were the decisions taken by the developers.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
| url    = https://www.mail-archive.com/flightgear-devel%40lists.sourceforge.net/msg17198.html&lt;br /&gt;
| title  = &amp;lt;nowiki&amp;gt;[Flightgear-devel] Project tracking&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| author = &amp;lt;nowiki&amp;gt;James Turner&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| date   = Mon, 28 Jul 2008 10:06:05 -0700&lt;br /&gt;
}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The aim of the Instant-Cquotes script is to help wiki editors to copy relevant excerpts from such sources, formatting them as proper [[Template:Cquote|quotations]], and bootstrap new articles collecting them until a dedicated rewrite is made. It can also be used to reuse announcements to update the changelogs, [[Next newsletter|newsletter]] or the [[Release plan/Lessons learned]] page.&lt;br /&gt;
&lt;br /&gt;
After being away from the wiki system for some time it becomes more of an effort to re-learn how to start a new file and figure out how to format it , with what headings, etc. Sometimes it is almost too much to do the original write up of the original post and all the work of that layout and effort to have to also duplicate it in a wiki article. If I was a little more current and affluent with the wiki editor, I might not be so hesitant to create the work there instead of the forum.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=284698#p284698 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Breaking down NLCD raster image &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; wlbragg &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  May 9th, 2016 &lt;br /&gt;
  |added  =  May 9th, 2016 &lt;br /&gt;
  |script_version = 0.38 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In a few cases, such collections of quotes helped not only create bootstrap new articles, but even actual features.&lt;br /&gt;
&lt;br /&gt;
In other cases, quotes have been used to update documentation of features (e.g. [[Rembrandt]]) whose maintainers may not be actively involved in FlightGear, to help document discussions that are taking place in the meantime, and provide some background information for people interested in the corresponding feature.&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
# Install a user script manager. On Firefox, you can use [https://addons.mozilla.org/en-US/firefox/addon/greasemonkey/ Greasemonkey]; on Chrome/Chromium, Opera or Safari, you can use [https://tampermonkey.net/ Tampermonkey] (download links: [https://tampermonkey.net/index.php?ext=dhdg&amp;amp;browser=chrome Chrome/Chromium], [https://tampermonkey.net/index.php?ext=dhdg&amp;amp;browser=opera Opera], [https://tampermonkey.net/index.php?ext=dhdg&amp;amp;browser=safari Safari]).&lt;br /&gt;
# Visit [https://greasyfork.org/en/scripts/19331-instant-cquotes the Instant-Cquotes page on GreasyFork] and click on {{button|Install this script}} (green button). If Greasemonkey/Tampermonkey prompts you to confirm the installation, agree to do so.&lt;br /&gt;
&lt;br /&gt;
[[File:Howto-install-instant-cquotes.png|thumb|Click the green button to install the script]]&lt;br /&gt;
&lt;br /&gt;
=== Manual installation ===&lt;br /&gt;
{{note|This will install the most recent development version of the script, which might contain bugs. Also, GreaseMonkey/TamperMonkey will not update it automatically whenever a new version is released.}}&lt;br /&gt;
&lt;br /&gt;
* '''Firefox'''&lt;br /&gt;
# Install Greasemonkey.&lt;br /&gt;
# Save [[#The Script|the script]] below as &amp;lt;code&amp;gt;instant_cquotes.user.js&amp;lt;/code&amp;gt;, then drag-and-drop it into Firefox.&lt;br /&gt;
[[File:Greasemonkey-setup-on-firefox.png|thumb|Screenshot showing the Greasemonkey setup dialog (on Firefox)]]&lt;br /&gt;
&lt;br /&gt;
* '''Chrome/Chromium''', '''Opera''', or '''Safari'''&lt;br /&gt;
# Install Tampermonkey.&lt;br /&gt;
# Navigate to '''Add a new Script'''.&lt;br /&gt;
# Copy and paste [[#The Script|the script]] below into the editing window.&lt;br /&gt;
# Click the {{button|Save}} button (just above the {{button|Search}} button).&lt;br /&gt;
&lt;br /&gt;
=== Mobile installation ===&lt;br /&gt;
As of May 2016, there is no separate version available for mobile use. Your best chance is installing a userscript addon on Android, like one of those:&lt;br /&gt;
* [https://play.google.com/store/apps/details?id=net.biniok.tampermonkey Tampermonkey (Google Play Store)]&lt;br /&gt;
* [http://oilcan.jsharkey.org/ OilCan: Greasemonkey on steroids for Android]&lt;br /&gt;
&lt;br /&gt;
For installation instructions, refer to [https://openuserjs.org/about/Tampermonkey-for-Android Tampermonkey for Android] or [http://www.blogtechnika.com/how-to-access-greasemonkey-scripts-on-android-phones/ How To Access Greasemonkey Scripts on Android Phones].&lt;br /&gt;
&lt;br /&gt;
Testing/feedback would obviously be appreciated - if in doubt, feel free to just edit the wiki page to add your findings/questions.&lt;br /&gt;
&lt;br /&gt;
=== Configuration ===&lt;br /&gt;
[[File:User-script-menu.png|thumb|GreaseMonkey menu shown in FireFox with instanct cquotes menu items]]&lt;br /&gt;
&lt;br /&gt;
[[File:Config-dialog-instant-cquotes.png|thumb|The configuration dialog for the Instant-Cquotes script]]&lt;br /&gt;
&lt;br /&gt;
As of version 0.30, a dedicated configuration dialog is in the process of being added, so that certain script features can be dynamically configured, without having to edit the script. For now, this is merely a placeholder that provides a checkbox to easily enable/disable the debug mode. In the future, we are hoping to also expose other features this way.&lt;br /&gt;
&lt;br /&gt;
== Usage ==&lt;br /&gt;
[[File:Updated-cquotes-script-by-redleader.png|thumb|Instant-Cquotes script, with updates contributed by Red Leader]]&lt;br /&gt;
&lt;br /&gt;
[[File:New-cquotes.png|thumb|Screenshot showing Instant-Cquotes 0.30 at work]]&lt;br /&gt;
&lt;br /&gt;
# Go to some [[mailing list]] archive URL, for example [http://sourceforge.net/p/flightgear/mailman/message/32400727/] or any forum message, such as {{forumref|title=Re: Get objects to show up on Map/Radar|t=23299|label=p212558|f=71}}.&lt;br /&gt;
# Select the relevant portion of text.&lt;br /&gt;
# When you release the mouse button, a box will appear containing the converted text (for now, mainly properly-referenced quotes for the wiki).&lt;br /&gt;
# The text will be automatically selected and copied to the clipboard.&lt;br /&gt;
# Paste the text into the desired wiki page.&lt;br /&gt;
&lt;br /&gt;
For example, by selecting part of the forum post in the link above you can get the following quotation:&lt;br /&gt;
&lt;br /&gt;
{{FGCquote&lt;br /&gt;
|1= The upcoming FlightGear version (3.2) will contain a canvas-based map dialog, including a modular &amp;quot;plugin&amp;quot; system for creating custom map layers and charts with roughly ~50 lines of code, most of it boilerplate. &lt;br /&gt;
This is entirely XML/Nasal based (scripted) - symbols can be pretty much anything, raster or vector images (png or svg), but even animated. Styling can be customied, too.&lt;br /&gt;
For more info, I suggest to check out:&lt;br /&gt;
[[MapStructure#Porting the map dialog]]&lt;br /&gt;
&lt;br /&gt;
[[File:MapStructureDialog.png|250px]]&lt;br /&gt;
|2= {{cite web&lt;br /&gt;
  | url    = http://forum.flightgear.org/viewtopic.php?p=212558#p212558&lt;br /&gt;
  | title  = &amp;lt;nowiki&amp;gt;Re: Get objects to show up on Map/Radar&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  | author = &amp;lt;nowiki&amp;gt;Hooray&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  | date   = Jun 14th, 2014&lt;br /&gt;
  }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== On quoting ===&lt;br /&gt;
{{Main article|FlightGear wiki:Quoting Guidelines}}&lt;br /&gt;
&lt;br /&gt;
Using the Instant-Cquotes script is a good way to bootstrap and write some preliminary notes; however, while quotes might be useful to understand how undocumented subsystems and features work and are definitely better than nothing, they are not meant to replace proper, structured and well-written wiki articles.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
| url    = http://forum.flightgear.org/viewtopic.php?p=282800#p282800&lt;br /&gt;
| title  = &amp;lt;nowiki&amp;gt;Re: What is the QT launcher?&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| author = &amp;lt;nowiki&amp;gt;bugman&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| date   = Apr 17th, 2016&lt;br /&gt;
| added   = Apr 17th, 2016&lt;br /&gt;
| script_version = 0.25&lt;br /&gt;
}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One way to convert pages bootstrapped using quotes is to extract relevant information from them and keep citations only as references; in case important details are missing, they can be asked for on the [[Mailing lists|mailing lists]] (on the forum, the chance to get a complete answer might be lower).&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
| url    = http://sourceforge.net/p/flightgear/mailman/message/34954385/&lt;br /&gt;
| title  = &amp;lt;nowiki&amp;gt;Re: [Flightgear-devel] Wiki Quotes&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| author = &amp;lt;nowiki&amp;gt;James Turner&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| date   = Mar 21st, 2016&lt;br /&gt;
| added   = Mar 21st, 2016&lt;br /&gt;
| script_version = 0.25&lt;br /&gt;
}}&amp;lt;/ref&amp;gt; Another option might be moving the quotes to the Talk page for each entry, which would preserve the sources without clogging up the articles.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
| url    = http://sourceforge.net/p/flightgear/mailman/message/34948989/&lt;br /&gt;
| title  = &amp;lt;nowiki&amp;gt;Re: [Flightgear-devel] Wiki Quotes&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| author = &amp;lt;nowiki&amp;gt;Stuart Buchanan&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| date   = Mar 19th, 2016&lt;br /&gt;
| added   = Mar 19th, 2016&lt;br /&gt;
| script_version = 0.25&lt;br /&gt;
}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As a matter of fact, the whole paragraph above was assembled using this approach; to see for yourself, look up the references at the end of this page. For another example, see [[TerraSync#News]].&lt;br /&gt;
&lt;br /&gt;
== Development ==&lt;br /&gt;
{{Note|A Chrome/Chromium-specific extension that will not need Tampermonkey installed is under development.}}&lt;br /&gt;
&lt;br /&gt;
=== Resources ===&lt;br /&gt;
* https://www.mediawiki.org/wiki/API:Changing_wiki_content&lt;br /&gt;
* https://www.mediawiki.org/wiki/API:Edit&lt;br /&gt;
&lt;br /&gt;
=== Adding sources ===&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
{{WIP}}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
Adding a new source is pretty straightforward if you understand how xpath and regexes work - basically, you only need an archive (e.g. gmane), and then determine the xpath of each relevant field, as well as the regular expression to process the extracted fields (optional).&lt;br /&gt;
&lt;br /&gt;
The basic steps are these:&lt;br /&gt;
# open the user script in an editor&lt;br /&gt;
# navigate to the meta header of the user script&lt;br /&gt;
# add a new URL to the top of the script, e.g. by copying/adapting an existing line like this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// @match       https://sourceforge.net/p/flightgear/mailman/*&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once copied, add the new URL:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// @match       http://thread.gmane.org/gmane.games.flightgear.devel/*&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next, you need to navigate to the configuration hash to add a new website to it. &lt;br /&gt;
&lt;br /&gt;
Again, it makes sense to simply take an existing configuration hash and adapt it as needed (ignore/omit the tests vector for now by keeping it empty):&lt;br /&gt;
&lt;br /&gt;
{{Caution|the following example may meanwhile be outdated, so be sure to look at the actual code instead}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  'Sourceforge Mailing list': {&lt;br /&gt;
    enabled: true,&lt;br /&gt;
    type: 'archive',&lt;br /&gt;
    event: 'document.onmouseup', // when to invoke the event handler&lt;br /&gt;
    event_handler: instantCquote, // the event handler to be invoked&lt;br /&gt;
    url_reg: '^(http|https)://sourceforge.net/p/flightgear/mailman/.*/',&lt;br /&gt;
    content: {&lt;br /&gt;
      xpath: 'tbody/tr[2]/td/pre/text()',&lt;br /&gt;
      selection: getSelectedText,&lt;br /&gt;
      idStyle: /msg[0-9]{8}/,&lt;br /&gt;
      parentTag: [&lt;br /&gt;
        'tagName',&lt;br /&gt;
        'PRE'&lt;br /&gt;
      ],&lt;br /&gt;
    transform: [] // vector with transformation callbacks&lt;br /&gt;
    }, // content recipe&lt;br /&gt;
    // vector with tests to be executed for sanity checks (unit testing)&lt;br /&gt;
    tests: [&lt;br /&gt;
    ], // end of vector with self-tests&lt;br /&gt;
    // regex/xpath and transformations for extracting various required fields&lt;br /&gt;
    author: {&lt;br /&gt;
      xpath: 'tbody/tr[1]/td/div/small/text()',&lt;br /&gt;
      transform: [extract(/From: (.*) &amp;lt;.*@.*&amp;gt;/)]&lt;br /&gt;
    },&lt;br /&gt;
    title: {&lt;br /&gt;
      xpath: 'tbody/tr[1]/td/div/div[1]/b/a/text()'&lt;br /&gt;
      transform: []&lt;br /&gt;
    },&lt;br /&gt;
    date: {&lt;br /&gt;
      xpath: 'tbody/tr[1]/td/div/small/text()',&lt;br /&gt;
      transform: [extract(/- (.*-.*-.*) /)]&lt;br /&gt;
    },&lt;br /&gt;
    url: {&lt;br /&gt;
      xpath: 'tbody/tr[1]/td/div/div[1]/b/a/@href',&lt;br /&gt;
      transform: [prepend('https://sourceforge.net')]&lt;br /&gt;
    }&lt;br /&gt;
  }, // end of mailing list profile&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, we need to review/adapt the profile according to the new archive we'd like to see supported. &lt;br /&gt;
&lt;br /&gt;
for starters, that means:&lt;br /&gt;
* changing the name of the profile, e.g. to read gmane (instead of sourceforge)&lt;br /&gt;
* change the '''url_reg''' field to the gmane URL (this can be a regular expression)&lt;br /&gt;
&lt;br /&gt;
Next, it makes sense to use an [https://addons.mozilla.org/de/firefox/addon/xpath-checker/ XPath checker], so that we can look up the xpath expression for various HTML elements, and add those to the configuration hash above.&lt;br /&gt;
&lt;br /&gt;
For testing purposes, you will probably go to the setup dialog and enable the DEBUG mode, and use your browser's console to see what is going on.&lt;br /&gt;
&lt;br /&gt;
=== Getting involved ===&lt;br /&gt;
While having some experience with JavaScript/HTML and jQuery will definitely be useful, JavaScript is close enough to FlightGear scripting ([[Nasal]]), so that people can get involved pretty easily. &lt;br /&gt;
&lt;br /&gt;
Most maintenance work will typically involve reviewing/maintaining a few configuration hashes, that contain meta information for each supported archive (mailing list/forum).&lt;br /&gt;
&lt;br /&gt;
Usually, each hash contains a combination of xpath/regex expressions to look up the relevant information, as well as vector of optional transformations that are applied (in order) to convert contents to a different format (e.g. dates).&lt;br /&gt;
&lt;br /&gt;
In addition, there is growing library of utility functions, a handful wrappers for useful stuff, for example:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;Host.dbLog(message_string)&amp;lt;/code&amp;gt; - log a message to the console if the DEBUG flag is set&lt;br /&gt;
* &amp;lt;code&amp;gt;Host.download(url, callback, method='GET')&amp;lt;/code&amp;gt; - will download the URL and pass the downloaded content to the callback specified&lt;br /&gt;
* &amp;lt;code&amp;gt;Host.downloadPosting(url, callback)&amp;lt;/code&amp;gt; - will download the posting URL and pass the extracted and transformed author/content and date fields in a hash to the callback specified, the URL must be one supported in the CONFIG hash (i.e. forum/sourceforge for now)&lt;br /&gt;
* &amp;lt;code&amp;gt;Host.make_doc(string, type=&amp;quot;text/html&amp;quot;)&amp;lt;/code&amp;gt; - will turn a string/blob into a DOM that can be queried&lt;br /&gt;
* &amp;lt;code&amp;gt;Host.eval_xpath(document, xpath_expression, type=XPathResult.STRING_TYPE)&amp;lt;/code&amp;gt; - will apply the xpath expression to the document specified, returning the requested type (defaulted to string) &lt;br /&gt;
* &amp;lt;code&amp;gt;Host.set_persistent(key,value)&amp;lt;/code&amp;gt;  - stores a key/value pair&lt;br /&gt;
* &amp;lt;code&amp;gt;Host.get_persistent(key,default_value)&amp;lt;/code&amp;gt; - retrieves a values using the key specified, falling back to the default value&lt;br /&gt;
&lt;br /&gt;
=== Porting ===&lt;br /&gt;
[[File:Instant-cquote-firefox-addon-mode.png|thumb|Prototyping a dedicated instant-cquote mode for use as a firefox addon]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Porting the script to support other browsers/script engines is greatly appreciated. Typically, this should be pretty self-contained, because all main APIs are intended to be encapsulated in a so called &amp;quot;Environment&amp;quot; hash, where APIs that are specific to a particular browser/script engine should be provided with a wrapper. As of mid 2016, most APIs are now kept inside such an Environment hash (look at the GreaseMonkey hash for reference/details), so that it is now even possible to turn the script into a standalone FireFox addon without having to change much of the underlying code.&lt;br /&gt;
&lt;br /&gt;
=== Self checks (unit testing) ===&lt;br /&gt;
For regression testing purposes, there's a dedicated &amp;quot;self check&amp;quot; dialog that will be extended over time. For now it will download a few profile/website specific postings using a vector called &amp;quot;tests&amp;quot; and then log the posting's title, author and date to the console.&lt;br /&gt;
&lt;br /&gt;
The next step will be  actually showing that information in the dialog itself - there's a separate helper function to accomplish that, so that the corresponding div layer can be updated with the results.&lt;br /&gt;
&lt;br /&gt;
[[File:Sanity-check-cquotes-dialog.png|thumb|automatically executed sanity checks]]&lt;br /&gt;
&lt;br /&gt;
=== Debug mode ===&lt;br /&gt;
[[File:Instant-cquotes-debug-mode.png|thumb|Instant-Cquotes debug mode]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== AJAX (live page editing) ===&lt;br /&gt;
{{WIP}}&lt;br /&gt;
&lt;br /&gt;
* http://wiki.flightgear.org/api.php&lt;br /&gt;
* http://wiki.flightgear.org/api.php?action=parse&amp;amp;page=Frequently%20asked%20questions&amp;amp;prop=sections&lt;br /&gt;
&lt;br /&gt;
For now, the setup dialog will try to obtain a login token for the wiki and show a message if successful.&lt;br /&gt;
&lt;br /&gt;
In addition, the profile/website hash also contains a new wiki entry for the FlightGear wiki, whose '''event_handler''' callback will be invoked once the FG wiki is visited - the console/log will show a greeting, so that is where other code can be added - e.g. to help clean up/rewrite FGCquote-based articles automatically etc.&lt;br /&gt;
&lt;br /&gt;
There is a vector of &amp;quot;modes&amp;quot;, whose members are a hash containing trigger/handler fields, linked to two callbacks - the trigger callback can be used to check some condition, while the handler will be invoked if the trigger returns true.&lt;br /&gt;
&lt;br /&gt;
This can be used to support an arbitrary number of modes, whose triggers are evaluated during page load - all triggers that return true, will have their handlers invoked, which is how the following snippet works to rewrite/augment wiki edit handles:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;gt;&lt;br /&gt;
 'FlightGear.wiki': {&lt;br /&gt;
    type: 'wiki',&lt;br /&gt;
    enabled: false,&lt;br /&gt;
    event: 'document.onmouseup', // when to invoke the event handler&lt;br /&gt;
    event_handler: function () {&lt;br /&gt;
      console.log('FlightGear wiki handler active (waiting to be populated)');&lt;br /&gt;
      // this is where the logic for a wiki mode can be added over time (for now, it's a NOP)&lt;br /&gt;
    &lt;br /&gt;
    //for each supported mode, invoke the trigger and call the corresponding handler&lt;br /&gt;
    [].forEach.call(CONFIG['FlightGear.wiki'].modes, function(mode) {&lt;br /&gt;
      //dbLog(&amp;quot;Checking trigger:&amp;quot;+mode.name);&lt;br /&gt;
      if(mode.trigger) {&lt;br /&gt;
        mode.handler();&lt;br /&gt;
      }&lt;br /&gt;
    });&lt;br /&gt;
      &lt;br /&gt;
    }, // the event handler to be invoked&lt;br /&gt;
    url_reg: '^(http|https)://wiki.flightgear.org', // ignore for now: not currently used by the wiki mode&lt;br /&gt;
    &lt;br /&gt;
    modes: [&lt;br /&gt;
      { name:'process-editSections',&lt;br /&gt;
        trigger: function() {return true;}, // match URL regex - return true for always match&lt;br /&gt;
       &lt;br /&gt;
        // the code implementing the mode&lt;br /&gt;
        handler: function() {&lt;br /&gt;
                &lt;br /&gt;
    var editSections = document.getElementsByClassName('mw-editsection');&lt;br /&gt;
    console.log('FlightGear wiki article, number of edit sections: '+editSections.length);&lt;br /&gt;
   &lt;br /&gt;
    // for now, just rewrite edit sections and add a note to them&lt;br /&gt;
   &lt;br /&gt;
     [].forEach.call(editSections, function (sec) {&lt;br /&gt;
       sec.appendChild(&lt;br /&gt;
         document.createTextNode(' (instant-cquotes is lurking) ')&lt;br /&gt;
       );&lt;br /&gt;
     }); //forEach section&lt;br /&gt;
        } // handler&lt;br /&gt;
       &lt;br /&gt;
       &lt;br /&gt;
      } // process-editSections&lt;br /&gt;
      // TODO: add other wiki modes below &lt;br /&gt;
      &lt;br /&gt;
    ] // modes&lt;br /&gt;
    &lt;br /&gt;
  }, // end of wiki profile&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See [[User:Red Leader/Sandbox/AJAX test]]&lt;br /&gt;
&lt;br /&gt;
* https://www.mediawiki.org/wiki/API:Changing_wiki_content&lt;br /&gt;
* https://www.mediawiki.org/wiki/Extension:VisualEditor&lt;br /&gt;
* https://en.wikipedia.org/wiki/Wikipedia:Creating_a_bot&lt;br /&gt;
&lt;br /&gt;
=== Mobile edition ===&lt;br /&gt;
{{Note|As of 02/2016, Hooray is contemplating to make this available as an addon for Android phones.}}&lt;br /&gt;
&lt;br /&gt;
=== Issues/limitations ===&lt;br /&gt;
==== Bugs ====&lt;br /&gt;
* It's eating characters, apparently related to regex/xpath handling - e.g. words like &amp;quot;analyzing&amp;quot; are turned into &amp;quot;analying&amp;quot; [http://forum.flightgear.org/viewtopic.php?f=6&amp;amp;t=28378&amp;amp;p=270735&amp;amp;hilit=analyzing#p270735]&lt;br /&gt;
==== Non working URLs ====&lt;br /&gt;
* image matching/extraction: http://forum.flightgear.org/viewtopic.php?p=276221#p276221&lt;br /&gt;
* http://sourceforge.net/p/flightgear/mailman/message/34754961/&lt;br /&gt;
* http://forum.flightgear.org/viewtopic.php?f=18&amp;amp;t=27054&amp;amp;start=90#p273972 → selecting from “As promised, two sample installation sessions on Linux” to “That's it.” towards the end of the message causes Iceweasel (Firefox) 44.0.2 to display a dialog box reading “A script on this page may be busy, or it may have stopped responding. You can stop the script now, open the script in the debugger, or let the script continue.” The line below reads “Script: chrome://greasemonkey-modules/...quotes/instant_cquotes.user.js:544”. Choosing ''Continue'' doesn't help: the same message reappears a few seconds afterwards.&lt;br /&gt;
&lt;br /&gt;
=== Feature requests &amp;amp; ideas ===&lt;br /&gt;
* try to recognize list items [https://sourceforge.net/p/flightgear/mailman/message/35095319/] (heuristics: look for colon/asterisk, dashes and CR/LF)&lt;br /&gt;
* should add [[Template:News]] to the article dropdown for announcements [http://wiki.flightgear.org/index.php?title=Template:News&amp;amp;oldid=98266]&lt;br /&gt;
* add a mode that will download screenshots from forum postings and automatically upload/categorize them, see [[Birds]]&lt;br /&gt;
* split the article dropdown into sections, and also populate it with the user's watchlist [https://www.mediawiki.org/wiki/API:Watchlist] {{Progressbar|60}}&lt;br /&gt;
* mailing list templates, listed at [http://wiki.flightgear.org/Template_talk:Project_infrastructure#Related_mailing_list_templates]&lt;br /&gt;
* expose the cquote/ref markup via the UI so that it can be edited/customized and treated like a template {{Done}} (0.36+)&lt;br /&gt;
* identify common/repeated links and automatically create [[Template:Project infrastructure|link/infrastructure templates]] and use those (should be straightforward using the AJAX mode) [http://wiki.flightgear.org/index.php?title=Mailing_lists&amp;amp;curid=2038&amp;amp;diff=97876&amp;amp;oldid=85252]&lt;br /&gt;
* add a devel/maintainer mode where it will return the xpath for a selection [http://stackoverflow.com/questions/361130/get-selected-text-and-selected-nodes-on-a-page] [http://stackoverflow.com/questions/12485334/get-surrounding-dom-node-of-selection]&lt;br /&gt;
* move openlink,dblog helpers to Environment hash {{Done}}&lt;br /&gt;
* identify CLI arguments like --aircraft=c172p and wrap them in between code tags &amp;lt;code&amp;gt;--aircraft=c172p&amp;lt;/code&amp;gt; [https://sourceforge.net/p/flightgear/mailman/message/35063277/] (note that we can simply download [https://sourceforge.net/p/flightgear/fgdata/ci/next/tree/options.xml options.xml] via openlink() and use that, which is kinda of neat...) {{Progressbar|60}} (see downloadOptionsXML() in the code)&lt;br /&gt;
* introduce &amp;quot;layouts&amp;quot; (templates) for different purposes: newsletter, changelog, wiki article, [[The Manual]] (LaTex)  ? {{Progressbar|40}}&lt;br /&gt;
* use wikipedia template if possible [https://sourceforge.net/p/flightgear/mailman/message/35057670/]&lt;br /&gt;
* the new '''tests''' vector could also contain vectors for tests to test the extract/transform* utilities, see Environment.APITests {{Progressbar|50}}&lt;br /&gt;
* move environment specific APIs (browser, script host etc) into some kind of Environment hash to encapsulate things (Red Leader was working on a pure Chrome-only version at some point IIRC) {{Progressbar|80}}&lt;br /&gt;
* encode script settings in created markup, for future processing/updating of quotes&lt;br /&gt;
* look up &amp;lt;code&amp;gt;[x]&amp;lt;/code&amp;gt; references and replace with the corresponding link (titled) [https://sourceforge.net/p/flightgear/mailman/message/35055331/] [https://sourceforge.net/p/flightgear/mailman/message/35062598/]&lt;br /&gt;
** convert footnotes into Abbr templates [http://article.gmane.org/gmane.games.flightgear.devel/78971]&lt;br /&gt;
* support named refs for combining identical refs [http://wiki.flightgear.org/index.php?title=FlightGear_Qt_launcher&amp;amp;curid=13693&amp;amp;diff=97562&amp;amp;oldid=97551]&lt;br /&gt;
* adopt [[Template:Forumref]]&lt;br /&gt;
* implement a less obnoxious quoting mode, without quotes, where only the ref part would be added, e.g. see the example at [[Graphics Card Profiles]] (it's still 99% quotes, but much less annoying) {{Done}}&lt;br /&gt;
* attachment support: identify attachments and link to them: [https://sourceforge.net/p/flightgear/mailman/message/11683451/] [https://sourceforge.net/p/flightgear/mailman/message/23906620/] [https://sourceforge.net/p/flightgear/mailman/message/35059842/] [https://sourceforge.net/p/flightgear/mailman/message/35067087/]&lt;br /&gt;
* bulletin points: if there is a colon (:) followed by at least two dashes (-), split up everything after the colon to turn each dash into an asterisk (wiki markup for bulletin points), followed by a newline [http://sourceforge.net/p/flightgear/mailman/message/34760165/]   &lt;br /&gt;
* generic URL/template matching, e.g. for for sourceforge commit IDs&lt;br /&gt;
* make filters/conversions configurable via checkboxes (nowiki, wrap in alert/note boxes)&lt;br /&gt;
* make syntax highlighting configurable (language, mode) ?&lt;br /&gt;
* consider using something like the Roles template to turn contributor names into tooltips where contributor roles are shown (core dev, fgdata committer etc)&lt;br /&gt;
* introduce support for tag clouds to help categorize/classify related quotes&lt;br /&gt;
* consider making transformations optional/configurable using check boxes in the jQuery dialog&lt;br /&gt;
* add new input method, for quotes that need to be updated/converted (added script version specifically for this purpose), should also add extraction/processing date&lt;br /&gt;
* investigate why not all mailing list archives/postings are supported correctly: http://sourceforge.net/p/flightgear/mailman/message/8090479/ (problem traced to &amp;lt;code&amp;gt;getPostID()&amp;lt;/code&amp;gt;)&lt;br /&gt;
* explore having a ref-only mode without using cquotes, i.e. just copy/paste quotes with proper ref tags and a references section, to rewrite the whole thing (possibly with templates for different purposes, e.g. newsletter/changelog) {{Done}}&lt;br /&gt;
* should use Template:Forumref (category:link templates)&lt;br /&gt;
* should be updated to use the new repo/flightgear file templates created by Johan &amp;amp; RedLeader {{Not done}}&lt;br /&gt;
* resolve links to forum threads to look up the title for the topic/posting, so that the posting's title can be used for those links, instead of just the URL - we can probably do that by making an AJAX call to open URLs asynchronously and extract the title for the thread/posting to come up with something like &amp;lt;code&amp;gt;[http://forum.flightgear.org/viewtopic.php?f=4&amp;amp;t=24421 A call to developers-Lockheed -L188 Electra]&amp;lt;/code&amp;gt; ([http://forum.flightgear.org/viewtopic.php?f=4&amp;amp;t=26562&amp;amp;p=247325&amp;amp;hilit=links#p247347]) {{Progressbar|50}}&lt;br /&gt;
* convert quoted bug tracker URLs to use the issue template on the wiki {{not done}}&lt;br /&gt;
* do regex/xpath validation, and display any errors (e.g. template/theme changes on the forum would currently break the script) {{Progressbar|60}}&lt;br /&gt;
* increased focus on supporting different output formats, maybe using a simple [http://www.jquery-steps.com/ jQuery based wizard] (wiki, forum, newsletter, changelog) {{Not done}}&lt;br /&gt;
* token matching for keywords/acronyms to link to the corresponding wiki articles (e.g. Nasal, Canvas, FG_ROOT, FG_HOME etc) {{Not done}}&lt;br /&gt;
* Add support for [http://sourceforge.net/p/flightgear/codetickets/ tickets], merge requests comments and [http://www.fguk.eu/index.php/forum/index FGUK forum]. (also see [[FlightGear wiki talk:Instant-Cquotes#more sources]])&lt;br /&gt;
* GET-encoded SID arguments should be stripped from forum URLs. {{Not done}}&lt;br /&gt;
* Links to repositories should be converted to use wiki templates. {{Not done}}&lt;br /&gt;
* The {{Abbr|regexes|regular expressions}} used may fail if the HTML DOM of the source changes (e.g., phpBB/theme update)&lt;br /&gt;
** Show a warning when that's the case. {{Progressbar|70}} (see the self-check dialog)&lt;br /&gt;
** Try multiple regexes in order. {{Progressbar|30}} (see the self-check dialog)&lt;br /&gt;
* Use the script to update previously created Cquotes automatically&lt;br /&gt;
** Instead of using the &amp;lt;code&amp;gt;getSelection()&amp;lt;/code&amp;gt; helper, we could register a match for &amp;lt;tt&amp;gt;wiki.flightgear.org&amp;lt;/tt&amp;gt; with &amp;lt;code&amp;gt;action=edit&amp;lt;/code&amp;gt; set, so that we can directly process all text of an edited page, using AJAX calls to open the URL in the background. {{Progressbar|40}} (see the self-check dialog, available via the greasemonkey menu)&lt;br /&gt;
** See [https://www.mediawiki.org/wiki/API:Edit#Editing_via_Ajax MW:API:Edit § Editing via Ajax]&lt;br /&gt;
&lt;br /&gt;
=== Changelog ===&lt;br /&gt;
{{Note|Contributors are invited to document their changes here, please also add your wiki handle so that others can more easily get in touch.}}&lt;br /&gt;
&lt;br /&gt;
* first stab at implementing unit tests by adding a vector with URLS to be downloaded and fields to be matched (WIP), shown in a jQuery dialog&lt;br /&gt;
* support for persistent settings and a jQuery setup dialog with persistence&lt;br /&gt;
* hosting is moved, to allow auto-updates [http://www.greasespot.net/2012/02/automatic-script-updates-come-to.html] [https://wiki.greasespot.net/Metadata_Block#.40updateURL] [http://stackoverflow.com/questions/15095055/why-isnt-my-greasemonkey-script-updating]&lt;br /&gt;
* changed to ref-only quotes for now, not using the FGCquote template anymore, due to its obnoxious appearance on quote-heavy pages (should probably become a runtime option instead)&lt;br /&gt;
* updated to use https for forum postings&lt;br /&gt;
* add version info to each created quote, i.e. for future updates&lt;br /&gt;
* add helper for opening websites asynchronously using AJAX (also via GM helper API)&lt;br /&gt;
* display version number in output dialog&lt;br /&gt;
* begin using the GreaseMonkey API for setting clipboard content&lt;br /&gt;
&lt;br /&gt;
== The script ==&lt;br /&gt;
&amp;lt;gallery mode=packed widths=230px heights=230px&amp;gt;&lt;br /&gt;
Instant-cquotes-revamped.png|Instant cquotes: Revamped user interface exposes script internals to make the script better configurable at runtime&lt;br /&gt;
Instant-cquotes-template-editor.png|Instant cquotes now features a simple built-in template editor with support for variable substitution, so that wiki templates can be more easily customized&lt;br /&gt;
Instant-cquotes-with-wikimedia-API-integration.png|Screenshot showing instant-cquotes with wikimedia API integration to fetch articles/sections and populate dropdown menus accordingly&lt;br /&gt;
Instant-cquotes-on-steroids-with-watchlist-support.png|Screenshot showing the JQuery-mode of the instant cquotes script with built-in support for fetching a user's wiki/watchlist to edit/update articles in a semi-automated fashion&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
{{PD-author|FlightGear contributors}}&lt;br /&gt;
&lt;br /&gt;
{{Note|Anybody interested in contributing to the code is invited to directly edit this wiki article. From 05/2016, the script is hosted on GreasyFork to allow automatic updates. If you'd like to see your changes applied, please bump the version number and [[User:Elgaton|Elgaton]] will upload it in the state it was when the version number was bumped. ''Make sure to perform thorough testing'' before the bump to prevent unexpected breakage; it is generally a good idea to validate your changes using an online syntax checker, e.g.:&lt;br /&gt;
* http://jshint.com/ &lt;br /&gt;
* http://esprima.org/demo/validate.html&lt;br /&gt;
* http://codebeautify.org/jsvalidate&lt;br /&gt;
&amp;lt;p/&amp;gt;Thank you!}}&lt;br /&gt;
&lt;br /&gt;
Changes that should be mentioned in the changelog, should be added below (and moved to the [[#Changelog]] section subsequently:&lt;br /&gt;
&lt;br /&gt;
* preparations for adding support to download fgdata related files like options.xml to automatically regex known CLI commands&lt;br /&gt;
* preparatory work for adding a speech-rewrite engine to assist in converting 1st person speech to 3rd person&lt;br /&gt;
* framework for encapsulating userscript specifics in an environment hash to provide better updating/porting support&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;// ==UserScript==&lt;br /&gt;
// @name        Instant-Cquotes&lt;br /&gt;
// @name:it     Instant-Cquotes&lt;br /&gt;
// @license     public domain&lt;br /&gt;
// @version     0.39&lt;br /&gt;
// @date        2016-05-05&lt;br /&gt;
// @description Automatically converts selected FlightGear mailing list and forum quotes into post-processed MediaWiki markup (i.e. cquotes).&lt;br /&gt;
// @description:it Converte automaticamente citazioni dalla mailing list e dal forum di FlightGear in marcatori MediaWiki (cquote).&lt;br /&gt;
// @author      Hooray, bigstones, Philosopher, Red Leader &amp;amp; Elgaton (2013-2016)&lt;br /&gt;
// @supportURL  http://wiki.flightgear.org/FlightGear_wiki:Instant-Cquotes&lt;br /&gt;
// @icon        http://wiki.flightgear.org/images/2/25/Quotes-logo-200x200.png&lt;br /&gt;
// @match       https://sourceforge.net/p/flightgear/mailman/*&lt;br /&gt;
// @match       http://sourceforge.net/p/flightgear/mailman/*&lt;br /&gt;
// @match       https://forum.flightgear.org/*&lt;br /&gt;
// @match       http://wiki.flightgear.org/*&lt;br /&gt;
// @namespace   http://wiki.flightgear.org/FlightGear_wiki:Instant-Cquotes&lt;br /&gt;
// @run-at      document-start&lt;br /&gt;
// @require     https://code.jquery.com/jquery-1.10.2.js&lt;br /&gt;
// @require     https://code.jquery.com/ui/1.11.4/jquery-ui.js&lt;br /&gt;
// @require     https://cdn.jsdelivr.net/genetic.js/0.1.14/genetic.js&lt;br /&gt;
// @require     https://cdn.jsdelivr.net/synaptic/1.0.4/synaptic.min.js&lt;br /&gt;
// @resource    jQUI_CSS https://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css&lt;br /&gt;
// @resource    myLogo http://wiki.flightgear.org/images/2/25/Quotes-logo-200x200.png&lt;br /&gt;
// @grant       GM_registerMenuCommand&lt;br /&gt;
// @grant       GM_setValue&lt;br /&gt;
// @grant       GM_getValue&lt;br /&gt;
// @grant       GM_addStyle&lt;br /&gt;
// @grant       GM_getResourceText&lt;br /&gt;
// @grant       GM_getResourceURL&lt;br /&gt;
// @grant       GM_setClipboard&lt;br /&gt;
// @grant       GM_xmlhttpRequest&lt;br /&gt;
// @noframes&lt;br /&gt;
// ==/UserScript==&lt;br /&gt;
//&lt;br /&gt;
// This work has been released into the public domain by their authors. This&lt;br /&gt;
// applies worldwide.&lt;br /&gt;
// In some countries this may not be legally possible; if so:&lt;br /&gt;
// The authors grant anyone the right to use this work for any purpose, without&lt;br /&gt;
// any conditions, unless such conditions are required by law.&lt;br /&gt;
//&lt;br /&gt;
// This script has a number of dependencies that are implicitly satisfied when run as a user script &lt;br /&gt;
// via GreaseMonkey/TamperMonkey; however, these need to be explicitly handled when using a different mode (e.g. firefox/android):&lt;br /&gt;
// &lt;br /&gt;
// - jQuery - user interface (REQUIRED)&lt;br /&gt;
// - genetic-js - genetic programming (OPTIONAL/EXPERIMENTAL)&lt;br /&gt;
// - synaptic - neural networks (OPTIONAL/EXPERIMENTAL)&lt;br /&gt;
// &lt;br /&gt;
// &lt;br /&gt;
&lt;br /&gt;
/* Here are some TODOs&lt;br /&gt;
 * - support RSS feeds http://dir.gmane.org/gmane.games.flightgear.devel/&lt;br /&gt;
 * - move event handling/processing to the CONFIG hash&lt;br /&gt;
 * - use try/catch more widely&lt;br /&gt;
 * - wrap function calls in try/call for better debugging/diagnostics&lt;br /&gt;
 * - add helpers for [].forEach.call, map, apply and call&lt;br /&gt;
 * - replace for/in, for/of, let statements for better compatibility (dont require ES6)&lt;br /&gt;
 * - for the same reason, replace use of functions with default params &lt;br /&gt;
 * - isolate UI (e.g. JQUERY) code in UserInterface hash&lt;br /&gt;
 * - expose regex/transformations via the UI&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
'use strict';&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// TODO: move to GreaseMonkey/UI host&lt;br /&gt;
// prevent conflicts with jQuery used on webpages: https://wiki.greasespot.net/Third-Party_Libraries#jQuery&lt;br /&gt;
// http://stackoverflow.com/a/5014220&lt;br /&gt;
this.$ = this.jQuery = jQuery.noConflict(true);&lt;br /&gt;
&lt;br /&gt;
// this hash is just intended to help isolate UI specifics&lt;br /&gt;
// so that we don't need to maintain/port tons of code &lt;br /&gt;
&lt;br /&gt;
var UserInterface = {&lt;br /&gt;
  get: function() {&lt;br /&gt;
    return UserInterface.DEFAULT;&lt;br /&gt;
  },&lt;br /&gt;
  &lt;br /&gt;
 CONSOLE: {&lt;br /&gt;
   &lt;br /&gt;
 }, // CONSOLE (shell, mainly useful for testing)&lt;br /&gt;
  &lt;br /&gt;
 DEFAULT: {&lt;br /&gt;
  alert: function(msg) {return window.alert(msg);     },&lt;br /&gt;
  prompt: function(msg) {return window.prompt(msg);  }, &lt;br /&gt;
  confirm: function(msg) {return window.confirm(msg); },&lt;br /&gt;
  dialog: null,&lt;br /&gt;
  selection: null,&lt;br /&gt;
  populateWatchlist: function() {&lt;br /&gt;
    &lt;br /&gt;
  },&lt;br /&gt;
  populateEditSections: function() {&lt;br /&gt;
    &lt;br /&gt;
  }&lt;br /&gt;
 &lt;br /&gt;
 }, // default UI mapping (Browser/User script)&lt;br /&gt;
  &lt;br /&gt;
  JQUERY: {&lt;br /&gt;
    &lt;br /&gt;
  } // JQUERY &lt;br /&gt;
  &lt;br /&gt;
}; // UserInterface&lt;br /&gt;
&lt;br /&gt;
var UI = UserInterface.get(); // DEFAULT for now&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// This hash is intended to help encapsulate platform specifics (browser/scripting host)&lt;br /&gt;
// Ideally, all APIs that are platform specific should be kept here&lt;br /&gt;
// This should make it much easier to update/port and maintain the script in the future&lt;br /&gt;
var Environment = {&lt;br /&gt;
  getHost: function(xpi=false) {&lt;br /&gt;
 &lt;br /&gt;
     if(xpi) {&lt;br /&gt;
       Environment.scriptEngine = 'firefox addon';&lt;br /&gt;
       console.log('in firefox xpi/addon mode');&lt;br /&gt;
       return Environment.FirefoxAddon; // HACK for testing the xpi mode (firefox addon)&lt;br /&gt;
     }&lt;br /&gt;
    &lt;br /&gt;
    // This will determine the script engine in use: http://stackoverflow.com/questions/27487828/how-to-detect-if-a-userscript-is-installed-from-the-chrome-store&lt;br /&gt;
    if (typeof(GM_info) === 'undefined') {&lt;br /&gt;
    Environment.scriptEngine = &amp;quot;plain Chrome (Or Opera, or scriptish, or Safari, or rarer)&amp;quot;;&lt;br /&gt;
    // See http://stackoverflow.com/a/2401861/331508 for optional browser sniffing code.&lt;br /&gt;
   }&lt;br /&gt;
   else {&lt;br /&gt;
    Environment.scriptEngine = GM_info.scriptHandler  ||  &amp;quot;Greasemonkey&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
   console.log ('Instant cquotes is running on ' + Environment.scriptEngine + '.');&lt;br /&gt;
    &lt;br /&gt;
   //console.log(&amp;quot;not in firefox addon mode...&amp;quot;);&lt;br /&gt;
    // See also: https://wiki.greasespot.net/Cross-browser_userscripting&lt;br /&gt;
    return Environment.GreaseMonkey; // return the only/default host (for now)&lt;br /&gt;
  },&lt;br /&gt;
  &lt;br /&gt;
  validate: function(host) {&lt;br /&gt;
    if (host.get_persistent('startup.disable_validation',false)) return;&lt;br /&gt;
    &lt;br /&gt;
    if(Environment.scriptEngine !== &amp;quot;Greasemonkey&amp;quot;) &lt;br /&gt;
      console.log(&amp;quot;NOTE: This script has not been tested with script engines other than GreaseMonkey recently!&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    var dependencies = [&lt;br /&gt;
      {name:'jQuery', test: function() {} },&lt;br /&gt;
      {name:'genetic.js', test: function() {} },&lt;br /&gt;
      {name:'synaptic', test: function() {} },&lt;br /&gt;
    ];&lt;br /&gt;
    &lt;br /&gt;
    [].forEach.call(dependencies, function(dep) {&lt;br /&gt;
      console.log(&amp;quot;Checking for dependency:&amp;quot;+dep.name);&lt;br /&gt;
      var status=false;&lt;br /&gt;
      try {&lt;br /&gt;
      dep.test.call(undefined);&lt;br /&gt;
      status=true;&lt;br /&gt;
      }&lt;br /&gt;
      catch(e) {&lt;br /&gt;
      status=false;       &lt;br /&gt;
      }&lt;br /&gt;
      finally {&lt;br /&gt;
        var success = (status)?'==&amp;gt; success':'==&amp;gt; failed';&lt;br /&gt;
        console.log(success);&lt;br /&gt;
        return status;&lt;br /&gt;
      }&lt;br /&gt;
    });&lt;br /&gt;
  }, // validate&lt;br /&gt;
  &lt;br /&gt;
  // this contains unit tests for checking crucial APIs that must work for the script to work correctly&lt;br /&gt;
  // for the time being, most of these are stubs waiting to be filled in&lt;br /&gt;
  // for a working example, refer to the JSON test at the end&lt;br /&gt;
  // TODO: add jQuery tests&lt;br /&gt;
  APITests: [&lt;br /&gt;
     {name:'download', test: function(recipient) {recipient(true);}  },&lt;br /&gt;
     {name:'make_doc', test: function(recipient) { recipient(true);}   },&lt;br /&gt;
     {name:'eval_xpath', test: function(recipient) { recipient(true);} },&lt;br /&gt;
     {name:'JSON de/serialization', test: function(recipient) {&lt;br /&gt;
       //console.log(&amp;quot;running json test&amp;quot;);&lt;br /&gt;
       var identifier = 'unit_tests.json_serialization';&lt;br /&gt;
       var hash1 = {x:1,y:2,z:3};&lt;br /&gt;
       Host.set_persistent(identifier, hash1, true);&lt;br /&gt;
       var hash2 = Host.get_persistent(identifier,null,true);&lt;br /&gt;
       &lt;br /&gt;
       recipient(JSON.stringify(hash1) === JSON.stringify(hash2));&lt;br /&gt;
     } // callback &lt;br /&gt;
     },&lt;br /&gt;
    &lt;br /&gt;
    // downloads a posting and tries to transform it to 3rd person speech ...&lt;br /&gt;
    // TODO: add another test to check forum postings&lt;br /&gt;
    {name:'text/speech transformation', test: function(recipient) {&lt;br /&gt;
    &lt;br /&gt;
    // the posting we want to download&lt;br /&gt;
    var url='https://sourceforge.net/p/flightgear/mailman/message/35066974/';&lt;br /&gt;
    Host.downloadPosting(url, function (result) {&lt;br /&gt;
      &lt;br /&gt;
    // only process the first sentence by using comma/dot as delimiter&lt;br /&gt;
    var firstSentence = result.content.substring(result.content.indexOf(',')+1, result.content.indexOf('.'));&lt;br /&gt;
      &lt;br /&gt;
    var transformed = transformSpeech(firstSentence, result.author, null, speechTransformations );&lt;br /&gt;
    console.log(&amp;quot;3rd person speech transformation:\n&amp;quot;+transformed);   &lt;br /&gt;
    &lt;br /&gt;
    recipient(true);&lt;br /&gt;
    }); // downloadPosting() &lt;br /&gt;
        &lt;br /&gt;
  }// test()&lt;br /&gt;
    }, // end of speech transform test&lt;br /&gt;
    {&lt;br /&gt;
      name:&amp;quot;download $FG_ROOT/options.xml&amp;quot;, test: function(recipient) {&lt;br /&gt;
        downloadOptionsXML();&lt;br /&gt;
        recipient(true);&lt;br /&gt;
      } // test&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
  ], // end of APITests&lt;br /&gt;
  &lt;br /&gt;
  runAPITests: function(host, recipient) {&lt;br /&gt;
    console.log(&amp;quot;Running API tests&amp;quot;);&lt;br /&gt;
    for(let test of Environment.APITests ) {&lt;br /&gt;
      //var test = Environment.APITests[t];&lt;br /&gt;
      // invoke the callback passed, with the hash containing the test specs, so that the console/log or a div can be updated showing the test results&lt;br /&gt;
      &lt;br /&gt;
      recipient.call(undefined, test);&lt;br /&gt;
      &lt;br /&gt;
    } // foreach test&lt;br /&gt;
  }, // runAPITests&lt;br /&gt;
  &lt;br /&gt;
  /*&lt;br /&gt;
   * ===================================================================================================================================================&lt;br /&gt;
   *&lt;br /&gt;
   */&lt;br /&gt;
  &lt;br /&gt;
  // NOTE: This mode/environment is WIP and highly experimental ...&lt;br /&gt;
  // To see this working, you need to package up the whole file as a firefox xpi using &amp;quot;jpm xpi&amp;quot;&lt;br /&gt;
  // and then start the whole thing via &amp;quot;jpm run&amp;quot;, to do that, you also need a matching package.json (i.e. via jpm init) &lt;br /&gt;
  // ALSO: you will have to explicitly install any dependencies using jpm&lt;br /&gt;
  FirefoxAddon: {&lt;br /&gt;
  	init: function() {&lt;br /&gt;
		console.log(&amp;quot;Firefox addon mode ...&amp;quot;);&lt;br /&gt;
  	},&lt;br /&gt;
	getScriptVersion: function() {&lt;br /&gt;
		return '0.36'; // FIXME&lt;br /&gt;
	},&lt;br /&gt;
	dbLog: function(msg) {&lt;br /&gt;
		console.log(msg);&lt;br /&gt;
	},&lt;br /&gt;
	addEventListener: function(ev, cb) {&lt;br /&gt;
&lt;br /&gt;
	require(&amp;quot;sdk/tabs&amp;quot;).on(&amp;quot;ready&amp;quot;, logURL);&lt;br /&gt;
 	function logURL(tab) {&lt;br /&gt;
  		console.log(&amp;quot;URL loaded:&amp;quot; + tab.url);&lt;br /&gt;
	}	&lt;br /&gt;
	},&lt;br /&gt;
    &lt;br /&gt;
	registerConfigurationOption: function(name, callback, hook) {&lt;br /&gt;
	// https://developer.mozilla.org/en-US/Add-ons/SDK/Tutorials/Add_a_Context_Menu_Item&lt;br /&gt;
		console.log(&amp;quot;config menu support n/a in firefox mode&amp;quot;);&lt;br /&gt;
 // https://developer.mozilla.org/en-US/Add-ons/SDK/Tutorials/Using_third-party_modules_%28jpm%29  &lt;br /&gt;
 var menuitems = require(&amp;quot;menuitem&amp;quot;);&lt;br /&gt;
 var menuitem = menuitems.Menuitem({&lt;br /&gt;
  id: &amp;quot;clickme&amp;quot;,&lt;br /&gt;
  menuid: &amp;quot;menu_ToolsPopup&amp;quot;,&lt;br /&gt;
  label: name,&lt;br /&gt;
  onCommand: function() {&lt;br /&gt;
    console.log(&amp;quot;menuitem clicked:&amp;quot;);&lt;br /&gt;
    callback();&lt;br /&gt;
  },&lt;br /&gt;
  insertbefore: &amp;quot;menu_pageInfo&amp;quot;&lt;br /&gt;
});&lt;br /&gt;
	},&lt;br /&gt;
    &lt;br /&gt;
	registerTrigger: function() {&lt;br /&gt;
		// https://developer.mozilla.org/en-US/Add-ons/SDK/Tutorials/Add_a_Context_Menu_Item&lt;br /&gt;
		// https://developer.mozilla.org/en-US/Add-ons/SDK/High-Level_APIs/context-menu#Item%28options%29&lt;br /&gt;
		var contextMenu = require(&amp;quot;sdk/context-menu&amp;quot;);&lt;br /&gt;
		var menuItem = contextMenu.Item({&lt;br /&gt;
  		label: &amp;quot;Instant Cquote&amp;quot;,&lt;br /&gt;
  		context: contextMenu.SelectionContext(),&lt;br /&gt;
      // https://developer.mozilla.org/en/Add-ons/SDK/Guides/Two_Types_of_Scripts&lt;br /&gt;
      // https://developer.mozilla.org/en-US/Add-ons/SDK/Guides/Content_Scripts&lt;br /&gt;
  		contentScript: 'self.on(&amp;quot;click&amp;quot;, function () {' +&lt;br /&gt;
                 '  var text = window.getSelection().toString();' +&lt;br /&gt;
                 '  self.postMessage(text);' +&lt;br /&gt;
                 '});',&lt;br /&gt;
  		onMessage: function (selectionText) {&lt;br /&gt;
    		console.log(selectionText);&lt;br /&gt;
        instantCquote(selectionText);&lt;br /&gt;
  		}&lt;br /&gt;
	});&lt;br /&gt;
  &lt;br /&gt;
    // for selection handling stuff, see: https://developer.mozilla.org/en-US/Add-ons/SDK/High-Level_APIs/selection&lt;br /&gt;
    &lt;br /&gt;
    function myListener() {&lt;br /&gt;
  console.log(&amp;quot;A selection has been made.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
var selection = require(&amp;quot;sdk/selection&amp;quot;);&lt;br /&gt;
selection.on('select', myListener);&lt;br /&gt;
    &lt;br /&gt;
	}, //registerTrigger&lt;br /&gt;
    &lt;br /&gt;
	get_persistent: function(key, default_value) {&lt;br /&gt;
    // https://developer.mozilla.org/en-US/Add-ons/SDK/High-Level_APIs/simple-storage&lt;br /&gt;
    var ss = require(&amp;quot;sdk/simple-storage&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    console.log(&amp;quot;firefox mode does not yet have persistence support&amp;quot;);&lt;br /&gt;
    return default_value;},&lt;br /&gt;
	set_persistent: function(key, value) {&lt;br /&gt;
		console.log(&amp;quot;firefox persistence stubs not yet filled in !&amp;quot;);&lt;br /&gt;
	},&lt;br /&gt;
    &lt;br /&gt;
  &lt;br /&gt;
	set_clipboard: function(content) {&lt;br /&gt;
	// https://developer.mozilla.org/en-US/Add-ons/SDK/High-Level_APIs/clipboard&lt;br /&gt;
    &lt;br /&gt;
	//console.log('clipboard stub not yet filled in ...');&lt;br /&gt;
    var clipboard = require(&amp;quot;sdk/clipboard&amp;quot;);&lt;br /&gt;
    clipboard.set(content);&lt;br /&gt;
	} //set_cliipboard&lt;br /&gt;
    &lt;br /&gt;
  }, // end of FireFox addon config&lt;br /&gt;
  &lt;br /&gt;
  // placeholder for now ...&lt;br /&gt;
  Android: {&lt;br /&gt;
    // NOP&lt;br /&gt;
  }, // Android&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  ///////////////////////////////////////&lt;br /&gt;
  // supported  script engines:&lt;br /&gt;
  ///////////////////////////////////////&lt;br /&gt;
  &lt;br /&gt;
  GreaseMonkey: {&lt;br /&gt;
  // TODO: move environment specific initialization code here  &lt;br /&gt;
  init: function() {&lt;br /&gt;
  // Check if Greasemonkey/Tampermonkey is available&lt;br /&gt;
  try {&lt;br /&gt;
  // TODO: add version check for clipboard API and check for TamperMonkey/Scriptish equivalents ?&lt;br /&gt;
  GM_addStyle(GM_getResourceText('jQUI_CSS'));&lt;br /&gt;
  } // try&lt;br /&gt;
  catch (error) {&lt;br /&gt;
  console.log('Could not add style or determine script version');&lt;br /&gt;
  } // catch&lt;br /&gt;
&lt;br /&gt;
  var commands = [&lt;br /&gt;
  {name:'Setup quotes',callback:setupDialog, hook:'S' },&lt;br /&gt;
  {name:'Check quotes',callback:selfCheckDialog, hook:'C' }&lt;br /&gt;
  ];&lt;br /&gt;
      &lt;br /&gt;
  for (let c of commands ) {&lt;br /&gt;
   this.registerConfigurationOption(c.name, c.callback, c.hook);&lt;br /&gt;
  }  &lt;br /&gt;
     &lt;br /&gt;
  }, // init()&lt;br /&gt;
    &lt;br /&gt;
  getScriptVersion: function() {&lt;br /&gt;
  return GM_info.script.version;  &lt;br /&gt;
  },&lt;br /&gt;
    &lt;br /&gt;
  dbLog: function (message) {&lt;br /&gt;
  if (Boolean(DEBUG)) {&lt;br /&gt;
    console.log('Instant cquotes:' + message);&lt;br /&gt;
  }&lt;br /&gt;
  }, // dbLog()&lt;br /&gt;
    &lt;br /&gt;
  registerConfigurationOption: function(name,callback,hook) {&lt;br /&gt;
  // https://wiki.greasespot.net/GM_registerMenuCommand&lt;br /&gt;
  // https://wiki.greasespot.net/Greasemonkey_Manual:Monkey_Menu#The_Menu&lt;br /&gt;
    GM_registerMenuCommand(name, callback, hook);&lt;br /&gt;
  }, //registerMenuCommand()&lt;br /&gt;
    &lt;br /&gt;
  registerTrigger: function() {&lt;br /&gt;
    &lt;br /&gt;
    // TODO: we can use the following callback non-interactively, i.e. to trigger background tasks&lt;br /&gt;
// http://javascript.info/tutorial/onload-ondomcontentloaded&lt;br /&gt;
document.addEventListener(&amp;quot;DOMContentLoaded&amp;quot;, function(event) {&lt;br /&gt;
    console.log(&amp;quot;Instant Cquotes: DOM fully loaded and parsed&amp;quot;);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
window.addEventListener('load', init); // page fully loaded&lt;br /&gt;
Host.dbLog('Instant Cquotes: page load handler registered');&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    // Initialize (matching page loaded)&lt;br /&gt;
function init() {&lt;br /&gt;
  console.log('Instant Cquotes: page load handler invoked');&lt;br /&gt;
  var profile = getProfile();&lt;br /&gt;
  &lt;br /&gt;
  Host.dbLog(&amp;quot;Profile type is:&amp;quot;+profile.type);&lt;br /&gt;
  &lt;br /&gt;
  // Dispatch to correct event handler (depending on website/URL)&lt;br /&gt;
  // TODO: this stuff could/should be moved into the config hash itself&lt;br /&gt;
  &lt;br /&gt;
  if (profile.type=='wiki') {&lt;br /&gt;
    profile.event_handler(); // just for testing&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
   &lt;br /&gt;
    Host.dbLog('using default mode');&lt;br /&gt;
    document.onmouseup = instantCquote;&lt;br /&gt;
    // HACK: preparations for moving the the event/handler logic also into the profile hash, so that the wiki (edit mode) can be handled equally&lt;br /&gt;
    //eval(profile.event+&amp;quot;=instantCquote&amp;quot;);&lt;br /&gt;
     &lt;br /&gt;
} // init()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
  }, // registerTrigger&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
   download: function (url, callback, method='GET') {&lt;br /&gt;
  // http://wiki.greasespot.net/GM_xmlhttpRequest&lt;br /&gt;
     try {&lt;br /&gt;
  GM_xmlhttpRequest({&lt;br /&gt;
    method: method,&lt;br /&gt;
    url: url,&lt;br /&gt;
    onload: callback&lt;br /&gt;
  });&lt;br /&gt;
     }catch(e) {&lt;br /&gt;
       console.log(&amp;quot;download did not work&amp;quot;);&lt;br /&gt;
     }&lt;br /&gt;
  }, // download()&lt;br /&gt;
    &lt;br /&gt;
    // is only intended to work with archives supported by the  hash&lt;br /&gt;
    downloadPosting: function (url, EventHandler) {&lt;br /&gt;
      &lt;br /&gt;
    Host.download(url, function (response) {&lt;br /&gt;
    var profile = getProfile(url);&lt;br /&gt;
    var blob = response.responseText;&lt;br /&gt;
    var doc = Host.make_doc(blob,'text/html'); &lt;br /&gt;
    var result = {}; // hash to be returned&lt;br /&gt;
    &lt;br /&gt;
    [].forEach.call(['author','date','title','content'], function(field) {&lt;br /&gt;
      var xpath_query = '//' + profile[field].xpath;&lt;br /&gt;
      try {&lt;br /&gt;
       var value = Host.eval_xpath(doc, xpath_query).stringValue; &lt;br /&gt;
       //UI.alert(&amp;quot;extracted field value:&amp;quot;+value);&lt;br /&gt;
        &lt;br /&gt;
        // now apply all transformations, if any&lt;br /&gt;
       value = applyTransformations(value, profile[field].transform );&lt;br /&gt;
        &lt;br /&gt;
       result[field]=value; // store the extracted/transormed value in the hash that we pass on&lt;br /&gt;
      } // try&lt;br /&gt;
      catch(e) {&lt;br /&gt;
        UI.alert(&amp;quot;downloadPosting failed:\n&amp;quot;+ e.message);&lt;br /&gt;
      } // catch&lt;br /&gt;
    }); // forEach field&lt;br /&gt;
    &lt;br /&gt;
    EventHandler(result); // pass the result to the handler&lt;br /&gt;
    }); // call to Host.download() &lt;br /&gt;
      &lt;br /&gt;
    }, // downloadPosting()&lt;br /&gt;
    &lt;br /&gt;
    // TODO: add makeAJAXCall, and makeWikiCall here&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
    // turn a string/text blob into a DOM tree that can be queried (e.g. for xpath expressions)&lt;br /&gt;
    // FIXME: this is browser specific not GM specific ...&lt;br /&gt;
    make_doc: function(text, type='text/html') {&lt;br /&gt;
      // to support other browsers, see: https://developer.mozilla.org/en/docs/Web/API/DOMParser&lt;br /&gt;
      return new DOMParser().parseFromString(text,type);&lt;br /&gt;
    }, // make DOM document&lt;br /&gt;
    &lt;br /&gt;
    // xpath handling may be handled separately depending on browser/platform, so better encapsulate this&lt;br /&gt;
    // FIXME: this is browser specific not GM specific ...&lt;br /&gt;
    eval_xpath: function(doc, xpath, type=XPathResult.STRING_TYPE) {&lt;br /&gt;
      return doc.evaluate(xpath, doc, null, type, null);&lt;br /&gt;
    }, // eval_xpath&lt;br /&gt;
    &lt;br /&gt;
    set_persistent: function(key, value, json=false) &lt;br /&gt;
    {&lt;br /&gt;
      // transparently stringify to json&lt;br /&gt;
      if(json) {&lt;br /&gt;
        // http://stackoverflow.com/questions/16682150/store-a-persistent-list-between-sessions&lt;br /&gt;
        value = JSON.stringify (value);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      // https://wiki.greasespot.net/GM_setValue&lt;br /&gt;
      GM_setValue(key, value);&lt;br /&gt;
      //UI.alert('Saved value for key\n'+key+':'+value);&lt;br /&gt;
    }, // set_persistent&lt;br /&gt;
    &lt;br /&gt;
    get_persistent: function(key, default_value, json=false) {&lt;br /&gt;
     // https://wiki.greasespot.net/GM_getValue&lt;br /&gt;
    &lt;br /&gt;
      var value=GM_getValue(key, default_value);&lt;br /&gt;
      // transparently support JSON: http://stackoverflow.com/questions/16682150/store-a-persistent-list-between-sessions&lt;br /&gt;
      if(json) {&lt;br /&gt;
        value = JSON.parse (value)  ||  {};&lt;br /&gt;
      }&lt;br /&gt;
      return value;&lt;br /&gt;
    }, // get_persistent&lt;br /&gt;
&lt;br /&gt;
   setClipboard: function(msg) {&lt;br /&gt;
   // this being a greasemonkey user-script, we are not &lt;br /&gt;
   // subject to usual browser restrictions&lt;br /&gt;
   // http://wiki.greasespot.net/GM_setClipboard&lt;br /&gt;
   GM_setClipboard(msg);&lt;br /&gt;
  }, // setClipboard()&lt;br /&gt;
    &lt;br /&gt;
    getTemplate: function() {&lt;br /&gt;
    &lt;br /&gt;
    // hard-coded default template&lt;br /&gt;
    var template = '$CONTENT&amp;lt;ref&amp;gt;{{cite web\n' +&lt;br /&gt;
  '  |url    =  $URL \n' +&lt;br /&gt;
  '  |title  =  &amp;lt;nowiki&amp;gt; $TITLE &amp;lt;/nowiki&amp;gt; \n' +&lt;br /&gt;
  '  |author =  &amp;lt;nowiki&amp;gt; $AUTHOR &amp;lt;/nowiki&amp;gt; \n' +&lt;br /&gt;
  '  |date   =  $DATE \n' +&lt;br /&gt;
  '  |added  =  $ADDED \n' +&lt;br /&gt;
  '  |script_version = $SCRIPT_VERSION \n' +&lt;br /&gt;
  '  }}&amp;lt;/ref&amp;gt;\n';&lt;br /&gt;
     &lt;br /&gt;
    // return a saved template if found, fall back to hard-coded one above otherwise&lt;br /&gt;
    return Host.get_persistent('default_template', template);&lt;br /&gt;
    &lt;br /&gt;
  } // getTemplate&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
  } // end of GreaseMonkey environment, add other environments below&lt;br /&gt;
  &lt;br /&gt;
}; // Environment hash - intended to help encapsulate host specific stuff (APIs)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// the first thing we need to do is to determine what APIs are available&lt;br /&gt;
// and store everything in a Host hash, which is subsequently used for API lookups&lt;br /&gt;
// the Host hash contains all platform/browser-specific APIs&lt;br /&gt;
var Host = Environment.getHost();&lt;br /&gt;
Environment.validate(Host); // this checks the obtained host to see if all required dependencies are available&lt;br /&gt;
Host.init(); // run environment specific initialization code (e.g. logic for GreaseMonkey setup)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// move DEBUG handling to a persistent configuration flag so that we can configure this using a jQuery dialog (defaulted to false)&lt;br /&gt;
// TODO: move DEBUG variable to Environment hash / init() routine&lt;br /&gt;
var DEBUG = Host.get_persistent('debug_mode_enabled', false);&lt;br /&gt;
Host.dbLog(&amp;quot;Debug mode is:&amp;quot;+DEBUG);&lt;br /&gt;
function DEBUG_mode() {&lt;br /&gt;
  // reset script invocation counter for testing purposes&lt;br /&gt;
  Host.dbLog('Resetting script invocation counter');&lt;br /&gt;
  Host.set_persistent(GM_info.script.version, 0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if (DEBUG)&lt;br /&gt;
DEBUG_mode();&lt;br /&gt;
&lt;br /&gt;
// hash with supported websites/URLs,  includes xpath and regex expressions to extract certain fields, and a vector with optional transformations for post-processing each field&lt;br /&gt;
&lt;br /&gt;
var CONFIG = {&lt;br /&gt;
  // WIP: the first entry is special, i.e. it's not an actual list archive (source), but only added here so that the same script can be used&lt;br /&gt;
  // for editing the FlightGear wiki&lt;br /&gt;
  &lt;br /&gt;
  'FlightGear.wiki': {&lt;br /&gt;
    type: 'wiki',&lt;br /&gt;
    enabled: false,&lt;br /&gt;
    event: 'document.onmouseup', // when to invoke the event handler&lt;br /&gt;
    // TODO: move downloadWatchlist() etc here&lt;br /&gt;
    event_handler: function () {&lt;br /&gt;
      console.log('FlightGear wiki handler active (waiting to be populated)');&lt;br /&gt;
      // this is where the logic for a wiki mode can be added over time (for now, it's a NOP)&lt;br /&gt;
    &lt;br /&gt;
    //for each supported mode, invoke the trigger and call the corresponding handler&lt;br /&gt;
    [].forEach.call(CONFIG['FlightGear.wiki'].modes, function(mode) {&lt;br /&gt;
      //dbLog(&amp;quot;Checking trigger:&amp;quot;+mode.name);&lt;br /&gt;
      if(mode.trigger() ) {&lt;br /&gt;
        mode.handler();&lt;br /&gt;
      }&lt;br /&gt;
    });&lt;br /&gt;
      &lt;br /&gt;
    }, // the event handler to be invoked&lt;br /&gt;
    url_reg: '^(http|https)://wiki.flightgear.org', // ignore for now: not currently used by the wiki mode&lt;br /&gt;
    &lt;br /&gt;
    modes: [&lt;br /&gt;
      { name:'process-editSections',&lt;br /&gt;
        trigger: function() {return true;}, // match URL regex - return true for always match&lt;br /&gt;
       &lt;br /&gt;
        // the code implementing the mode&lt;br /&gt;
        handler: function() {&lt;br /&gt;
                &lt;br /&gt;
    var editSections = document.getElementsByClassName('mw-editsection');&lt;br /&gt;
    console.log('FlightGear wiki article, number of edit sections: '+editSections.length);&lt;br /&gt;
   &lt;br /&gt;
    // for now, just rewrite edit sections and add a note to them&lt;br /&gt;
   &lt;br /&gt;
     [].forEach.call(editSections, function (sec) {&lt;br /&gt;
       sec.appendChild(&lt;br /&gt;
         document.createTextNode(' (instant-cquotes is lurking) ')&lt;br /&gt;
       );&lt;br /&gt;
     }); //forEach section&lt;br /&gt;
        } // handler&lt;br /&gt;
       &lt;br /&gt;
       &lt;br /&gt;
      } // process-editSections&lt;br /&gt;
      // TODO: add other wiki modes below &lt;br /&gt;
      &lt;br /&gt;
    ] // modes&lt;br /&gt;
    &lt;br /&gt;
  }, // end of wiki profile&lt;br /&gt;
  &lt;br /&gt;
  'Sourceforge Mailing list': {&lt;br /&gt;
    enabled: true,&lt;br /&gt;
    type: 'archive',&lt;br /&gt;
    event: 'document.onmouseup', // when to invoke the event handler&lt;br /&gt;
    event_handler: instantCquote, // the event handler to be invoked&lt;br /&gt;
    url_reg: '^(http|https)://sourceforge.net/p/flightgear/mailman/.*/',&lt;br /&gt;
    content: {&lt;br /&gt;
      xpath: 'tbody/tr[2]/td/pre/text()', // NOTE this is only used by the downloadPosting  helper to retrieve the posting without having a selection (TODO:add content xpath to forum hash)&lt;br /&gt;
      selection: getSelectedText,&lt;br /&gt;
      idStyle: /msg[0-9]{8}/,&lt;br /&gt;
      parentTag: [&lt;br /&gt;
        'tagName',&lt;br /&gt;
        'PRE'&lt;br /&gt;
      ],&lt;br /&gt;
      transform: [],&lt;br /&gt;
    }, // content recipe&lt;br /&gt;
    // vector with tests to be executed for sanity checks (unit testing)&lt;br /&gt;
    tests: [&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://sourceforge.net/p/flightgear/mailman/message/35059454/',&lt;br /&gt;
        author: 'Erik Hofman',&lt;br /&gt;
        date: 'May 3rd, 2016', // NOTE: using the transformed date here &lt;br /&gt;
        title: 'Re: [Flightgear-devel] Auto altimeter setting at startup (?)'&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://sourceforge.net/p/flightgear/mailman/message/35059961/',&lt;br /&gt;
        author: 'Ludovic Brenta',&lt;br /&gt;
        date: 'May 3rd, 2016',&lt;br /&gt;
        title: 'Re: [Flightgear-devel] dual-control-tools and the limit on packet size'&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://sourceforge.net/p/flightgear/mailman/message/20014126/',&lt;br /&gt;
        author: 'Tim Moore',&lt;br /&gt;
        date: 'Aug 4th, 2008',&lt;br /&gt;
        title: 'Re: [Flightgear-devel] Cockpit displays (rendering, modelling)'&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://sourceforge.net/p/flightgear/mailman/message/23518343/',&lt;br /&gt;
        author: 'Tim Moore',&lt;br /&gt;
        date: 'Sep 10th, 2009',&lt;br /&gt;
        title: '[Flightgear-devel] Atmosphere patch from John Denker'&lt;br /&gt;
      } // add other tests below&lt;br /&gt;
&lt;br /&gt;
    ], // end of vector with self-tests&lt;br /&gt;
    // regex/xpath and transformations for extracting various required fields&lt;br /&gt;
    author: {&lt;br /&gt;
      xpath: 'tbody/tr[1]/td/div/small/text()',&lt;br /&gt;
      transform: [extract(/From: (.*) &amp;lt;.*@.*&amp;gt;/)]&lt;br /&gt;
    },&lt;br /&gt;
    title: {&lt;br /&gt;
      xpath: 'tbody/tr[1]/td/div/div[1]/b/a/text()',&lt;br /&gt;
      transform:[]&lt;br /&gt;
    },&lt;br /&gt;
    date: {&lt;br /&gt;
      xpath: 'tbody/tr[1]/td/div/small/text()',&lt;br /&gt;
      transform: [extract(/- (.*-.*-.*) /)]&lt;br /&gt;
    },&lt;br /&gt;
    url: {&lt;br /&gt;
      xpath: 'tbody/tr[1]/td/div/div[1]/b/a/@href',&lt;br /&gt;
      transform: [prepend('https://sourceforge.net')]&lt;br /&gt;
    }&lt;br /&gt;
  }, // end of mailing list profile&lt;br /&gt;
  // next website/URL (forum)&lt;br /&gt;
  'FlightGear forum': {&lt;br /&gt;
    enabled: true,&lt;br /&gt;
    type: 'archive',&lt;br /&gt;
    event: 'document.onmouseup', // when to invoke the event handler (not used atm)&lt;br /&gt;
    event_handler: null, // the event handler to be invoked (not used atm)&lt;br /&gt;
    url_reg: /https:\/\/forum\.flightgear\.org\/.*/,&lt;br /&gt;
    content: {&lt;br /&gt;
      xpath: '', //TODO: this must be added for downloadPosting() to work, or it cannot extract contents&lt;br /&gt;
      selection: getSelectedHtml,&lt;br /&gt;
      idStyle: /p[0-9]{6}/,&lt;br /&gt;
      parentTag: [&lt;br /&gt;
        'className',&lt;br /&gt;
        'content',&lt;br /&gt;
        'postbody'&lt;br /&gt;
      ],&lt;br /&gt;
      transform: [&lt;br /&gt;
        removeComments,&lt;br /&gt;
        forum_quote2cquote,&lt;br /&gt;
        forum_smilies2text,&lt;br /&gt;
        forum_fontstyle2wikistyle,&lt;br /&gt;
        forum_code2syntaxhighlight,&lt;br /&gt;
        img2link,&lt;br /&gt;
        a2wikilink,&lt;br /&gt;
        vid2wiki,&lt;br /&gt;
        list2wiki,&lt;br /&gt;
        forum_br2newline&lt;br /&gt;
      ]&lt;br /&gt;
    },&lt;br /&gt;
    // vector with tests to be executed for sanity checks (unit testing)&lt;br /&gt;
    // postings will be downloaded using the URL specified, and then the author/title &lt;br /&gt;
    // fields extracted using the outer regex and matched against what is expected&lt;br /&gt;
    // NOTE: forum postings can be edited, so that these tests would fail - thus, it makes sense to pick locked topics/postings for such tests&lt;br /&gt;
    tests: [&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://forum.flightgear.org/viewtopic.php?f=18&amp;amp;p=284108#p284108',&lt;br /&gt;
        author: 'mickybadia',&lt;br /&gt;
        date: 'May 3rd, 2016',&lt;br /&gt;
        title: 'OSM still PNG maps'&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://forum.flightgear.org/viewtopic.php?f=19&amp;amp;p=284120#p284120',&lt;br /&gt;
        author: 'Thorsten',&lt;br /&gt;
        date: 'May 3rd, 2016',&lt;br /&gt;
        title: 'Re: FlightGear\'s Screenshot Of The Month MAY 2016'&lt;br /&gt;
      },&lt;br /&gt;
       {&lt;br /&gt;
        url: 'https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;t=29279&amp;amp;p=283455#p283446',&lt;br /&gt;
        author: 'Hooray',&lt;br /&gt;
         date: 'Apr 25th, 2016',&lt;br /&gt;
        title: 'Re: Best way to learn Canvas?'&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://forum.flightgear.org/viewtopic.php?f=4&amp;amp;t=1460&amp;amp;p=283994#p283994',&lt;br /&gt;
        author: 'bugman',&lt;br /&gt;
        date: 'May 2nd, 2016',&lt;br /&gt;
        title: 'Re: eurofighter typhoon'&lt;br /&gt;
      } // add other tests below&lt;br /&gt;
&lt;br /&gt;
    ], // end of vector with self-tests&lt;br /&gt;
    author: {&lt;br /&gt;
      xpath: 'div/div[1]/p/strong/a/text()',&lt;br /&gt;
      transform: [] // no transformations applied&lt;br /&gt;
    },&lt;br /&gt;
    title: {&lt;br /&gt;
      xpath: 'div/div[1]/h3/a/text()',&lt;br /&gt;
      transform: [] // no transformations applied&lt;br /&gt;
    },&lt;br /&gt;
    date: {&lt;br /&gt;
      xpath: 'div/div[1]/p/text()[2]',&lt;br /&gt;
      transform: [extract(/» (.*?[0-9]{4})/)]&lt;br /&gt;
    },&lt;br /&gt;
    url: {&lt;br /&gt;
      xpath: 'div/div[1]/p/a/@href',&lt;br /&gt;
      transform: [&lt;br /&gt;
        extract(/\.(.*)/),&lt;br /&gt;
        prepend('https://forum.flightgear.org')&lt;br /&gt;
      ] // transform vector&lt;br /&gt;
    } // url&lt;br /&gt;
  } // forum &lt;br /&gt;
}; // CONFIG has&lt;br /&gt;
&lt;br /&gt;
// hash to map URLs (wiki article, issue tracker, sourceforge link, forum thread etc) to existing wiki templates&lt;br /&gt;
var MatchURL2Templates = [&lt;br /&gt;
  // placeholder for now&lt;br /&gt;
 {&lt;br /&gt;
   name: 'rewrite sourceforge code links',&lt;br /&gt;
   url_reg: '',&lt;br /&gt;
   handler: function() {&lt;br /&gt;
   &lt;br /&gt;
 } // handler&lt;br /&gt;
  &lt;br /&gt;
 } // add other templates below&lt;br /&gt;
  &lt;br /&gt;
]; // MatchURL2Templates&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// output methods (alert and jQuery for now)&lt;br /&gt;
var OUTPUT = {&lt;br /&gt;
  // Shows a window.prompt() message box&lt;br /&gt;
  msgbox: function (msg) {&lt;br /&gt;
    UI.prompt('Copy to clipboard ' + Host.getScriptVersion(), msg);&lt;br /&gt;
    Host.setClipboard(msg);&lt;br /&gt;
  }, // msgbox&lt;br /&gt;
  &lt;br /&gt;
  // this is currently work-in-progress, and will need to be refactored sooner or later&lt;br /&gt;
  // for now, functionality matters more than elegant design/code :)&lt;br /&gt;
  jQueryTabbed: function(msg, original) {&lt;br /&gt;
  // FIXME: using backtics here makes the whole thing require ES6  ....&lt;br /&gt;
  var markup = $(`&amp;lt;div id=&amp;quot;tabs&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;ul&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#selection&amp;quot;&amp;gt;Selection&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#articles&amp;quot;&amp;gt;Articles&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#templates&amp;quot;&amp;gt;Templates&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#development&amp;quot;&amp;gt;Development&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#settings&amp;quot;&amp;gt;Settings&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#help&amp;quot;&amp;gt;Help&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#about&amp;quot;&amp;gt;About&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;/ul&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;selection&amp;quot;&amp;gt;This tab contains your extracted and post-processed selection, converted to proper wikimedia markup, including proper attribution.&lt;br /&gt;
  &amp;lt;div id=&amp;quot;content&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;label for=&amp;quot;template_select&amp;quot;&amp;gt;Select a template&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;select name=&amp;quot;template_select&amp;quot; id=&amp;quot;template_select&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;option&amp;gt;default&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option&amp;gt;cquote&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;/select&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;options&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Note this is work-in-progress, i.e. not yet fully functional&amp;lt;/b&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
    &amp;lt;label for=&amp;quot;article_select&amp;quot;&amp;gt;Select an article to update&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;select name=&amp;quot;article_select&amp;quot; id=&amp;quot;article_select&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;news&amp;quot; label=&amp;quot;News&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;support&amp;quot; label=&amp;quot;Support&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;release&amp;quot; label=&amp;quot;Release&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;develop&amp;quot; label=&amp;quot;Development&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;watchlist&amp;quot; label=&amp;quot;Watchlist&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;/select&amp;gt;&lt;br /&gt;
    &amp;lt;p/&amp;gt;&lt;br /&gt;
    &amp;lt;label for=&amp;quot;section_select&amp;quot;&amp;gt;Select section:&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;select name=&amp;quot;section_select&amp;quot; id=&amp;quot;section_select&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;/select&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;articles&amp;quot;&amp;gt;This tab contains articles that you can directly access/edit using the mediawiki API&amp;lt;br/&amp;gt;&lt;br /&gt;
  Note: The watchlist is retrieved dynamically, so does not need to be edited here&amp;lt;br/&amp;gt;&lt;br /&gt;
    &amp;lt;label for=&amp;quot;article_select&amp;quot;&amp;gt;Select an article&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;select name=&amp;quot;article_select&amp;quot; id=&amp;quot;article_select&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;news&amp;quot; label=&amp;quot;News&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;support&amp;quot; label=&amp;quot;Support&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;develop&amp;quot; label=&amp;quot;Development&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;release&amp;quot; label=&amp;quot;Release&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;!-- the watchlist is retrieved dynamically, so omit it here &lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;watchlist&amp;quot; label=&amp;quot;Watchlist&amp;quot;/&amp;gt;&lt;br /&gt;
    --&amp;gt;&lt;br /&gt;
    &amp;lt;/select&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;button id=&amp;quot;article_new&amp;quot;&amp;gt;New&amp;lt;/button&amp;gt;&lt;br /&gt;
   &amp;lt;button id=&amp;quot;article_remove&amp;quot;&amp;gt;Remove&amp;lt;/button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div id=&amp;quot;edit_article&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;label for=&amp;quot;article_name&amp;quot;&amp;gt;Article&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;text&amp;quot; id=&amp;quot;article_name&amp;quot; name=&amp;quot;article_name&amp;quot;&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;label for=&amp;quot;article_url&amp;quot;&amp;gt;Link&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;text&amp;quot; id=&amp;quot;article_url&amp;quot; name=&amp;quot;article_url&amp;quot;&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;button id=&amp;quot;article_save&amp;quot;&amp;gt;Save&amp;lt;/button&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;templates&amp;quot;&amp;gt;This tab contains templates for different types of articles (newsletter, changelog, release plan etc)&amp;lt;p/&amp;gt;&lt;br /&gt;
  For now, this is WIP - in the future, there will be a dropdown menu added and all templates will be editable.&amp;lt;p/&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;template_header&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;label for=&amp;quot;template_select&amp;quot;&amp;gt;Select a template&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;select name=&amp;quot;template_select&amp;quot; id=&amp;quot;template_select&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;option&amp;gt;default&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option&amp;gt;cquote&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;/select&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;template_area&amp;quot;/&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;template_controls&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;button id=&amp;quot;template_save&amp;quot;&amp;gt;Save&amp;lt;/button&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;development&amp;quot;&amp;gt;This tab is a placeholder for features currently under development&amp;lt;p/&amp;gt;&lt;br /&gt;
  &amp;lt;button id=&amp;quot;evolve_regex&amp;quot;&amp;gt;Evolve regex&amp;lt;/button&amp;gt;&amp;lt;p/&amp;gt;&lt;br /&gt;
  &amp;lt;button id=&amp;quot;test_perceptron&amp;quot;&amp;gt;Test Perceptron&amp;lt;/button&amp;gt;&amp;lt;p/&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;output&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table id=&amp;quot;results&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;thead&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
     &amp;lt;th&amp;gt;Generation&amp;lt;/th&amp;gt;&lt;br /&gt;
     &amp;lt;th&amp;gt;Fitness&amp;lt;/th&amp;gt;&lt;br /&gt;
     &amp;lt;th&amp;gt;Expression&amp;lt;/th&amp;gt;&lt;br /&gt;
     &amp;lt;th&amp;gt;Result&amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
  &amp;lt;/thead&amp;gt;&lt;br /&gt;
  &amp;lt;tbody&amp;gt;&lt;br /&gt;
  &amp;lt;/tbody&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt; &lt;br /&gt;
&lt;br /&gt;
   &amp;lt;!--&lt;br /&gt;
   &amp;lt;textarea id=&amp;quot;devel_output&amp;quot; lines=&amp;quot;10&amp;quot;&amp;gt;&amp;lt;/textarea&amp;gt;&amp;lt;p/&amp;gt;&lt;br /&gt;
  --&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div id=&amp;quot;settings&amp;quot;&amp;gt;This tab will contain script specific settings&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;help&amp;quot;&amp;gt;One day, this tab may contain help....&amp;lt;p/&amp;gt;&amp;lt;button id=&amp;quot;helpButton&amp;quot;&amp;gt;Instant Cquotes&amp;lt;/button&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;about&amp;quot;&amp;gt;show some  script related information here&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;`); // tabs div&lt;br /&gt;
    &lt;br /&gt;
   var evolve_regex = $('div#development button#evolve_regex', markup);&lt;br /&gt;
   evolve_regex.click(function() {&lt;br /&gt;
     //alert(&amp;quot;Evolve regex&amp;quot;);&lt;br /&gt;
     evolve_expression_test();&lt;br /&gt;
   });&lt;br /&gt;
    &lt;br /&gt;
   var test_perceptron = $('div#development button#test_perceptron', markup);&lt;br /&gt;
   test_perceptron.click(function() {&lt;br /&gt;
     alert(&amp;quot;Test perceptron&amp;quot;);&lt;br /&gt;
   });&lt;br /&gt;
   &lt;br /&gt;
    &lt;br /&gt;
    // add dynamic elements to each tab&lt;br /&gt;
    &lt;br /&gt;
   // NOTE: this affects all template selectors, on all tabs&lt;br /&gt;
   $('select#template_select', markup).change(function() {&lt;br /&gt;
     UI.alert(&amp;quot;Sorry, templates are not yet fully implemented (WIP)&amp;quot;);&lt;br /&gt;
   });&lt;br /&gt;
    &lt;br /&gt;
   var help = $('#helpButton', markup);&lt;br /&gt;
   help.button();&lt;br /&gt;
   help.click(function() {&lt;br /&gt;
     window.open(&amp;quot;http://wiki.flightgear.org/FlightGear_wiki:Instant-Cquotes&amp;quot;);&lt;br /&gt;
   });&lt;br /&gt;
    &lt;br /&gt;
   // rows=&amp;quot;10&amp;quot;cols=&amp;quot;80&amp;quot; style=&amp;quot; width: 420px; height: 350px&amp;quot;&lt;br /&gt;
   var textarea = $('&amp;lt;textarea id=&amp;quot;quotedtext&amp;quot; rows=&amp;quot;20&amp;quot; cols=&amp;quot;70&amp;quot;/&amp;gt;');&lt;br /&gt;
   textarea.val(msg);&lt;br /&gt;
   $('#selection #content', markup).append(textarea);&lt;br /&gt;
  &lt;br /&gt;
   var templateArea = $('&amp;lt;textarea id=&amp;quot;template-edit&amp;quot; rows=&amp;quot;20&amp;quot; cols=&amp;quot;70&amp;quot;/&amp;gt;');&lt;br /&gt;
   templateArea.val( Host.getTemplate() );&lt;br /&gt;
   $('div#templates div#template_area', markup).append(templateArea);&lt;br /&gt;
   &lt;br /&gt;
   //$('#templates', markup).append($('&amp;lt;button&amp;gt;'));&lt;br /&gt;
    $('div#templates div#template_controls button#template_save',markup).button().click(function() {&lt;br /&gt;
      //UI.alert(&amp;quot;Saving template:\n&amp;quot;+templateArea.val() );&lt;br /&gt;
      &lt;br /&gt;
      Host.set_persistent('default_template',templateArea.val() );&lt;br /&gt;
    }); // save template&lt;br /&gt;
    &lt;br /&gt;
  // TODO: Currently, this is hard-coded, but should be made customizable via the &amp;quot;articles&amp;quot; tab at some point ...&lt;br /&gt;
  var articles = [&lt;br /&gt;
    // NOTE: category must match an existing &amp;lt;optgroup&amp;gt; above, title must match an existing wiki article&lt;br /&gt;
    {category:'support', name:'Frequently asked questions', url:''},&lt;br /&gt;
    {category:'support', name:'Asking for help', url:''},&lt;br /&gt;
    {category:'news', name:'Next newsletter', url:''},&lt;br /&gt;
    {category:'news', name:'Next changelog', url:''},&lt;br /&gt;
    {category:'release', name:'Release plan/Lessons learned', url:''}, // TODO: use wikimedia template&lt;br /&gt;
    {category:'develop', name:'Nasal library', url:''},&lt;br /&gt;
    {category:'develop', name:'Canvas Snippets', url:''},&lt;br /&gt;
    &lt;br /&gt;
  ];&lt;br /&gt;
    &lt;br /&gt;
    // TODO: this should be moved elsewhere&lt;br /&gt;
    function updateArticleList(selector) {&lt;br /&gt;
    $.each(articles, function (i, article) {&lt;br /&gt;
    $(selector+ ' optgroup#'+article.category, markup).append($('&amp;lt;option&amp;gt;', { &lt;br /&gt;
        value: article.name, // FIXME: just a placeholder for now&lt;br /&gt;
        text : article.name &lt;br /&gt;
    })); //append option&lt;br /&gt;
   }); // foreach&lt;br /&gt;
    } // updateArticleList&lt;br /&gt;
    &lt;br /&gt;
    // add the article list to the corresponding dropdown menus&lt;br /&gt;
    updateArticleList('select#article_select');&lt;br /&gt;
        &lt;br /&gt;
    // populate watchlist (prototype for now)&lt;br /&gt;
    // TODO: generalize &amp;amp; refactor: url, format&lt;br /&gt;
      &lt;br /&gt;
    // https://www.mediawiki.org/wiki/API:Watchlist&lt;br /&gt;
    // http://wiki.flightgear.org/api.php?action=query&amp;amp;list=watchlist&lt;br /&gt;
      var watchlist_url = 'http://wiki.flightgear.org/api.php?action=query&amp;amp;list=watchlist&amp;amp;format=json';&lt;br /&gt;
      Host.download(watchlist_url, function(response) {&lt;br /&gt;
        try {&lt;br /&gt;
       var watchlist = JSON.parse(response.responseText);&lt;br /&gt;
            &lt;br /&gt;
       //$('div#options select#section_select', markup).empty(); // delete all sections&lt;br /&gt;
      &lt;br /&gt;
      $.each(watchlist.query.watchlist, function (i, article) {&lt;br /&gt;
      $('div#options select#article_select optgroup#watchlist', markup).append($('&amp;lt;option&amp;gt;', { &lt;br /&gt;
        value: article.title, //FIXME just a placeholder for now&lt;br /&gt;
        text : article.title &lt;br /&gt;
    }));&lt;br /&gt;
   }); //foreach section&lt;br /&gt;
&lt;br /&gt;
        }&lt;br /&gt;
        catch (e) {&lt;br /&gt;
          UI.alert(&amp;quot;Could not download wiki watchlist\n&amp;quot;+watchlist.error.info);&lt;br /&gt;
        }&lt;br /&gt;
      }); // download &amp;amp; populate watchlist&lt;br /&gt;
      &lt;br /&gt;
    &lt;br /&gt;
    // register an event handler for the main tab, so that article specific sections can be retrieved&lt;br /&gt;
    $('div#options select#article_select', markup).change(function() {&lt;br /&gt;
      var article = this.value;&lt;br /&gt;
      &lt;br /&gt;
    // HACK: try to get a login token (actually not needed just for reading ...)&lt;br /&gt;
    Host.download('http://wiki.flightgear.org/api.php?action=query&amp;amp;prop=info|revisions&amp;amp;intoken=edit&amp;amp;rvprop=timestamp&amp;amp;titles=Main%20Page', function (response) {&lt;br /&gt;
    var message = 'FlightGear wiki login status (AJAX):';&lt;br /&gt;
    var status = response.statusText;&lt;br /&gt;
    &lt;br /&gt;
    // populate dropdown menu with article sections&lt;br /&gt;
    if (status === 'OK') {&lt;br /&gt;
    &lt;br /&gt;
      // Resolve redirects: https://www.mediawiki.org/wiki/API:Query#Resolving_redirects&lt;br /&gt;
      var section_url = 'http://wiki.flightgear.org/api.php?action=parse&amp;amp;page='+encodeURIComponent(article)+'&amp;amp;prop=sections&amp;amp;format=json&amp;amp;redirects';&lt;br /&gt;
      Host.download(section_url, function(response) {&lt;br /&gt;
        try {&lt;br /&gt;
       var sections = JSON.parse(response.responseText);&lt;br /&gt;
            &lt;br /&gt;
       $('div#options select#section_select', markup).empty(); // delete all sections&lt;br /&gt;
      &lt;br /&gt;
      $.each(sections.parse.sections, function (i, section) {&lt;br /&gt;
      $('div#options select#section_select', markup).append($('&amp;lt;option&amp;gt;', { &lt;br /&gt;
        value: section.line, //FIXME just a placeholder for now&lt;br /&gt;
        text : section.line &lt;br /&gt;
    }));&lt;br /&gt;
   }); //foreach section&lt;br /&gt;
&lt;br /&gt;
        }&lt;br /&gt;
        catch (e) {&lt;br /&gt;
          UI.alert(e.message);&lt;br /&gt;
        }&lt;br /&gt;
             &lt;br /&gt;
      }); //download sections&lt;br /&gt;
     &lt;br /&gt;
      &lt;br /&gt;
      &lt;br /&gt;
    } // login status is OK&lt;br /&gt;
&lt;br /&gt;
      &lt;br /&gt;
  }); // Host.download() call, i.e. we have a login token&lt;br /&gt;
      &lt;br /&gt;
    }); // on select change&lt;br /&gt;
    &lt;br /&gt;
  // init the tab stuff&lt;br /&gt;
  markup.tabs();&lt;br /&gt;
  &lt;br /&gt;
  var diagParam = {&lt;br /&gt;
      title: 'Instant Cquotes ' + Host.getScriptVersion(),&lt;br /&gt;
      modal: true,&lt;br /&gt;
      width: 700,&lt;br /&gt;
      buttons: [&lt;br /&gt;
        {&lt;br /&gt;
          text:'reported speech',&lt;br /&gt;
          click: function() {&lt;br /&gt;
            textarea.val(createCquote(original,true));&lt;br /&gt;
          }&lt;br /&gt;
        },&lt;br /&gt;
        &lt;br /&gt;
        {&lt;br /&gt;
          text: 'Copy',&lt;br /&gt;
          click: function () {&lt;br /&gt;
            Host.setClipboard(msg);&lt;br /&gt;
            $(this).dialog('close');&lt;br /&gt;
          }&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
      ]&lt;br /&gt;
  };&lt;br /&gt;
    &lt;br /&gt;
  // actually show our tabbed dialog using the params above&lt;br /&gt;
  markup.dialog(diagParam);&lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
  } // jQueryTabbed() &lt;br /&gt;
  &lt;br /&gt;
}; // output methods&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// TODO: we can use an online API to  help with some of this: http://www.eslnow.org/reported-speech-converter/&lt;br /&gt;
// See also: http://blog.mashape.com/list-of-25-natural-language-processing-apis/&lt;br /&gt;
// http://text-processing.com/docs/phrases.html&lt;br /&gt;
// http://www.alchemyapi.com/&lt;br /&gt;
// https://words.bighugelabs.com/api.php&lt;br /&gt;
// https://www.wordsapi.com/&lt;br /&gt;
// http://www.dictionaryapi.com/&lt;br /&gt;
// https://www.textrazor.com/&lt;br /&gt;
// http://www.programmableweb.com/news/how-5-natural-language-processing-apis-stack/analysis/2014/07/28&lt;br /&gt;
&lt;br /&gt;
var speechTransformations = [&lt;br /&gt;
// TODO: support aliasing using vectors: would/should &lt;br /&gt;
// ordering is crucial here (most specific first, least specific/most generic last)&lt;br /&gt;
 &lt;br /&gt;
// first, we start off  by expanding short forms: http://www.learnenglish.de/grammar/shortforms.html&lt;br /&gt;
// http://www.macmillandictionary.com/thesaurus-category/british/short-forms&lt;br /&gt;
 &lt;br /&gt;
  {query:/couldn\'t/gi, replacement:'could not'},&lt;br /&gt;
  {query:/I could not/gi, replacement:'$author could not'},&lt;br /&gt;
  &lt;br /&gt;
  {query:/I\'m/gi, replacement:'I am'},&lt;br /&gt;
  {query:/I am/gi, replacement:'$author is'},&lt;br /&gt;
  &lt;br /&gt;
  {query:/I\'ve/, replacement:'I have'},&lt;br /&gt;
  {query:/I have had/, replacement:'$author had'},&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  {query:/can(\'|\’)t/gi, replacement:'cannot'},&lt;br /&gt;
  &lt;br /&gt;
  {query:/I(\'|\’)ll/gi, replacement:'$author will'},&lt;br /&gt;
  {query:/I(\'|\’)d/gi, replacement:'$author would'},&lt;br /&gt;
  &lt;br /&gt;
  {query:/I have done/gi, replacement:'$author has done'},&lt;br /&gt;
  {query:/I\'ve done/gi, replacement:'$author has done'}, //FIXME. queries should really be vectors ...&lt;br /&gt;
  &lt;br /&gt;
  {query:/I believe/gi, replacement:'$author suggested'},&lt;br /&gt;
  {query:/I think/gi, replacement:'$author suggested'},&lt;br /&gt;
  {query:/I guess/gi, replacement:'$author believes'},&lt;br /&gt;
  &lt;br /&gt;
  {query:/I can see that/gi, replacement:'$author suggested that'},&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  {query:/I have got/gi, replacement:'$author has got'},&lt;br /&gt;
  {query:/I\'ve got/gi, replacement:'$author has got'},&lt;br /&gt;
  &lt;br /&gt;
  {query:/I\'d suggest/gi, replacement:'$author would suggest'},&lt;br /&gt;
  &lt;br /&gt;
  {query:/I\’m prototyping/gi, replacement:'$author is prototyping'},&lt;br /&gt;
  &lt;br /&gt;
  {query:/I myself/gi, replacement:'$author himself'},&lt;br /&gt;
  {query:/I am/gi, replacement:' $author is'},&lt;br /&gt;
  &lt;br /&gt;
  {query:/I can see/gi, replacement:'$author can see'},&lt;br /&gt;
  {query:/I can/gi, replacement:'$author can'},&lt;br /&gt;
  {query:/I have/gi, replacement:'$author has'},&lt;br /&gt;
  {query:/I should/g, replacement:'$author should'},&lt;br /&gt;
  {query:/I shall/gi, replacement:'$author shall'},&lt;br /&gt;
  {query:/I may/gi, replacement:'$author may'},&lt;br /&gt;
  {query:/I will/gi, replacement:'$author will'},&lt;br /&gt;
  {query:/I would/gi, replacement:'$author would'},&lt;br /&gt;
  {query:/by myself/gi, replacement:'by $author'},&lt;br /&gt;
  {query:/and I/gi, replacement:'and $author'},&lt;br /&gt;
  {query:/and me/gi, replacement:'and $author'},&lt;br /&gt;
  {query:/and myself/gi, replacement:'and $author'}&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  // least specific stuff last (broad/generic stuff is kept as is, with author clarification added in parentheses)&lt;br /&gt;
  /*&lt;br /&gt;
  {query:/I/, replacement:'I ($author)'},&lt;br /&gt;
  &lt;br /&gt;
  {query:/me/, replacement:'me ($author)'},&lt;br /&gt;
  {query:/my/, replacement:'my ($author)'},&lt;br /&gt;
  {query:/myself/, replacement:'myself ($author)'},&lt;br /&gt;
  {query:/mine/, replacement:'$author'}&lt;br /&gt;
  */&lt;br /&gt;
];&lt;br /&gt;
&lt;br /&gt;
// try to assist in transforming speech using the transformation vector passed in&lt;br /&gt;
// still needs to be exposed via the UI&lt;br /&gt;
function transformSpeech(text, author, gender, transformations) {&lt;br /&gt;
  // WIP: foreach transformation in vector, replace the search pattern with the matched string (replacing author/gender as applicable)&lt;br /&gt;
  //alert(&amp;quot;text to be transformed:\n&amp;quot;+text);&lt;br /&gt;
  for(var i=0;i&amp;lt; transformations.length; i++) {&lt;br /&gt;
    var token = transformations[i];&lt;br /&gt;
    // patch the replacement string using the correct author name &lt;br /&gt;
    var replacement = token.replacement.replace(/\$author/gi, author);&lt;br /&gt;
    text = text.replace(token.query, replacement);&lt;br /&gt;
  } // end of token transformation&lt;br /&gt;
  console.log(&amp;quot;transformed text is:&amp;quot;+text);&lt;br /&gt;
  return text;&lt;br /&gt;
} // transformSpeech&lt;br /&gt;
&lt;br /&gt;
// run a self-test&lt;br /&gt;
&lt;br /&gt;
(function() {&lt;br /&gt;
var author =&amp;quot;John Doe&amp;quot;;&lt;br /&gt;
var transformed = transformSpeech(&amp;quot;I have decided to commit a new feature&amp;quot;, author, null, speechTransformations );&lt;br /&gt;
if (transformed !== author+&amp;quot; has decided to commit a new feature&amp;quot;)&lt;br /&gt;
  Host.dbLog(&amp;quot;FIXME: Speech transformations are not working correctly&amp;quot;);&lt;br /&gt;
}) ();&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
var MONTHS = [&lt;br /&gt;
  'Jan',&lt;br /&gt;
  'Feb',&lt;br /&gt;
  'Mar',&lt;br /&gt;
  'Apr',&lt;br /&gt;
  'May',&lt;br /&gt;
  'Jun',&lt;br /&gt;
  'Jul',&lt;br /&gt;
  'Aug',&lt;br /&gt;
  'Sep',&lt;br /&gt;
  'Oct',&lt;br /&gt;
  'Nov',&lt;br /&gt;
  'Dec'&lt;br /&gt;
];&lt;br /&gt;
// Conversion for forum emoticons&lt;br /&gt;
var EMOTICONS = [&lt;br /&gt;
  [/:shock:/g,&lt;br /&gt;
  'O_O'],&lt;br /&gt;
  [&lt;br /&gt;
    /:lol:/g,&lt;br /&gt;
    '(lol)'&lt;br /&gt;
  ],&lt;br /&gt;
  [&lt;br /&gt;
    /:oops:/g,&lt;br /&gt;
    ':$'&lt;br /&gt;
  ],&lt;br /&gt;
  [&lt;br /&gt;
    /:cry:/g,&lt;br /&gt;
    ';('&lt;br /&gt;
  ],&lt;br /&gt;
  [&lt;br /&gt;
    /:evil:/g,&lt;br /&gt;
    '&amp;gt;:)'&lt;br /&gt;
  ],&lt;br /&gt;
  [&lt;br /&gt;
    /:twisted:/g,&lt;br /&gt;
    '3:)'&lt;br /&gt;
  ],&lt;br /&gt;
  [&lt;br /&gt;
    /:roll:/g,&lt;br /&gt;
    '(eye roll)'&lt;br /&gt;
  ],&lt;br /&gt;
  [&lt;br /&gt;
    /:wink:/g,&lt;br /&gt;
    ';)'&lt;br /&gt;
  ],&lt;br /&gt;
  [&lt;br /&gt;
    /:!:/g,&lt;br /&gt;
    '(!)'&lt;br /&gt;
  ],&lt;br /&gt;
  [&lt;br /&gt;
    /:\?:/g,&lt;br /&gt;
    '(?)'&lt;br /&gt;
  ],&lt;br /&gt;
  [&lt;br /&gt;
    /:idea:/g,&lt;br /&gt;
    '(idea)'&lt;br /&gt;
  ],&lt;br /&gt;
  [&lt;br /&gt;
    /:arrow:/g,&lt;br /&gt;
    '(-&amp;gt;)'&lt;br /&gt;
  ],&lt;br /&gt;
  [&lt;br /&gt;
    /:mrgreen:/g,&lt;br /&gt;
    'xD'&lt;br /&gt;
  ]&lt;br /&gt;
];&lt;br /&gt;
// ##################&lt;br /&gt;
// # Main functions #&lt;br /&gt;
// ##################&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// the required trigger is host specific (userscript vs. addon vs. android etc)&lt;br /&gt;
// for now, this merely wraps window.load mapping to the instantCquotoe callback below&lt;br /&gt;
Host.registerTrigger();&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// FIXME: function is currently referenced in CONFIG hash - event_handler, so cannot be easily moved across&lt;br /&gt;
// The main function&lt;br /&gt;
// TODO: split up, so that we can reuse the code elsewhere&lt;br /&gt;
function instantCquote(sel) {&lt;br /&gt;
  var profile = getProfile();&lt;br /&gt;
  &lt;br /&gt;
  // TODO: use config hash here&lt;br /&gt;
  var selection =  document.getSelection(),&lt;br /&gt;
  post_id=0;&lt;br /&gt;
  &lt;br /&gt;
  try {&lt;br /&gt;
    post_id = getPostId(selection, profile);&lt;br /&gt;
  } &lt;br /&gt;
  catch (error) {&lt;br /&gt;
    Host.dbLog('Failed extracting post id\nProfile:' + profile);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  if (selection.toString() === '') {&lt;br /&gt;
    Host.dbLog('No text is selected, aborting function');&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  if (!checkValid(selection, profile)) {&lt;br /&gt;
    Host.dbLog('Selection is not valid, aborting function');&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  try {&lt;br /&gt;
    transformationLoop(profile, post_id);&lt;br /&gt;
  }&lt;br /&gt;
  catch(e) {&lt;br /&gt;
    UI.alert(&amp;quot;Transformation loop:\n&amp;quot;+e.message);&lt;br /&gt;
  }&lt;br /&gt;
} // instantCquote&lt;br /&gt;
&lt;br /&gt;
  // TODO: this needs to be refactored so that it can be also reused by the async/AJAX mode&lt;br /&gt;
  // to extract fields in the background (i.e. move to a separate function)&lt;br /&gt;
function transformationLoop(profile, post_id) {&lt;br /&gt;
  var output = {}, field;&lt;br /&gt;
  Host.dbLog(&amp;quot;Starting extraction/transformation loop&amp;quot;);&lt;br /&gt;
  for (field in profile) {&lt;br /&gt;
    if (field === 'name') continue;&lt;br /&gt;
    if (field ==='type' || field === 'event' || field === 'event_handler') continue; // skip fields that don't contain xpath expressions&lt;br /&gt;
    Host.dbLog(&amp;quot;Extracting field using field id:&amp;quot;+post_id);&lt;br /&gt;
    var fieldData = extractFieldInfo(profile, post_id, field);&lt;br /&gt;
    var transform = profile[field].transform;&lt;br /&gt;
    if (transform !== undefined) {&lt;br /&gt;
      Host.dbLog('Field \'' + field + '\' before transformation:\n\'' + fieldData + '\'');&lt;br /&gt;
      fieldData = applyTransformations(fieldData, transform);&lt;br /&gt;
      Host.dbLog('Field \'' + field + '\' after transformation:\n\'' + fieldData + '\'');&lt;br /&gt;
    }&lt;br /&gt;
    output[field] = fieldData;&lt;br /&gt;
  } // extract and transform all fields for the current profile (website)&lt;br /&gt;
  Host.dbLog(&amp;quot;extraction and transformation loop finished&amp;quot;);&lt;br /&gt;
  output.content = stripWhitespace(output.content);&lt;br /&gt;
  &lt;br /&gt;
  var outputPlain = createCquote(output);&lt;br /&gt;
  outputText(outputPlain, output);&lt;br /&gt;
} // transformationLoop()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/// #############&lt;br /&gt;
&lt;br /&gt;
function runProfileTests() {&lt;br /&gt;
  &lt;br /&gt;
  for (var profile in CONFIG) {&lt;br /&gt;
    if (CONFIG[profile].type != 'archive' || !CONFIG[profile].enabled ) continue; // skip the wiki entry, because it's not an actual archive that we need to test&lt;br /&gt;
    // should be really moved to downloadPostign&lt;br /&gt;
    if (CONFIG[profile].content.xpath === '') console.log(&amp;quot;xpath for content extraction is empty, cannot procedurally extract contents&amp;quot;);&lt;br /&gt;
    for (var test in CONFIG[profile].tests) {&lt;br /&gt;
      var required_data = CONFIG[profile].tests[test];&lt;br /&gt;
      var title = required_data.title;&lt;br /&gt;
      //dbLog('Running test for posting titled:' + title);&lt;br /&gt;
      // fetch posting via getPostingDataAJAX() and compare to the fields we are looking for (author, title, date)&lt;br /&gt;
      //getPostingDataAJAX(profile, required_data.url);&lt;br /&gt;
      //alert(&amp;quot;required title:&amp;quot;+title);&lt;br /&gt;
    } // foreach test&lt;br /&gt;
&lt;br /&gt;
  } // foreach profile (website)&lt;br /&gt;
  &lt;br /&gt;
} //runProfileTests&lt;br /&gt;
&lt;br /&gt;
function selfCheckDialog() {&lt;br /&gt;
  var sections = '&amp;lt;h3&amp;gt;Important APIs:&amp;lt;/h3&amp;gt;&amp;lt;div id=&amp;quot;api_checks&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;';&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  try {&lt;br /&gt;
   runProfileTests.call(undefined); // check website profiles&lt;br /&gt;
  }&lt;br /&gt;
  catch (e) {&lt;br /&gt;
      UI.alert(e.message);&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  for (var profile in CONFIG) {&lt;br /&gt;
    // TODO: also check if enabled or not&lt;br /&gt;
    if (CONFIG[profile].type != 'archive') continue; // skip the wiki entry, because it's not an actual archive that we need to test&lt;br /&gt;
    var test_results = '';&lt;br /&gt;
    for (var test in CONFIG[profile].tests) {&lt;br /&gt;
      // var fieldData = extractFieldInfo(profile, post_id, 'author');&lt;br /&gt;
      test_results += CONFIG[profile].tests[test].title + '&amp;lt;p/&amp;gt;';&lt;br /&gt;
    }&lt;br /&gt;
    sections +='&amp;lt;h3&amp;gt;' + profile + ':&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;'+ CONFIG[profile].url_reg+'&amp;lt;/font&amp;gt;&amp;lt;/h3&amp;gt;&amp;lt;div&amp;gt;&amp;lt;p&amp;gt;' + test_results + '&amp;lt;/p&amp;gt;&amp;lt;/div&amp;gt;\n';&lt;br /&gt;
  }  // https://jqueryui.com/accordion/&lt;br /&gt;
  &lt;br /&gt;
 &lt;br /&gt;
  var checkDlg = $('&amp;lt;div id=&amp;quot;selfCheck&amp;quot; title=&amp;quot;Self Check dialog&amp;quot;&amp;gt;&amp;lt;p&amp;gt;&amp;lt;div id=&amp;quot;accordion&amp;quot;&amp;gt;' + sections + '&amp;lt;/div&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;/div&amp;gt;');&lt;br /&gt;
  &lt;br /&gt;
   // run all API tests, invoke the callback to obtain the status&lt;br /&gt;
  Environment.runAPITests(Host, function(meta) {&lt;br /&gt;
  &lt;br /&gt;
  //console.log('Running API test '+meta.name);&lt;br /&gt;
    &lt;br /&gt;
  meta.test(function(result) {&lt;br /&gt;
   var status = (result)?'success':'fail';&lt;br /&gt;
   var test = $(&amp;quot;&amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&amp;quot;).text('Running API test '+meta.name+':'+status); &lt;br /&gt;
   $('#api_checks', checkDlg).append(test);&lt;br /&gt;
  }); // update tests results&lt;br /&gt;
    &lt;br /&gt;
  }); // runAPITests&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  /*&lt;br /&gt;
  [].forEach.call(CONFIG, function(profile) {&lt;br /&gt;
    alert(&amp;quot;profile is:&amp;quot;+profile);&lt;br /&gt;
  [].forEach.call(CONFIG[profile].tests, function(test) {&lt;br /&gt;
    &lt;br /&gt;
    //UI.alert(test.url);&lt;br /&gt;
    Host.downloadPosting(test.url, function(downloaded) {&lt;br /&gt;
      alert(&amp;quot;downloaded:&amp;quot;);&lt;br /&gt;
      //if (test.title == downloaded.title) alert(&amp;quot;titles match:&amp;quot;+test.title);&lt;br /&gt;
    }); //downloadPosting&lt;br /&gt;
  }); //forEach test&lt;br /&gt;
  }); //forEach profile&lt;br /&gt;
  */&lt;br /&gt;
  &lt;br /&gt;
  //$('#accordion',checkDlg).accordion();&lt;br /&gt;
  checkDlg.dialog({&lt;br /&gt;
    width: 700,&lt;br /&gt;
    height: 500,&lt;br /&gt;
    open: function () {&lt;br /&gt;
      // http://stackoverflow.com/questions/2929487/putting-a-jquery-ui-accordion-in-a-jquery-ui-dialog&lt;br /&gt;
      $('#accordion').accordion({&lt;br /&gt;
        autoHeight: true&lt;br /&gt;
      });&lt;br /&gt;
    }&lt;br /&gt;
  }); // show dialog&lt;br /&gt;
} // selfCheckDialog&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// show a simple configuration dialog (WIP)&lt;br /&gt;
function setupDialog() {&lt;br /&gt;
  //alert(&amp;quot;configuration dialog is not yet implemented&amp;quot;);&lt;br /&gt;
  var checked = (Host.get_persistent('debug_mode_enabled', false) === true) ? 'checked' : '';&lt;br /&gt;
  //dbLog(&amp;quot;value is:&amp;quot;+get_persistent(&amp;quot;debug_mode_enabled&amp;quot;));&lt;br /&gt;
  //dbLog(&amp;quot;persistent debug flag is:&amp;quot;+checked);&lt;br /&gt;
  var setupDiv = $('&amp;lt;div id=&amp;quot;setupDialog&amp;quot; title=&amp;quot;Setup dialog&amp;quot;&amp;gt;NOTE: this configuration dialog is still work-in-progress&amp;lt;/p&amp;gt;&amp;lt;label&amp;gt;&amp;lt;input id=&amp;quot;debugcb&amp;quot; type=&amp;quot;checkbox&amp;quot;' + checked + '&amp;gt;Enable Debug mode&amp;lt;/label&amp;gt;&amp;lt;p/&amp;gt;&amp;lt;div id=&amp;quot;progressbar&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;');&lt;br /&gt;
  setupDiv.click(function () {&lt;br /&gt;
    //alert(&amp;quot;changing persistent debug state&amp;quot;);&lt;br /&gt;
    Host.set_persistent('debug_mode_enabled', $('#debugcb').is(':checked'));&lt;br /&gt;
  });&lt;br /&gt;
  //MediaWiki editing stub, based on: https://www.mediawiki.org/wiki/API:Edit#Editing_via_Ajax&lt;br /&gt;
  //only added here to show some status info in the setup dialog&lt;br /&gt;
  Host.download('http://wiki.flightgear.org/api.php?action=query&amp;amp;prop=info|revisions&amp;amp;intoken=edit&amp;amp;rvprop=timestamp&amp;amp;titles=Main%20Page', function (response) {&lt;br /&gt;
    var message = 'FlightGear wiki login status (AJAX):';&lt;br /&gt;
    var status = response.statusText;&lt;br /&gt;
    var color = (status == 'OK') ? 'green' : 'red';&lt;br /&gt;
    Host.dbLog(message + status);&lt;br /&gt;
    var statusDiv = $('&amp;lt;p&amp;gt;' + message + status + '&amp;lt;/p&amp;gt;').css('color', color);&lt;br /&gt;
    setupDiv.append(statusDiv);&lt;br /&gt;
  });&lt;br /&gt;
  setupDiv.dialog();&lt;br /&gt;
} // setupDialog&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// this  can be used to download/cache $FG_ROOT/options.xml so that fgfs CLI arguments can be recognized and post-processed automatically&lt;br /&gt;
// which can help transforming postings correctly&lt;br /&gt;
function downloadOptionsXML() {&lt;br /&gt;
&lt;br /&gt;
  // download $FG_ROOT/options.xml&lt;br /&gt;
          Host.download(&amp;quot;https://sourceforge.net/p/flightgear/fgdata/ci/next/tree/options.xml?format=raw&amp;quot;, function(response) {&lt;br /&gt;
            var xml = response.responseText;&lt;br /&gt;
            var doc = Host.make_doc(xml, 'text/xml');&lt;br /&gt;
            // https://developer.mozilla.org/en-US/docs/Web/API/XPathResult&lt;br /&gt;
            var options = Host.eval_xpath(doc, '//*/option', XPathResult.ORDERED_NODE_SNAPSHOT_TYPE);&lt;br /&gt;
            &lt;br /&gt;
            // http://help.dottoro.com/ljgnejkp.php&lt;br /&gt;
            Host.dbLog(&amp;quot;Number of options found in options.xml:&amp;quot;+options.snapshotLength);&lt;br /&gt;
            &lt;br /&gt;
            // http://help.dottoro.com/ljtfvvpx.php&lt;br /&gt;
            &lt;br /&gt;
              // https://sourceforge.net/p/flightgear/fgdata/ci/next/tree/options.xml&lt;br /&gt;
              &lt;br /&gt;
            &lt;br /&gt;
          }); // end of options.xml download&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
} // downloadOptionsXML&lt;br /&gt;
&lt;br /&gt;
function getProfile(url=undefined) {&lt;br /&gt;
  &lt;br /&gt;
  if(url === undefined) &lt;br /&gt;
    url=window.location.href;&lt;br /&gt;
  else&lt;br /&gt;
    url=url;&lt;br /&gt;
  &lt;br /&gt;
  Host.dbLog(&amp;quot;getProfile call URL is:&amp;quot;+url);&lt;br /&gt;
  &lt;br /&gt;
  for (var profile in CONFIG) {&lt;br /&gt;
    if (url.match(CONFIG[profile].url_reg) !== null) {&lt;br /&gt;
      Host.dbLog('Matching website profile found');&lt;br /&gt;
      var invocations = Host.get_persistent(Host.getScriptVersion(), 0);&lt;br /&gt;
      Host.dbLog('Number of script invocations for version ' + Host.getScriptVersion() + ' is:' + invocations);&lt;br /&gt;
&lt;br /&gt;
      // determine if we want to show a config dialog&lt;br /&gt;
      if (invocations === 0) {&lt;br /&gt;
        Host.dbLog(&amp;quot;ask for config dialog to be shown&amp;quot;);&lt;br /&gt;
        var response = UI.confirm('This is your first time running version ' + Host.getScriptVersion() + '\nConfigure now?');&lt;br /&gt;
        if (response) {&lt;br /&gt;
                  &lt;br /&gt;
          // show configuration dialog (jQuery)&lt;br /&gt;
          setupDialog();&lt;br /&gt;
        } &lt;br /&gt;
        else {&lt;br /&gt;
        } // don't configure&lt;br /&gt;
&lt;br /&gt;
      }      &lt;br /&gt;
      &lt;br /&gt;
      // increment number of invocations, use the script's version number as the key, to prevent the config dialog from showing up again (except for updated scripts)&lt;br /&gt;
      // FIXME: this is triggered/incremented by each click ...&lt;br /&gt;
      Host.dbLog(&amp;quot;increment number of script invocations&amp;quot;);&lt;br /&gt;
      Host.set_persistent(Host.getScriptVersion(), invocations + 1);&lt;br /&gt;
      return CONFIG[profile];&lt;br /&gt;
    } // matched website profile&lt;br /&gt;
    Host.dbLog('Could not find matching URL in getProfile() call!');&lt;br /&gt;
  } // for each profile&lt;br /&gt;
}// Get the HTML code that is selected&lt;br /&gt;
&lt;br /&gt;
function getSelectedHtml() {&lt;br /&gt;
  // From http://stackoverflow.com/a/6668159&lt;br /&gt;
  var html = '',&lt;br /&gt;
  selection = document.getSelection();&lt;br /&gt;
  if (selection.rangeCount) {&lt;br /&gt;
    var container = document.createElement('div');&lt;br /&gt;
    for (var i = 0; i &amp;lt; selection.rangeCount; i++) {&lt;br /&gt;
      container.appendChild(selection.getRangeAt(i).cloneContents());&lt;br /&gt;
    }&lt;br /&gt;
    html = container.innerHTML;&lt;br /&gt;
  }&lt;br /&gt;
  Host.dbLog('instantCquote(): Unprocessed HTML\n\'' + html + '\'');&lt;br /&gt;
  return html;&lt;br /&gt;
}// Gets the selected text&lt;br /&gt;
&lt;br /&gt;
function getSelectedText() {&lt;br /&gt;
  return document.getSelection().toString();&lt;br /&gt;
}// Get the ID of the post&lt;br /&gt;
// (this needs some work so that it can be used by the AJAX mode, without an actual selection)&lt;br /&gt;
&lt;br /&gt;
function getPostId(selection, profile, focus) {&lt;br /&gt;
  if (focus !== undefined) {&lt;br /&gt;
    Host.dbLog(&amp;quot;Trying to get PostId with defined focus&amp;quot;);&lt;br /&gt;
    selection = selection.focusNode.parentNode;&lt;br /&gt;
  } else {&lt;br /&gt;
    Host.dbLog(&amp;quot;Trying to get PostId with undefined focus&amp;quot;);&lt;br /&gt;
    selection = selection.anchorNode.parentNode;&lt;br /&gt;
  }&lt;br /&gt;
  while (selection.id.match(profile.content.idStyle) === null) {&lt;br /&gt;
    selection = selection.parentNode;&lt;br /&gt;
  }&lt;br /&gt;
  Host.dbLog(&amp;quot;Selection id is:&amp;quot;+selection.id);&lt;br /&gt;
  return selection.id;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Checks that the selection is valid&lt;br /&gt;
function checkValid(selection, profile) {&lt;br /&gt;
  var ret = true,&lt;br /&gt;
  selection_cp = {&lt;br /&gt;
  },&lt;br /&gt;
  tags = profile.content.parentTag;&lt;br /&gt;
  for (var n = 0; n &amp;lt; 2; n++) {&lt;br /&gt;
    if (n === 0) {&lt;br /&gt;
      selection_cp = selection.anchorNode.parentNode;&lt;br /&gt;
    } else {&lt;br /&gt;
      selection_cp = selection.focusNode.parentNode;&lt;br /&gt;
    }&lt;br /&gt;
    while (true) {&lt;br /&gt;
      if (selection_cp.tagName === 'BODY') {&lt;br /&gt;
        ret = false;&lt;br /&gt;
        break;&lt;br /&gt;
      } else {&lt;br /&gt;
        var cont = false;&lt;br /&gt;
        for (var i = 0; i &amp;lt; tags.length; i++) {&lt;br /&gt;
          if (selection_cp[tags[0]] === tags[i]) {&lt;br /&gt;
            cont = true;&lt;br /&gt;
            break;&lt;br /&gt;
          }&lt;br /&gt;
        }&lt;br /&gt;
        if (cont) {&lt;br /&gt;
          break;&lt;br /&gt;
        } else {&lt;br /&gt;
          selection_cp = selection_cp.parentNode;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  ret = ret &amp;amp;&amp;amp; (getPostId(selection, profile) === getPostId(selection, profile, 1));&lt;br /&gt;
  return ret;&lt;br /&gt;
}// Extracts the raw text from a certain place, using an XPath&lt;br /&gt;
&lt;br /&gt;
function extractFieldInfo(profile, id, field) {&lt;br /&gt;
  &lt;br /&gt;
  if (field === 'content') {&lt;br /&gt;
    Host.dbLog(&amp;quot;Returning content (selection)&amp;quot;);&lt;br /&gt;
    return profile[field].selection();&lt;br /&gt;
  } else {&lt;br /&gt;
    Host.dbLog(&amp;quot;Extracting field via xpath:&amp;quot;+field);&lt;br /&gt;
    var xpath = '//*[@id=&amp;quot;' + id + '&amp;quot;]/' + profile[field].xpath;&lt;br /&gt;
    return Host.eval_xpath(document, xpath).stringValue; // document.evaluate(xpath, document, null, XPathResult.STRING_TYPE, null).stringValue;&lt;br /&gt;
  }&lt;br /&gt;
}// Change the text using specified transformations&lt;br /&gt;
&lt;br /&gt;
function applyTransformations(fieldInfo, trans) { &lt;br /&gt;
    for (var i = 0; i &amp;lt; trans.length; i++) {&lt;br /&gt;
      fieldInfo = trans[i](fieldInfo);&lt;br /&gt;
      Host.dbLog('applyTransformations(): Multiple transformation, transformation after loop #' + (i + 1) + ':\n\'' + fieldInfo + '\'');&lt;br /&gt;
    }&lt;br /&gt;
    return fieldInfo;&lt;br /&gt;
  &lt;br /&gt;
} //applyTransformations&lt;br /&gt;
&lt;br /&gt;
// Formats the quote&lt;br /&gt;
&lt;br /&gt;
function createCquote(data, indirect_speech=false) {&lt;br /&gt;
 if(!indirect_speech)&lt;br /&gt;
   return nonQuotedRef(data); // conventional/verbatim selection&lt;br /&gt;
  else { &lt;br /&gt;
    // pattern match the content using a vector of regexes&lt;br /&gt;
    data.content = transformSpeech(data.content, data.author, null, speechTransformations );&lt;br /&gt;
    return nonQuotedRef(data);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function nonQuotedRef(data) { //TODO: rename &lt;br /&gt;
  var template = Host.getTemplate();&lt;br /&gt;
  &lt;br /&gt;
  var substituted = template&lt;br /&gt;
  .replace('$CONTENT', data.content)&lt;br /&gt;
  .replace('$URL',data.url)&lt;br /&gt;
  .replace('$TITLE',data.title)  &lt;br /&gt;
  .replace('$AUTHOR',data.author)&lt;br /&gt;
  .replace('$DATE',datef(data.date))&lt;br /&gt;
  .replace('$ADDED',datef(data.date))&lt;br /&gt;
  .replace('$SCRIPT_VERSION', Host.getScriptVersion() );&lt;br /&gt;
  &lt;br /&gt;
  return substituted; &lt;br /&gt;
}// &lt;br /&gt;
&lt;br /&gt;
// Output the text.&lt;br /&gt;
// Tries the jQuery dialog, and falls back to window.prompt()&lt;br /&gt;
&lt;br /&gt;
function outputText(msg, original) {&lt;br /&gt;
  try {&lt;br /&gt;
    OUTPUT.jQueryTabbed(msg, original); &lt;br /&gt;
  } &lt;br /&gt;
  catch (err) {&lt;br /&gt;
    msg = msg.replace(/&amp;amp;lt;\/syntaxhighligh(.)&amp;gt;/g, '&amp;lt;/syntaxhighligh$1');&lt;br /&gt;
    OUTPUT.msgbox(msg);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// #############&lt;br /&gt;
// # Utilities #&lt;br /&gt;
// #############&lt;br /&gt;
&lt;br /&gt;
function extract(regex) {&lt;br /&gt;
  return function (text) {&lt;br /&gt;
    return text.match(regex) [1];&lt;br /&gt;
  };&lt;br /&gt;
}&lt;br /&gt;
function prepend(prefix) {&lt;br /&gt;
  return function (text) {&lt;br /&gt;
    return prefix + text;&lt;br /&gt;
  };&lt;br /&gt;
}&lt;br /&gt;
function removeComments(html) {&lt;br /&gt;
  return html.replace(/&amp;lt;!--.*?--&amp;gt;/g, '');&lt;br /&gt;
}// Not currently used (as of June 2015), but kept just in case&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// currently unused&lt;br /&gt;
function escapePipes(html) {&lt;br /&gt;
  html = html.replace(/\|\|/g, '{{!!}n}');&lt;br /&gt;
  html = html.replace(/\|\-/g, '{{!-}}');&lt;br /&gt;
  return html.replace(/\|/g, '{{!}}');&lt;br /&gt;
}// Converts HTML &amp;lt;a href=&amp;quot;...&amp;quot;&amp;gt;...&amp;lt;/a&amp;gt; tags to wiki links, internal if possible.&lt;br /&gt;
&lt;br /&gt;
function a2wikilink(html) {&lt;br /&gt;
  // Links to wiki images, because&lt;br /&gt;
  // they need special treatment, or else they get displayed.&lt;br /&gt;
  html = html.replace(/&amp;lt;a.*?href=&amp;quot;http:\/\/wiki\.flightgear\.org\/File:(.*?)&amp;quot;.*?&amp;gt;(.*?)&amp;lt;\/a&amp;gt;/g, '[[Media:$1|$2]]');&lt;br /&gt;
  // Wiki links without custom text.&lt;br /&gt;
  html = html.replace(/&amp;lt;a.*?href=&amp;quot;http:\/\/wiki\.flightgear\.org\/(.*?)&amp;quot;.*?&amp;gt;http:\/\/wiki\.flightgear\.org\/.*?&amp;lt;\/a&amp;gt;/g, '[[$1]]');&lt;br /&gt;
  // Links to the wiki with custom text&lt;br /&gt;
  html = html.replace(/&amp;lt;a.*?href=&amp;quot;http:\/\/wiki\.flightgear\.org\/(.*?)&amp;quot;.*?&amp;gt;(.*?)&amp;lt;\/a&amp;gt;/g, '[[$1|$2]]');&lt;br /&gt;
  // Remove underscores from all wiki links&lt;br /&gt;
  var list = html.match(/\[\[.*?\]\]/g);&lt;br /&gt;
  if (list !== null) {&lt;br /&gt;
    for (var i = 0; i &amp;lt; list.length; i++) {&lt;br /&gt;
      html = html.replace(list[i], underscore2Space(list[i]));&lt;br /&gt;
    }&lt;br /&gt;
  }  // Convert non-wiki links&lt;br /&gt;
  // TODO: identify forum/devel list links, and use the AJAX/Host.download helper to get a title/subject for unnamed links (using the existing xpath/regex helpers for that)&lt;br /&gt;
&lt;br /&gt;
  html = html.replace(/&amp;lt;a.*?href=&amp;quot;(.*?)&amp;quot;.*?&amp;gt;(.*?)&amp;lt;\/a&amp;gt;/g, '[$1 $2]');&lt;br /&gt;
  // Remove triple dots from external links.&lt;br /&gt;
  // Replace with raw URL (MediaWiki converts it to a link).&lt;br /&gt;
  list = html.match(/\[.*?(\.\.\.).*?\]/g);&lt;br /&gt;
  if (list !== null) {&lt;br /&gt;
    for (var i = 0; i &amp;lt; list.length; i++) {&lt;br /&gt;
      html = html.replace(list[i], list[i].match(/\[(.*?) .*?\]/) [1]);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return html;&lt;br /&gt;
}// Converts images, including images in &amp;lt;a&amp;gt; links&lt;br /&gt;
&lt;br /&gt;
function img2link(html) {&lt;br /&gt;
  html = html.replace(/&amp;lt;a[^&amp;lt;]*?href=&amp;quot;([^&amp;lt;]*?)&amp;quot;[^&amp;lt;]*?&amp;gt;&amp;lt;img.*?src=&amp;quot;http:\/\/wiki\.flightgear\.org\/images\/.*?\/.*?\/(.*?)&amp;quot;.*?&amp;gt;&amp;lt;\/a&amp;gt;/g, '[[File:$2|250px|link=$1]]');&lt;br /&gt;
  html = html.replace(/&amp;lt;img.*?src=&amp;quot;http:\/\/wiki\.flightgear\.org\/images\/.*?\/.*?\/(.*?)&amp;quot;.*?&amp;gt;/g, '[[File:$1|250px]]');&lt;br /&gt;
  html = html.replace(/&amp;lt;a[^&amp;lt;]*?href=&amp;quot;([^&amp;lt;]*?)&amp;quot;[^&amp;lt;]*?&amp;gt;&amp;lt;img.*?src=&amp;quot;(.*?)&amp;quot;.*?&amp;gt;&amp;lt;\/a&amp;gt;/g, '(see [$2 image], links to [$1 here])');&lt;br /&gt;
  return html.replace(/&amp;lt;img.*?src=&amp;quot;(.*?)&amp;quot;.*?&amp;gt;/g, '(see the [$1 linked image])');&lt;br /&gt;
}// Converts smilies&lt;br /&gt;
&lt;br /&gt;
function forum_smilies2text(html) {&lt;br /&gt;
  html = html.replace(/&amp;lt;img src=&amp;quot;\.\/images\/smilies\/icon_.*?\.gif&amp;quot; alt=&amp;quot;(.*?)&amp;quot;.*?&amp;gt;/g, '$1');&lt;br /&gt;
  for (var i = 0; i &amp;lt; EMOTICONS.length; i++) {&lt;br /&gt;
    html = html.replace(EMOTICONS[i][0], EMOTICONS[i][1]);&lt;br /&gt;
  }&lt;br /&gt;
  return html;&lt;br /&gt;
}// Converts font formatting&lt;br /&gt;
&lt;br /&gt;
function forum_fontstyle2wikistyle(html) {&lt;br /&gt;
  html = html.replace(/&amp;lt;span style=&amp;quot;font-weight: bold&amp;quot;&amp;gt;(.*?)&amp;lt;\/span&amp;gt;/g, '\'\'\'$1\'\'\'');&lt;br /&gt;
  html = html.replace(/&amp;lt;span style=&amp;quot;text-decoration: underline&amp;quot;&amp;gt;(.*?)&amp;lt;\/span&amp;gt;/g, '&amp;lt;u&amp;gt;$1&amp;lt;/u&amp;gt;');&lt;br /&gt;
  html = html.replace(/&amp;lt;span style=&amp;quot;font-style: italic&amp;quot;&amp;gt;(.*?)&amp;lt;\/span&amp;gt;/g, '\'\'$1\'\'');&lt;br /&gt;
  return html.replace(/&amp;lt;span class=&amp;quot;posthilit&amp;quot;&amp;gt;(.*?)&amp;lt;\/span&amp;gt;/g, '$1');&lt;br /&gt;
}// Converts code blocks&lt;br /&gt;
&lt;br /&gt;
function forum_code2syntaxhighlight(html) {&lt;br /&gt;
  var list = html.match(/&amp;lt;dl class=&amp;quot;codebox&amp;quot;&amp;gt;.*?&amp;lt;code&amp;gt;(.*?)&amp;lt;\/code&amp;gt;.*?&amp;lt;\/dl&amp;gt;/g),&lt;br /&gt;
  data = [&lt;br /&gt;
  ];&lt;br /&gt;
  if (list === null) return html;&lt;br /&gt;
  for (var n = 0; n &amp;lt; list.length; n++) {&lt;br /&gt;
    data = html.match(/&amp;lt;dl class=&amp;quot;codebox&amp;quot;&amp;gt;.*?&amp;lt;code&amp;gt;(.*?)&amp;lt;\/code&amp;gt;.*?&amp;lt;\/dl&amp;gt;/);&lt;br /&gt;
    html = html.replace(data[0], processCode(data));&lt;br /&gt;
  }&lt;br /&gt;
  return html;&lt;br /&gt;
}// Strips any whitespace from the beginning and end of a string&lt;br /&gt;
&lt;br /&gt;
function stripWhitespace(html) {&lt;br /&gt;
  html = html.replace(/^\s*?(\S)/, '$1');&lt;br /&gt;
  return html.replace(/(\S)\s*?\z/, '$1');&lt;br /&gt;
}// Process code, including basic detection of language&lt;br /&gt;
&lt;br /&gt;
function processCode(data) {&lt;br /&gt;
  var lang = '',&lt;br /&gt;
  code = data[1];&lt;br /&gt;
  code = code.replace(/&amp;amp;nbsp;/g, ' ');&lt;br /&gt;
  if (code.match(/=?.*?\(?.*?\)?;/) !== null) lang = 'nasal';&lt;br /&gt;
  if (code.match(/&amp;amp;lt;.*?&amp;amp;gt;.*?&amp;amp;lt;\/.*?&amp;amp;gt;/) !== null || code.match(/&amp;amp;lt;!--.*?--&amp;amp;gt;/) !== null) lang = 'xml';&lt;br /&gt;
  code = code.replace(/&amp;lt;br\/?&amp;gt;/g, '\n');&lt;br /&gt;
  return '&amp;lt;syntaxhighlight lang=&amp;quot;' + lang + '&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;\n' + code + '\n&amp;amp;lt;/syntaxhighlight&amp;gt;';&lt;br /&gt;
}// Converts quote blocks to Cquotes&lt;br /&gt;
&lt;br /&gt;
function forum_quote2cquote(html) {&lt;br /&gt;
  html = html.replace(/&amp;lt;blockquote class=&amp;quot;uncited&amp;quot;&amp;gt;&amp;lt;div&amp;gt;(.*?)&amp;lt;\/div&amp;gt;&amp;lt;\/blockquote&amp;gt;/g, '{{cquote|$1}}');&lt;br /&gt;
  if (html.match(/&amp;lt;blockquote&amp;gt;/g) === null) return html;&lt;br /&gt;
  var numQuotes = html.match(/&amp;lt;blockquote&amp;gt;/g).length;&lt;br /&gt;
  for (var n = 0; n &amp;lt; numQuotes; n++) {&lt;br /&gt;
    html = html.replace(/&amp;lt;blockquote&amp;gt;&amp;lt;div&amp;gt;&amp;lt;cite&amp;gt;(.*?) wrote.*?:&amp;lt;\/cite&amp;gt;(.*?)&amp;lt;\/div&amp;gt;&amp;lt;\/blockquote&amp;gt;/, '{{cquote|$2|$1}}');&lt;br /&gt;
  }&lt;br /&gt;
  return html;&lt;br /&gt;
}// Converts videos to wiki style&lt;br /&gt;
&lt;br /&gt;
function vid2wiki(html) {&lt;br /&gt;
  // YouTube&lt;br /&gt;
  html = html.replace(/&amp;lt;div class=&amp;quot;video-wrapper&amp;quot;&amp;gt;\s.*?&amp;lt;div class=&amp;quot;video-container&amp;quot;&amp;gt;\s*?&amp;lt;iframe class=&amp;quot;youtube-player&amp;quot;.*?width=&amp;quot;(.*?)&amp;quot; height=&amp;quot;(.*?)&amp;quot; src=&amp;quot;http:\/\/www\.youtube\.com\/embed\/(.*?)&amp;quot;.*?&amp;gt;&amp;lt;\/iframe&amp;gt;\s*?&amp;lt;\/div&amp;gt;\s*?&amp;lt;\/div&amp;gt;/g, '{{#ev:youtube|$3|$1x$2}}');&lt;br /&gt;
  // Vimeo&lt;br /&gt;
  html = html.replace(/&amp;lt;iframe src=&amp;quot;http:\/\/player\.vimeo\.com\/video\/(.*?)\?.*?&amp;quot; width=&amp;quot;(.*?)&amp;quot; height=&amp;quot;(.*?)&amp;quot;.*?&amp;gt;.*?&amp;lt;\/iframe&amp;gt;/g, '{{#ev:vimeo|$1|$2x$3}}');&lt;br /&gt;
  return html.replace(/\[.*? Watch on Vimeo\]/g, '');&lt;br /&gt;
}// Not currently used (as of June 2015), but kept just in case&lt;br /&gt;
&lt;br /&gt;
// currently unused&lt;br /&gt;
function escapeEquals(html) {&lt;br /&gt;
  return html.replace(/=/g, '{{=}}');&lt;br /&gt;
}// &amp;lt;br&amp;gt; to newline.&lt;br /&gt;
&lt;br /&gt;
function forum_br2newline(html) {&lt;br /&gt;
  html = html.replace(/&amp;lt;br\/?&amp;gt;&amp;lt;br\/?&amp;gt;/g, '\n');&lt;br /&gt;
  return html.replace(/&amp;lt;br\/?&amp;gt;/g, '\n\n');&lt;br /&gt;
}// Forum list to wiki style&lt;br /&gt;
&lt;br /&gt;
function list2wiki(html) {&lt;br /&gt;
  var list = html.match(/&amp;lt;ul&amp;gt;(.*?)&amp;lt;\/ul&amp;gt;/g);&lt;br /&gt;
  if (list !== null) {&lt;br /&gt;
    for (var i = 0; i &amp;lt; list.length; i++) {&lt;br /&gt;
      html = html.replace(/&amp;lt;li&amp;gt;(.*?)&amp;lt;\/li&amp;gt;/g, '* $1\n');&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  list = html.match(/&amp;lt;ol.*?&amp;gt;(.*?)&amp;lt;\/ol&amp;gt;/g);&lt;br /&gt;
  if (list !== null) {&lt;br /&gt;
    for (var i = 0; i &amp;lt; list.length; i++) {&lt;br /&gt;
      html = html.replace(/&amp;lt;li&amp;gt;(.*?)&amp;lt;\/li&amp;gt;/g, '# $1\n');&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  html = html.replace(/&amp;lt;\/?[uo]l&amp;gt;/g, '');&lt;br /&gt;
  return html;&lt;br /&gt;
}&lt;br /&gt;
function nowiki(text) {&lt;br /&gt;
  return '&amp;lt;nowiki&amp;gt;' + text + '&amp;lt;/nowiki&amp;gt;';&lt;br /&gt;
}// Returns the correct ordinal adjective&lt;br /&gt;
&lt;br /&gt;
function ordAdj(date) {&lt;br /&gt;
  date = date.toString();&lt;br /&gt;
  if (date == '11' || date == '12' || date == '13') {&lt;br /&gt;
    return 'th';&lt;br /&gt;
  } else if (date.substr(1) == '1' || date == '1') {&lt;br /&gt;
    return 'st';&lt;br /&gt;
  } else if (date.substr(1) == '2' || date == '2') {&lt;br /&gt;
    return 'nd';&lt;br /&gt;
  } else if (date.substr(1) == '3' || date == '3') {&lt;br /&gt;
    return 'rd';&lt;br /&gt;
  } else {&lt;br /&gt;
    return 'th';&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Formats the date to this format: Apr 26th, 2015&lt;br /&gt;
function datef(text) {&lt;br /&gt;
  var date = new Date(text);&lt;br /&gt;
  return MONTHS[date.getMonth()] + ' ' + date.getDate() + ordAdj(date.getDate()) + ', ' + date.getFullYear();&lt;br /&gt;
}&lt;br /&gt;
function underscore2Space(str) {&lt;br /&gt;
  return str.replace(/_/g, ' ');&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// IGNORE EVERYTHING THAT FOLLOWS: &lt;br /&gt;
// This is an experiment to use GA/GP (genetic programming) to help procedurally evolve xpath and regex expressions if/when the underlying websites change&lt;br /&gt;
// so that we don't have to manually update/edit the script accordingly (this would also work for mobile themes etc)&lt;br /&gt;
// For now, this is heavily based on the genetic.js framework/examples: http://subprotocol.com/system/genetic-hello-world.html&lt;br /&gt;
// The idea is to evolve the xpath/regex expression by evaluating its return value against the expected/desired value&lt;br /&gt;
// the most important thing here is having a suitable fitness function&lt;br /&gt;
// &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function evolve_expression_test() {&lt;br /&gt;
  &lt;br /&gt;
try {  &lt;br /&gt;
var genetic = Genetic.create();&lt;br /&gt;
&lt;br /&gt;
// TODO: use minimizer: redundant_bytes + duration_msec + xpath.length&lt;br /&gt;
genetic.optimize = Genetic.Optimize.Maximize;&lt;br /&gt;
genetic.select1 = Genetic.Select1.Tournament2;&lt;br /&gt;
genetic.select2 = Genetic.Select2.Tournament2;&lt;br /&gt;
 &lt;br /&gt;
   &lt;br /&gt;
genetic.seed = function() {&lt;br /&gt;
&lt;br /&gt;
    function randomString(len) {&lt;br /&gt;
        var text = &amp;quot;&amp;quot;;&lt;br /&gt;
        var charset = &amp;quot;\\abcdefghijklmnopqrstuvwxyz0123456789[] ()&amp;lt;&amp;gt;*.,&amp;quot;;&lt;br /&gt;
        for(var i=0;i&amp;lt;len;i++)&lt;br /&gt;
            text += charset.charAt(Math.floor(Math.random() * charset.length));&lt;br /&gt;
        &lt;br /&gt;
        return text; // &amp;quot;From:&amp;amp;(.*)$&amp;lt;.*8.*&amp;gt;&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // create random strings that are equal in length to solution&lt;br /&gt;
    return randomString( this.userData[&amp;quot;solution&amp;quot;].length);&lt;br /&gt;
};&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
genetic.mutate = function(entity) {&lt;br /&gt;
    &lt;br /&gt;
    function replaceAt(str, index, character) {&lt;br /&gt;
        return str.substr(0, index) + character + str.substr(index+character.length);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // chromosomal drift&lt;br /&gt;
    var i = Math.floor(Math.random()*entity.length);&lt;br /&gt;
    return replaceAt(entity, i, String.fromCharCode(entity.charCodeAt(i) + (Math.floor(Math.random()*2) ? 1 : -1)));&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
genetic.crossover = function(mother, father) {&lt;br /&gt;
&lt;br /&gt;
    // two-point crossover&lt;br /&gt;
    var len = mother.length;&lt;br /&gt;
    var ca = Math.floor(Math.random()*len);&lt;br /&gt;
    var cb = Math.floor(Math.random()*len);     &lt;br /&gt;
    if (ca &amp;gt; cb) {&lt;br /&gt;
        var tmp = cb;&lt;br /&gt;
        cb = ca;&lt;br /&gt;
        ca = tmp;&lt;br /&gt;
    }&lt;br /&gt;
        &lt;br /&gt;
    var son = father.substr(0,ca) + mother.substr(ca, cb-ca) + father.substr(cb);&lt;br /&gt;
    var daughter = mother.substr(0,ca) + father.substr(ca, cb-ca) + mother.substr(cb);&lt;br /&gt;
    &lt;br /&gt;
    return [son, daughter];&lt;br /&gt;
};&lt;br /&gt;
    &lt;br /&gt;
genetic.determineExcessBytes = function (text, needle) {&lt;br /&gt;
    return text.length - needle.length;&lt;br /&gt;
};&lt;br /&gt;
    &lt;br /&gt;
genetic.containsText = function (text, needle) {&lt;br /&gt;
    return text.search(needle);&lt;br /&gt;
};&lt;br /&gt;
  &lt;br /&gt;
genetic.isValid = function(exp) {&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
    &lt;br /&gt;
/* myFitness:&lt;br /&gt;
 * - must be a valid xpath/regex expression (try/call)&lt;br /&gt;
 * - must containsText the needle&lt;br /&gt;
 * - low relative offset in text (begin/end)&lt;br /&gt;
 * - excessBytes&lt;br /&gt;
 * - short expression  (expression length)&lt;br /&gt;
 * - expression footprint (runtime)&lt;br /&gt;
 */ &lt;br /&gt;
&lt;br /&gt;
// TODO: the fitness function should validate each xpath/regex first&lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
genetic.fitness = function(entity) {&lt;br /&gt;
    var fitness = 0;&lt;br /&gt;
    var result;&lt;br /&gt;
    var validExp = 0.1;&lt;br /&gt;
    var hasToken = 0.1;&lt;br /&gt;
   &lt;br /&gt;
  &lt;br /&gt;
    var t = this.userData.tests[0].haystack;&lt;br /&gt;
    //var regex = new RegExp(this.userData.solution);&lt;br /&gt;
    //var output = t.match( new RegExp(&amp;quot;From: (.*) &amp;lt;.*@.*&amp;gt;&amp;quot;))[1];  &lt;br /&gt;
    // TODO: use search &amp;amp; match for improving the fitness&lt;br /&gt;
  &lt;br /&gt;
    if (0)  &lt;br /&gt;
    try {&lt;br /&gt;
    var regex = new RegExp(entity);&lt;br /&gt;
    var output = t.search( regex);&lt;br /&gt;
    validExp = 5;&lt;br /&gt;
    //if (output) validExp = 50;&lt;br /&gt;
    }&lt;br /&gt;
    catch(e) {&lt;br /&gt;
    //validExp = 2;    &lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
   &lt;br /&gt;
    &lt;br /&gt;
    var i;&lt;br /&gt;
    for (i=0;i&amp;lt;entity.length;++i) {&lt;br /&gt;
        // increase fitness for each character that matches&lt;br /&gt;
        if (entity[i] == this.userData[&amp;quot;solution&amp;quot;][i])&lt;br /&gt;
            fitness += 1;&lt;br /&gt;
        &lt;br /&gt;
        // award fractions of a point as we get warmer&lt;br /&gt;
        fitness += (127-Math.abs(entity.charCodeAt(i) - this.userData[&amp;quot;solution&amp;quot;].charCodeAt(i)))/50;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
    return fitness + (1*validExp + 1* hasToken);&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
genetic.generation = function(pop, generation, stats) {&lt;br /&gt;
    // stop running once we've reached the solution&lt;br /&gt;
    return pop[0].entity != this.userData[&amp;quot;solution&amp;quot;];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
genetic.notification = function(pop, generation, stats, isFinished) {&lt;br /&gt;
&lt;br /&gt;
    function lerp(a, b, p) {&lt;br /&gt;
        return a + (b-a)*p;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    var value = pop[0].entity;&lt;br /&gt;
    this.last = this.last||value;&lt;br /&gt;
    &lt;br /&gt;
    if (pop != 0 &amp;amp;&amp;amp; value == this.last)&lt;br /&gt;
        return;&lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
    var solution = [];&lt;br /&gt;
    var i;&lt;br /&gt;
    for (i=0;i&amp;lt;value.length;++i) {&lt;br /&gt;
        var diff = value.charCodeAt(i) - this.last.charCodeAt(i);&lt;br /&gt;
        var style = &amp;quot;background: transparent;&amp;quot;;&lt;br /&gt;
        if (diff &amp;gt; 0) {&lt;br /&gt;
            style = &amp;quot;background: rgb(0,200,50); color: #fff;&amp;quot;;&lt;br /&gt;
        } else if (diff &amp;lt; 0) {&lt;br /&gt;
            style = &amp;quot;background: rgb(0,100,50); color: #fff;&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        solution.push(&amp;quot;&amp;lt;span style=\&amp;quot;&amp;quot; + style + &amp;quot;\&amp;quot;&amp;gt;&amp;quot; + value[i] + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
    var t = this.userData.tests[0].haystack;&lt;br /&gt;
    //console.log(&amp;quot;haystack is:&amp;quot;+t);&lt;br /&gt;
    // &amp;quot;From: John Doe &amp;lt;John@do...&amp;gt; - 2020-07-02 17:36:03&amp;quot;, needle: &amp;quot;John Doe&amp;quot;}, /From: (.*) &amp;lt;.*@.*&amp;gt;/&lt;br /&gt;
    var regex = new RegExp(this.userData.solution);&lt;br /&gt;
    //var output = t.match( new RegExp(&amp;quot;From: (.*) &amp;lt;.*@.*&amp;gt;&amp;quot;))[1];  &lt;br /&gt;
    // TODO: use search &amp;amp; match for improving the fitness&lt;br /&gt;
    var output = t.search( new RegExp(value));&lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
    var buf = &amp;quot;&amp;quot;;&lt;br /&gt;
    buf += &amp;quot;&amp;lt;tr&amp;gt;&amp;quot;;&lt;br /&gt;
    buf += &amp;quot;&amp;lt;td&amp;gt;&amp;quot; + generation + &amp;quot;&amp;lt;/td&amp;gt;&amp;quot;;&lt;br /&gt;
    buf += &amp;quot;&amp;lt;td&amp;gt;&amp;quot; + pop[0].fitness.toPrecision(5) + &amp;quot;&amp;lt;/td&amp;gt;&amp;quot;;&lt;br /&gt;
    buf += &amp;quot;&amp;lt;td&amp;gt;&amp;quot; + solution.join(&amp;quot;&amp;quot;) + &amp;quot;&amp;lt;/td&amp;gt;&amp;quot;;&lt;br /&gt;
    buf += &amp;quot;&amp;lt;td&amp;gt;&amp;quot; + output + &amp;quot;&amp;lt;/td&amp;gt;&amp;quot;;&lt;br /&gt;
    buf += &amp;quot;&amp;lt;/tr&amp;gt;&amp;quot;;&lt;br /&gt;
    $(&amp;quot;#results tbody&amp;quot;).prepend(buf);&lt;br /&gt;
    &lt;br /&gt;
    this.last = value;&lt;br /&gt;
};&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  /*&lt;br /&gt;
genetic.notification2 = function(pop, generation, stats, isFinished) {&lt;br /&gt;
&lt;br /&gt;
    function lerp(a, b, p) {&lt;br /&gt;
        return a + (b-a)*p;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    var value = pop[0].entity;&lt;br /&gt;
    this.last = this.last||value;&lt;br /&gt;
    &lt;br /&gt;
    if (pop != 0 &amp;amp;&amp;amp; value == this.last)&lt;br /&gt;
        return;&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    var solution = [];&lt;br /&gt;
    var i;&lt;br /&gt;
    for (i=0;i&amp;lt;value.length;++i) {&lt;br /&gt;
    &lt;br /&gt;
    solution.push(value[i]);&lt;br /&gt;
 } &lt;br /&gt;
    console.log(&amp;quot;Generation:&amp;quot;+ generation + &amp;quot; Fitness:&amp;quot; + pop[0].fitness.toPrecision(5) + &amp;quot; Solution:&amp;quot; + solution.join(&amp;quot;&amp;quot;));&lt;br /&gt;
  &lt;br /&gt;
    this.last = value;&lt;br /&gt;
};&lt;br /&gt;
  */&lt;br /&gt;
    &lt;br /&gt;
      &lt;br /&gt;
var config = {&lt;br /&gt;
            &amp;quot;iterations&amp;quot;: 4000&lt;br /&gt;
            , &amp;quot;size&amp;quot;: 250&lt;br /&gt;
            , &amp;quot;crossover&amp;quot;: 0.3&lt;br /&gt;
            , &amp;quot;mutation&amp;quot;: 0.4&lt;br /&gt;
            , &amp;quot;skip&amp;quot;: 30 // notifications&lt;br /&gt;
            //, &amp;quot;webWorkers&amp;quot;: false&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
var profile = CONFIG['Sourceforge Mailing list'];&lt;br /&gt;
var posting = profile.tests[0];&lt;br /&gt;
var author_xpath = profile.title.xpath;&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
var regexTests = [&lt;br /&gt;
  {haystack: &amp;quot;From: John Doe &amp;lt;John@do...&amp;gt; - 2020-07-02 17:36:03&amp;quot;, needle: &amp;quot;John Doe&amp;quot;}, &lt;br /&gt;
  {haystack: &amp;quot;From: Marc Twain &amp;lt;Marc@ta...&amp;gt; - 2010-01-03 07:36:03&amp;quot;, needle: &amp;quot;Marc Twain&amp;quot;},&lt;br /&gt;
  {haystack: &amp;quot;From: George W. Bush &amp;lt;GWB@wh...&amp;gt; - 2055-11-11 17:33:13&amp;quot;, needle: &amp;quot;George W. Bush&amp;quot;}&lt;br /&gt;
];&lt;br /&gt;
  &lt;br /&gt;
// the regex we want to evolve&lt;br /&gt;
var solution = &amp;quot;From: (.*) &amp;lt;.*@.*&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// let's assume, we'd like to evolve a regex expression like this one&lt;br /&gt;
var userData = {&lt;br /&gt;
            solution: solution,&lt;br /&gt;
            tests: regexTests                         &lt;br /&gt;
};    &lt;br /&gt;
    &lt;br /&gt;
genetic.evolve(config, userData);&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
//console.log(&amp;quot;genetic.js is loaded and working, but disabled for now&amp;quot;);    &lt;br /&gt;
    &lt;br /&gt;
  &lt;br /&gt;
} // try&lt;br /&gt;
catch (e) {&lt;br /&gt;
  console.log(&amp;quot;genetic.js error:\n&amp;quot; +e.message);&lt;br /&gt;
} // catch&lt;br /&gt;
  &lt;br /&gt;
} // evolveExpression_test()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if(0) //TODO: expose via development tab&lt;br /&gt;
try {&lt;br /&gt;
  // https://github.com/cazala/synaptic&lt;br /&gt;
  var Neuron = synaptic.Neuron,&lt;br /&gt;
    Layer = synaptic.Layer,&lt;br /&gt;
    Network = synaptic.Network,&lt;br /&gt;
    Trainer = synaptic.Trainer,&lt;br /&gt;
    Architect = synaptic.Architect;&lt;br /&gt;
  &lt;br /&gt;
  function Perceptron(input, hidden, output)&lt;br /&gt;
{&lt;br /&gt;
    // create the layers&lt;br /&gt;
    var inputLayer = new Layer(input);&lt;br /&gt;
    var hiddenLayer = new Layer(hidden);&lt;br /&gt;
    var outputLayer = new Layer(output);&lt;br /&gt;
&lt;br /&gt;
    // connect the layers&lt;br /&gt;
    inputLayer.project(hiddenLayer);&lt;br /&gt;
    hiddenLayer.project(outputLayer);&lt;br /&gt;
&lt;br /&gt;
    // set the layers&lt;br /&gt;
    this.set({&lt;br /&gt;
        input: inputLayer,&lt;br /&gt;
        hidden: [hiddenLayer],&lt;br /&gt;
        output: outputLayer&lt;br /&gt;
    });&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// extend the prototype chain&lt;br /&gt;
Perceptron.prototype = new Network();&lt;br /&gt;
Perceptron.prototype.constructor = Perceptron;&lt;br /&gt;
  &lt;br /&gt;
var myPerceptron = new Perceptron(2,3,1);&lt;br /&gt;
var myTrainer = new Trainer(myPerceptron);&lt;br /&gt;
&lt;br /&gt;
myTrainer.XOR(); // { error: 0.004998819355993572, iterations: 21871, time: 356 }&lt;br /&gt;
&lt;br /&gt;
myPerceptron.activate([0,0]); // 0.0268581547421616&lt;br /&gt;
myPerceptron.activate([1,0]); // 0.9829673642853368&lt;br /&gt;
myPerceptron.activate([0,1]); // 0.9831714267395621&lt;br /&gt;
myPerceptron.activate([1,1]); // 0.02128894618097928&lt;br /&gt;
  &lt;br /&gt;
   &lt;br /&gt;
console.log(&amp;quot;Syntaptic loaded&amp;quot;);&lt;br /&gt;
} catch(e) {&lt;br /&gt;
  UI.alert(e.message);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Appendix}}&lt;/div&gt;</summary>
		<author><name>Elgaton</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=FlightGear_wiki:Instant-Refs&amp;diff=98423</id>
		<title>FlightGear wiki:Instant-Refs</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=FlightGear_wiki:Instant-Refs&amp;diff=98423"/>
		<updated>2016-05-20T12:24:45Z</updated>

		<summary type="html">&lt;p&gt;Elgaton: /* Usage */ Pressing Ctrl+C is no longer needed&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Quotes-logo-200x200.png|thumb]]&lt;br /&gt;
[[File:Instant-cquotes-firefox.png|thumb|Instant-Cquotes script in Firefox]]&lt;br /&gt;
&lt;br /&gt;
[[File:Ref-only-quotes.png|thumb|Instant-Cquotes screenshot prototyping runtime format selection]]&lt;br /&gt;
&lt;br /&gt;
The '''Instant-Cquotes''' script is a browser addon (user script) implemented in JavaScript in order to convert excerpts (created via copy&amp;amp;paste) from FlightGear forum or [[mailing list]] postings into MediaWiki markup/quotes to be used on the FlightGear wiki. It is supported by Firefox, Google Chrome/Chromium, Opera and Safari. It is being developed and maintained by a group of volunteers involved in maintaining the wiki and in trying to provide more up-to-date information to end-users who may not be as involved in the various FlightGear-related communication channels.&lt;br /&gt;
&lt;br /&gt;
== Background and motivation ==&lt;br /&gt;
FlightGear's development is, at best, &amp;quot;self-coordinated&amp;quot;, meaning that contributors discuss ideas and make proposals to contribute in a certain fashion and then team up to implement certain features and building blocks, often just temporarily.&lt;br /&gt;
&lt;br /&gt;
Unfortunately, due to a lack of development manpower, many ideas are not implemented immediately; it is, thus, important to know their pros and cons, as well as who originally proposed them and/or might help with their implementation, even after a long time, preferably with links to the original discussions so that new contributors can decide whether to get involved in some effort or not. The project documentation, however, is in great need of improvement&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
| url    = http://sourceforge.net/p/flightgear/mailman/message/15444440/&lt;br /&gt;
| title  = &amp;lt;nowiki&amp;gt;[Flightgear-devel] development process (was:  chaos...)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| author = &amp;lt;nowiki&amp;gt;John Denker&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| date   = Jul 16th, 2007&lt;br /&gt;
| added   = Jul 16th, 2007&lt;br /&gt;
| script_version = 0.23&lt;br /&gt;
}}&amp;lt;/ref&amp;gt; and usually significantly lacking behind:&amp;lt;ref name=&amp;quot;OlsonStateThingsFG&amp;quot;&amp;gt;{{cite web&lt;br /&gt;
| url    = http://sourceforge.net/p/flightgear/mailman/message/27861667/&lt;br /&gt;
| title  = &amp;lt;nowiki&amp;gt;Re: [Flightgear-devel] The state of things in Flight Gear&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| author = &amp;lt;nowiki&amp;gt;Curtis Olson&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| date   = Jul 27th, 2011&lt;br /&gt;
| added   = Jul 27th, 2011&lt;br /&gt;
| script_version = 0.23&lt;br /&gt;
}}&amp;lt;/ref&amp;gt; many core developers update it seldomly, if not anymore, as it takes time to write it, as well as an understanding of the inner workings of a complex system such as FlightGear. Furthermore, this task might not be attractive due to its short term impact on the project,&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
| url    = http://sourceforge.net/p/flightgear/mailman/message/27861562/&lt;br /&gt;
| title  = &amp;lt;nowiki&amp;gt;Re: [Flightgear-devel] The state of things in Flight Gear&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| author = &amp;lt;nowiki&amp;gt;Hal V. Engel&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| date   = Jul 27th, 2011&lt;br /&gt;
| added   = Jul 27th, 2011&lt;br /&gt;
| script_version = 0.23&lt;br /&gt;
}}&amp;lt;/ref&amp;gt; and it is overwhelming to think about creating documentation that would address the needs of many different kinds of contributors with different backgrounds, experience levels and goals.&amp;lt;ref name=&amp;quot;OlsonStateThingsFG&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Forum and mailing lists discussions have therefore become the only up-to-date (albeit difficult to filter)&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
| url    = http://forum.flightgear.org/viewtopic.php?p=280058#p280058&lt;br /&gt;
| title  = &amp;lt;nowiki&amp;gt;Re: quoting on the wiki&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| author = &amp;lt;nowiki&amp;gt;Thorsten&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| date   = Mar 21st, 2016&lt;br /&gt;
| added   = Mar 21st, 2016&lt;br /&gt;
| script_version = 0.25&lt;br /&gt;
}}&amp;lt;/ref&amp;gt; source of information about recent development progress; this makes it tricky to know what is going on, what needs fixing, what were the decisions taken by the developers.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
| url    = https://www.mail-archive.com/flightgear-devel%40lists.sourceforge.net/msg17198.html&lt;br /&gt;
| title  = &amp;lt;nowiki&amp;gt;[Flightgear-devel] Project tracking&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| author = &amp;lt;nowiki&amp;gt;James Turner&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| date   = Mon, 28 Jul 2008 10:06:05 -0700&lt;br /&gt;
}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The aim of the Instant-Cquotes script is to help wiki editors to copy relevant excerpts from such sources, formatting them as proper [[Template:Cquote|quotations]], and bootstrap new articles collecting them until a dedicated rewrite is made. It can also be used to reuse announcements to update the changelogs, [[Next newsletter|newsletter]] or the [[Release plan/Lessons learned]] page.&lt;br /&gt;
&lt;br /&gt;
After being away from the wiki system for some time it becomes more of an effort to re-learn how to start a new file and figure out how to format it , with what headings, etc. Sometimes it is almost too much to do the original write up of the original post and all the work of that layout and effort to have to also duplicate it in a wiki article. If I was a little more current and affluent with the wiki editor, I might not be so hesitant to create the work there instead of the forum.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=284698#p284698 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Breaking down NLCD raster image &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; wlbragg &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  May 9th, 2016 &lt;br /&gt;
  |added  =  May 9th, 2016 &lt;br /&gt;
  |script_version = 0.38 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In a few cases, such collections of quotes helped not only create bootstrap new articles, but even actual features.&lt;br /&gt;
&lt;br /&gt;
In other cases, quotes have been used to update documentation of features (e.g. [[Rembrandt]]) whose maintainers may not be actively involved in FlightGear, to help document discussions that are taking place in the meantime, and provide some background information for people interested in the corresponding feature.&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
# Install a user script manager. On Firefox, you can use [https://addons.mozilla.org/en-US/firefox/addon/greasemonkey/ Greasemonkey]; on Chrome/Chromium, Opera or Safari, you can use [https://tampermonkey.net/ Tampermonkey] (download links: [https://tampermonkey.net/index.php?ext=dhdg&amp;amp;browser=chrome Chrome/Chromium], [https://tampermonkey.net/index.php?ext=dhdg&amp;amp;browser=opera Opera], [https://tampermonkey.net/index.php?ext=dhdg&amp;amp;browser=safari Safari]).&lt;br /&gt;
# Visit [https://greasyfork.org/en/scripts/19331-instant-cquotes the Instant-Cquotes page on GreasyFork] and click on {{button|Install this script}} (green button). If Greasemonkey/Tampermonkey prompts you to confirm the installation, agree to do so.&lt;br /&gt;
&lt;br /&gt;
[[File:Howto-install-instant-cquotes.png|thumb|Click the green button to install the script]]&lt;br /&gt;
&lt;br /&gt;
=== Manual installation ===&lt;br /&gt;
{{note|This will install the most recent development version of the script, which might contain bugs. Also, GreaseMonkey/TamperMonkey will not update it automatically whenever a new version is released.}}&lt;br /&gt;
&lt;br /&gt;
* '''Firefox'''&lt;br /&gt;
# Install Greasemonkey.&lt;br /&gt;
# Save [[#The Script|the script]] below as &amp;lt;code&amp;gt;instant_cquotes.user.js&amp;lt;/code&amp;gt;, then drag-and-drop it into Firefox.&lt;br /&gt;
[[File:Greasemonkey-setup-on-firefox.png|thumb|Screenshot showing the Greasemonkey setup dialog (on Firefox)]]&lt;br /&gt;
&lt;br /&gt;
* '''Chrome/Chromium''', '''Opera''', or '''Safari'''&lt;br /&gt;
# Install Tampermonkey.&lt;br /&gt;
# Navigate to '''Add a new Script'''.&lt;br /&gt;
# Copy and paste [[#The Script|the script]] below into the editing window.&lt;br /&gt;
# Click the {{button|Save}} button (just above the {{button|Search}} button).&lt;br /&gt;
&lt;br /&gt;
=== Mobile installation ===&lt;br /&gt;
As of May 2016, there is no separate version available for mobile use. Your best chance is installing a userscript addon on Android, like one of those:&lt;br /&gt;
* [https://play.google.com/store/apps/details?id=net.biniok.tampermonkey Tampermonkey (Google Play Store)]&lt;br /&gt;
* [http://oilcan.jsharkey.org/ OilCan: Greasemonkey on steroids for Android]&lt;br /&gt;
&lt;br /&gt;
For installation instructions, refer to [https://openuserjs.org/about/Tampermonkey-for-Android Tampermonkey for Android] or [http://www.blogtechnika.com/how-to-access-greasemonkey-scripts-on-android-phones/ How To Access Greasemonkey Scripts on Android Phones].&lt;br /&gt;
&lt;br /&gt;
Testing/feedback would obviously be appreciated - if in doubt, feel free to just edit the wiki page to add your findings/questions.&lt;br /&gt;
&lt;br /&gt;
=== Configuration ===&lt;br /&gt;
[[File:User-script-menu.png|thumb|GreaseMonkey menu shown in FireFox with instanct cquotes menu items]]&lt;br /&gt;
&lt;br /&gt;
[[File:Config-dialog-instant-cquotes.png|thumb|The configuration dialog for the Instant-Cquotes script]]&lt;br /&gt;
&lt;br /&gt;
As of version 0.30, a dedicated configuration dialog is in the process of being added, so that certain script features can be dynamically configured, without having to edit the script. For now, this is merely a placeholder that provides a checkbox to easily enable/disable the debug mode. In the future, we are hoping to also expose other features this way.&lt;br /&gt;
&lt;br /&gt;
== Usage ==&lt;br /&gt;
[[File:Updated-cquotes-script-by-redleader.png|thumb|Instant-Cquotes script, with updates contributed by Red Leader]]&lt;br /&gt;
&lt;br /&gt;
[[File:New-cquotes.png|thumb|Screenshot showing Instant-Cquotes 0.30 at work]]&lt;br /&gt;
&lt;br /&gt;
# Go to some [[mailing list]] archive URL, for example [http://sourceforge.net/p/flightgear/mailman/message/32400727/] or any forum message, such as {{forumref|title=Re: Get objects to show up on Map/Radar|t=23299|label=p212558|f=71}}.&lt;br /&gt;
# Select the relevant portion of text.&lt;br /&gt;
# When you release the mouse button, a box will appear containing the converted text (for now, mainly properly-referenced quotes for the wiki).&lt;br /&gt;
# The text will be automatically selected and copied to the clipboard.&lt;br /&gt;
# Paste the text into the desired wiki page.&lt;br /&gt;
&lt;br /&gt;
For example, by selecting part of the forum post in the link above you can get the following quotation:&lt;br /&gt;
&lt;br /&gt;
{{FGCquote&lt;br /&gt;
|1= The upcoming FlightGear version (3.2) will contain a canvas-based map dialog, including a modular &amp;quot;plugin&amp;quot; system for creating custom map layers and charts with roughly ~50 lines of code, most of it boilerplate. &lt;br /&gt;
This is entirely XML/Nasal based (scripted) - symbols can be pretty much anything, raster or vector images (png or svg), but even animated. Styling can be customied, too.&lt;br /&gt;
For more info, I suggest to check out:&lt;br /&gt;
[[MapStructure#Porting the map dialog]]&lt;br /&gt;
&lt;br /&gt;
[[File:MapStructureDialog.png|250px]]&lt;br /&gt;
|2= {{cite web&lt;br /&gt;
  | url    = http://forum.flightgear.org/viewtopic.php?p=212558#p212558&lt;br /&gt;
  | title  = &amp;lt;nowiki&amp;gt;Re: Get objects to show up on Map/Radar&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  | author = &amp;lt;nowiki&amp;gt;Hooray&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  | date   = Jun 14th, 2014&lt;br /&gt;
  }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== On quoting ===&lt;br /&gt;
{{Main article|FlightGear wiki:Quoting Guidelines}}&lt;br /&gt;
&lt;br /&gt;
Using the Instant-Cquotes script is a good way to bootstrap and write some preliminary notes; however, while quotes might be useful to understand how undocumented subsystems and features work and are definitely better than nothing, they are not meant to replace proper, structured and well-written wiki articles.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
| url    = http://forum.flightgear.org/viewtopic.php?p=282800#p282800&lt;br /&gt;
| title  = &amp;lt;nowiki&amp;gt;Re: What is the QT launcher?&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| author = &amp;lt;nowiki&amp;gt;bugman&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| date   = Apr 17th, 2016&lt;br /&gt;
| added   = Apr 17th, 2016&lt;br /&gt;
| script_version = 0.25&lt;br /&gt;
}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One way to convert pages bootstrapped using quotes is to extract relevant information from them and keep citations only as references; in case important details are missing, they can be asked for on the [[Mailing lists|mailing lists]] (on the forum, the chance to get a complete answer might be lower).&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
| url    = http://sourceforge.net/p/flightgear/mailman/message/34954385/&lt;br /&gt;
| title  = &amp;lt;nowiki&amp;gt;Re: [Flightgear-devel] Wiki Quotes&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| author = &amp;lt;nowiki&amp;gt;James Turner&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| date   = Mar 21st, 2016&lt;br /&gt;
| added   = Mar 21st, 2016&lt;br /&gt;
| script_version = 0.25&lt;br /&gt;
}}&amp;lt;/ref&amp;gt; Another option might be moving the quotes to the Talk page for each entry, which would preserve the sources without clogging up the articles.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
| url    = http://sourceforge.net/p/flightgear/mailman/message/34948989/&lt;br /&gt;
| title  = &amp;lt;nowiki&amp;gt;Re: [Flightgear-devel] Wiki Quotes&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| author = &amp;lt;nowiki&amp;gt;Stuart Buchanan&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| date   = Mar 19th, 2016&lt;br /&gt;
| added   = Mar 19th, 2016&lt;br /&gt;
| script_version = 0.25&lt;br /&gt;
}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As a matter of fact, the whole paragraph above was assembled using this approach; to see for yourself, look up the references at the end of this page. For another example, see [[TerraSync#News]].&lt;br /&gt;
&lt;br /&gt;
== Development ==&lt;br /&gt;
{{Note|A Chrome/Chromium-specific extension that will not need Tampermonkey installed is under development.}}&lt;br /&gt;
&lt;br /&gt;
=== Resources ===&lt;br /&gt;
* https://www.mediawiki.org/wiki/API:Changing_wiki_content&lt;br /&gt;
* https://www.mediawiki.org/wiki/API:Edit&lt;br /&gt;
&lt;br /&gt;
=== Adding sources ===&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
{{WIP}}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
Adding a new source is pretty straightforward if you understand how xpath and regexes work - basically, you only need an archive (e.g. gmane), and then determine the xpath of each relevant field, as well as the regular expression to process the extracted fields (optional).&lt;br /&gt;
&lt;br /&gt;
The basic steps are these:&lt;br /&gt;
# open the user script in an editor&lt;br /&gt;
# navigate to the meta header of the user script&lt;br /&gt;
# add a new URL to the top of the script, e.g. by copying/adapting an existing line like this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// @match       https://sourceforge.net/p/flightgear/mailman/*&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once copied, add the new URL:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// @match       http://thread.gmane.org/gmane.games.flightgear.devel/*&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next, you need to navigate to the configuration hash to add a new website to it. &lt;br /&gt;
&lt;br /&gt;
Again, it makes sense to simply take an existing configuration hash and adapt it as needed (ignore/omit the tests vector for now by keeping it empty):&lt;br /&gt;
&lt;br /&gt;
{{Caution|the following example may meanwhile be outdated, so be sure to look at the actual code instead}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  'Sourceforge Mailing list': {&lt;br /&gt;
    enabled: true,&lt;br /&gt;
    type: 'archive',&lt;br /&gt;
    event: 'document.onmouseup', // when to invoke the event handler&lt;br /&gt;
    event_handler: instantCquote, // the event handler to be invoked&lt;br /&gt;
    url_reg: '^(http|https)://sourceforge.net/p/flightgear/mailman/.*/',&lt;br /&gt;
    content: {&lt;br /&gt;
      xpath: 'tbody/tr[2]/td/pre/text()',&lt;br /&gt;
      selection: getSelectedText,&lt;br /&gt;
      idStyle: /msg[0-9]{8}/,&lt;br /&gt;
      parentTag: [&lt;br /&gt;
        'tagName',&lt;br /&gt;
        'PRE'&lt;br /&gt;
      ],&lt;br /&gt;
    transform: [] // vector with transformation callbacks&lt;br /&gt;
    }, // content recipe&lt;br /&gt;
    // vector with tests to be executed for sanity checks (unit testing)&lt;br /&gt;
    tests: [&lt;br /&gt;
    ], // end of vector with self-tests&lt;br /&gt;
    // regex/xpath and transformations for extracting various required fields&lt;br /&gt;
    author: {&lt;br /&gt;
      xpath: 'tbody/tr[1]/td/div/small/text()',&lt;br /&gt;
      transform: [extract(/From: (.*) &amp;lt;.*@.*&amp;gt;/)]&lt;br /&gt;
    },&lt;br /&gt;
    title: {&lt;br /&gt;
      xpath: 'tbody/tr[1]/td/div/div[1]/b/a/text()'&lt;br /&gt;
      transform: []&lt;br /&gt;
    },&lt;br /&gt;
    date: {&lt;br /&gt;
      xpath: 'tbody/tr[1]/td/div/small/text()',&lt;br /&gt;
      transform: [extract(/- (.*-.*-.*) /)]&lt;br /&gt;
    },&lt;br /&gt;
    url: {&lt;br /&gt;
      xpath: 'tbody/tr[1]/td/div/div[1]/b/a/@href',&lt;br /&gt;
      transform: [prepend('https://sourceforge.net')]&lt;br /&gt;
    }&lt;br /&gt;
  }, // end of mailing list profile&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, we need to review/adapt the profile according to the new archive we'd like to see supported. &lt;br /&gt;
&lt;br /&gt;
for starters, that means:&lt;br /&gt;
* changing the name of the profile, e.g. to read gmane (instead of sourceforge)&lt;br /&gt;
* change the '''url_reg''' field to the gmane URL (this can be a regular expression)&lt;br /&gt;
&lt;br /&gt;
Next, it makes sense to use an [https://addons.mozilla.org/de/firefox/addon/xpath-checker/ XPath checker], so that we can look up the xpath expression for various HTML elements, and add those to the configuration hash above.&lt;br /&gt;
&lt;br /&gt;
For testing purposes, you will probably go to the setup dialog and enable the DEBUG mode, and use your browser's console to see what is going on.&lt;br /&gt;
&lt;br /&gt;
=== Getting involved ===&lt;br /&gt;
While having some experience with JavaScript/HTML and jQuery will definitely be useful, JavaScript is close enough to FlightGear scripting ([[Nasal]]), so that people can get involved pretty easily. &lt;br /&gt;
&lt;br /&gt;
Most maintenance work will typically involve reviewing/maintaining a few configuration hashes, that contain meta information for each supported archive (mailing list/forum).&lt;br /&gt;
&lt;br /&gt;
Usually, each hash contains a combination of xpath/regex expressions to look up the relevant information, as well as vector of optional transformations that are applied (in order) to convert contents to a different format (e.g. dates).&lt;br /&gt;
&lt;br /&gt;
In addition, there is growing library of utility functions, a handful wrappers for useful stuff, for example:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;Host.dbLog(message_string)&amp;lt;/code&amp;gt; - log a message to the console if the DEBUG flag is set&lt;br /&gt;
* &amp;lt;code&amp;gt;Host.download(url, callback, method='GET')&amp;lt;/code&amp;gt; - will download the URL and pass the downloaded content to the callback specified&lt;br /&gt;
* &amp;lt;code&amp;gt;Host.downloadPosting(url, callback)&amp;lt;/code&amp;gt; - will download the posting URL and pass the extracted and transformed author/content and date fields in a hash to the callback specified, the URL must be one supported in the CONFIG hash (i.e. forum/sourceforge for now)&lt;br /&gt;
* &amp;lt;code&amp;gt;Host.make_doc(string, type=&amp;quot;text/html&amp;quot;)&amp;lt;/code&amp;gt; - will turn a string/blob into a DOM that can be queried&lt;br /&gt;
* &amp;lt;code&amp;gt;Host.eval_xpath(document, xpath_expression, type=XPathResult.STRING_TYPE)&amp;lt;/code&amp;gt; - will apply the xpath expression to the document specified, returning the requested type (defaulted to string) &lt;br /&gt;
* &amp;lt;code&amp;gt;Host.set_persistent(key,value)&amp;lt;/code&amp;gt;  - stores a key/value pair&lt;br /&gt;
* &amp;lt;code&amp;gt;Host.get_persistent(key,default_value)&amp;lt;/code&amp;gt; - retrieves a values using the key specified, falling back to the default value&lt;br /&gt;
&lt;br /&gt;
=== Porting ===&lt;br /&gt;
[[File:Instant-cquote-firefox-addon-mode.png|thumb|Prototyping a dedicated instant-cquote mode for use as a firefox addon]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Porting the script to support other browsers/script engines is greatly appreciated. Typically, this should be pretty self-contained, because all main APIs are intended to be encapsulated in a so called &amp;quot;Environment&amp;quot; hash, where APIs that are specific to a particular browser/script engine should be provided with a wrapper. As of mid 2016, most APIs are now kept inside such an Environment hash (look at the GreaseMonkey hash for reference/details), so that it is now even possible to turn the script into a standalone FireFox addon without having to change much of the underlying code.&lt;br /&gt;
&lt;br /&gt;
=== Self checks (unit testing) ===&lt;br /&gt;
For regression testing purposes, there's a dedicated &amp;quot;self check&amp;quot; dialog that will be extended over time. For now it will download a few profile/website specific postings using a vector called &amp;quot;tests&amp;quot; and then log the posting's title, author and date to the console.&lt;br /&gt;
&lt;br /&gt;
The next step will be  actually showing that information in the dialog itself - there's a separate helper function to accomplish that, so that the corresponding div layer can be updated with the results.&lt;br /&gt;
&lt;br /&gt;
[[File:Sanity-check-cquotes-dialog.png|thumb|automatically executed sanity checks]]&lt;br /&gt;
&lt;br /&gt;
=== Debug mode ===&lt;br /&gt;
[[File:Instant-cquotes-debug-mode.png|thumb|Instant-Cquotes debug mode]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== AJAX (live page editing) ===&lt;br /&gt;
{{WIP}}&lt;br /&gt;
&lt;br /&gt;
* http://wiki.flightgear.org/api.php&lt;br /&gt;
* http://wiki.flightgear.org/api.php?action=parse&amp;amp;page=Frequently%20asked%20questions&amp;amp;prop=sections&lt;br /&gt;
&lt;br /&gt;
For now, the setup dialog will try to obtain a login token for the wiki and show a message if successful.&lt;br /&gt;
&lt;br /&gt;
In addition, the profile/website hash also contains a new wiki entry for the FlightGear wiki, whose '''event_handler''' callback will be invoked once the FG wiki is visited - the console/log will show a greeting, so that is where other code can be added - e.g. to help clean up/rewrite FGCquote-based articles automatically etc.&lt;br /&gt;
&lt;br /&gt;
There is a vector of &amp;quot;modes&amp;quot;, whose members are a hash containing trigger/handler fields, linked to two callbacks - the trigger callback can be used to check some condition, while the handler will be invoked if the trigger returns true.&lt;br /&gt;
&lt;br /&gt;
This can be used to support an arbitrary number of modes, whose triggers are evaluated during page load - all triggers that return true, will have their handlers invoked, which is how the following snippet works to rewrite/augment wiki edit handles:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;gt;&lt;br /&gt;
 'FlightGear.wiki': {&lt;br /&gt;
    type: 'wiki',&lt;br /&gt;
    enabled: false,&lt;br /&gt;
    event: 'document.onmouseup', // when to invoke the event handler&lt;br /&gt;
    event_handler: function () {&lt;br /&gt;
      console.log('FlightGear wiki handler active (waiting to be populated)');&lt;br /&gt;
      // this is where the logic for a wiki mode can be added over time (for now, it's a NOP)&lt;br /&gt;
    &lt;br /&gt;
    //for each supported mode, invoke the trigger and call the corresponding handler&lt;br /&gt;
    [].forEach.call(CONFIG['FlightGear.wiki'].modes, function(mode) {&lt;br /&gt;
      //dbLog(&amp;quot;Checking trigger:&amp;quot;+mode.name);&lt;br /&gt;
      if(mode.trigger) {&lt;br /&gt;
        mode.handler();&lt;br /&gt;
      }&lt;br /&gt;
    });&lt;br /&gt;
      &lt;br /&gt;
    }, // the event handler to be invoked&lt;br /&gt;
    url_reg: '^(http|https)://wiki.flightgear.org', // ignore for now: not currently used by the wiki mode&lt;br /&gt;
    &lt;br /&gt;
    modes: [&lt;br /&gt;
      { name:'process-editSections',&lt;br /&gt;
        trigger: function() {return true;}, // match URL regex - return true for always match&lt;br /&gt;
       &lt;br /&gt;
        // the code implementing the mode&lt;br /&gt;
        handler: function() {&lt;br /&gt;
                &lt;br /&gt;
    var editSections = document.getElementsByClassName('mw-editsection');&lt;br /&gt;
    console.log('FlightGear wiki article, number of edit sections: '+editSections.length);&lt;br /&gt;
   &lt;br /&gt;
    // for now, just rewrite edit sections and add a note to them&lt;br /&gt;
   &lt;br /&gt;
     [].forEach.call(editSections, function (sec) {&lt;br /&gt;
       sec.appendChild(&lt;br /&gt;
         document.createTextNode(' (instant-cquotes is lurking) ')&lt;br /&gt;
       );&lt;br /&gt;
     }); //forEach section&lt;br /&gt;
        } // handler&lt;br /&gt;
       &lt;br /&gt;
       &lt;br /&gt;
      } // process-editSections&lt;br /&gt;
      // TODO: add other wiki modes below &lt;br /&gt;
      &lt;br /&gt;
    ] // modes&lt;br /&gt;
    &lt;br /&gt;
  }, // end of wiki profile&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See [[User:Red Leader/Sandbox/AJAX test]]&lt;br /&gt;
&lt;br /&gt;
* https://www.mediawiki.org/wiki/API:Changing_wiki_content&lt;br /&gt;
* https://www.mediawiki.org/wiki/Extension:VisualEditor&lt;br /&gt;
* https://en.wikipedia.org/wiki/Wikipedia:Creating_a_bot&lt;br /&gt;
&lt;br /&gt;
=== Mobile edition ===&lt;br /&gt;
{{Note|As of 02/2016, Hooray is contemplating to make this available as an addon for Android phones.}}&lt;br /&gt;
&lt;br /&gt;
=== Issues/limitations ===&lt;br /&gt;
==== Bugs ====&lt;br /&gt;
* It's eating characters, apparently related to regex/xpath handling - e.g. words like &amp;quot;analyzing&amp;quot; are turned into &amp;quot;analying&amp;quot; [http://forum.flightgear.org/viewtopic.php?f=6&amp;amp;t=28378&amp;amp;p=270735&amp;amp;hilit=analyzing#p270735]&lt;br /&gt;
==== Non working URLs ====&lt;br /&gt;
* image matching/extraction: http://forum.flightgear.org/viewtopic.php?p=276221#p276221&lt;br /&gt;
* http://sourceforge.net/p/flightgear/mailman/message/34754961/&lt;br /&gt;
* http://forum.flightgear.org/viewtopic.php?f=18&amp;amp;t=27054&amp;amp;start=90#p273972 → selecting from “As promised, two sample installation sessions on Linux” to “That's it.” towards the end of the message causes Iceweasel (Firefox) 44.0.2 to display a dialog box reading “A script on this page may be busy, or it may have stopped responding. You can stop the script now, open the script in the debugger, or let the script continue.” The line below reads “Script: chrome://greasemonkey-modules/...quotes/instant_cquotes.user.js:544”. Choosing ''Continue'' doesn't help: the same message reappears a few seconds afterwards.&lt;br /&gt;
&lt;br /&gt;
=== Feature requests &amp;amp; ideas ===&lt;br /&gt;
* try to recognize list items [https://sourceforge.net/p/flightgear/mailman/message/35095319/] (heuristics: look for colon/asterisk, dashes and CR/LF)&lt;br /&gt;
* should add [[Template:News]] to the article dropdown for announcements [http://wiki.flightgear.org/index.php?title=Template:News&amp;amp;oldid=98266]&lt;br /&gt;
* add a mode that will download screenshots from forum postings and automatically upload/categorize them, see [[Birds]]&lt;br /&gt;
* split the article dropdown into sections, and also populate it with the user's watchlist [https://www.mediawiki.org/wiki/API:Watchlist] {{Progressbar|60}}&lt;br /&gt;
* mailing list templates, listed at [http://wiki.flightgear.org/Template_talk:Project_infrastructure#Related_mailing_list_templates]&lt;br /&gt;
* expose the cquote/ref markup via the UI so that it can be edited/customized and treated like a template {{Done}} (0.36+)&lt;br /&gt;
* identify common/repeated links and automatically create [[Template:Project infrastructure|link/infrastructure templates]] and use those (should be straightforward using the AJAX mode) [http://wiki.flightgear.org/index.php?title=Mailing_lists&amp;amp;curid=2038&amp;amp;diff=97876&amp;amp;oldid=85252]&lt;br /&gt;
* add a devel/maintainer mode where it will return the xpath for a selection [http://stackoverflow.com/questions/361130/get-selected-text-and-selected-nodes-on-a-page] [http://stackoverflow.com/questions/12485334/get-surrounding-dom-node-of-selection]&lt;br /&gt;
* move openlink,dblog helpers to Environment hash {{Done}}&lt;br /&gt;
* identify CLI arguments like --aircraft=c172p and wrap them in between code tags &amp;lt;code&amp;gt;--aircraft=c172p&amp;lt;/code&amp;gt; [https://sourceforge.net/p/flightgear/mailman/message/35063277/] (note that we can simply download [https://sourceforge.net/p/flightgear/fgdata/ci/next/tree/options.xml options.xml] via openlink() and use that, which is kinda of neat...) {{Progressbar|60}} (see downloadOptionsXML() in the code)&lt;br /&gt;
* introduce &amp;quot;layouts&amp;quot; (templates) for different purposes: newsletter, changelog, wiki article, [[The Manual]] (LaTex)  ? {{Progressbar|40}}&lt;br /&gt;
* use wikipedia template if possible [https://sourceforge.net/p/flightgear/mailman/message/35057670/]&lt;br /&gt;
* the new '''tests''' vector could also contain vectors for tests to test the extract/transform* utilities, see Environment.APITests {{Progressbar|50}}&lt;br /&gt;
* move environment specific APIs (browser, script host etc) into some kind of Environment hash to encapsulate things (Red Leader was working on a pure Chrome-only version at some point IIRC) {{Progressbar|80}}&lt;br /&gt;
* encode script settings in created markup, for future processing/updating of quotes&lt;br /&gt;
* look up &amp;lt;code&amp;gt;[x]&amp;lt;/code&amp;gt; references and replace with the corresponding link (titled) [https://sourceforge.net/p/flightgear/mailman/message/35055331/] [https://sourceforge.net/p/flightgear/mailman/message/35062598/]&lt;br /&gt;
** convert footnotes into Abbr templates [http://article.gmane.org/gmane.games.flightgear.devel/78971]&lt;br /&gt;
* support named refs for combining identical refs [http://wiki.flightgear.org/index.php?title=FlightGear_Qt_launcher&amp;amp;curid=13693&amp;amp;diff=97562&amp;amp;oldid=97551]&lt;br /&gt;
* adopt [[Template:Forumref]]&lt;br /&gt;
* implement a less obnoxious quoting mode, without quotes, where only the ref part would be added, e.g. see the example at [[Graphics Card Profiles]] (it's still 99% quotes, but much less annoying) {{Done}}&lt;br /&gt;
* attachment support: identify attachments and link to them: [https://sourceforge.net/p/flightgear/mailman/message/11683451/] [https://sourceforge.net/p/flightgear/mailman/message/23906620/] [https://sourceforge.net/p/flightgear/mailman/message/35059842/] [https://sourceforge.net/p/flightgear/mailman/message/35067087/]&lt;br /&gt;
* bulletin points: if there is a colon (:) followed by at least two dashes (-), split up everything after the colon to turn each dash into an asterisk (wiki markup for bulletin points), followed by a newline [http://sourceforge.net/p/flightgear/mailman/message/34760165/]   &lt;br /&gt;
* generic URL/template matching, e.g. for for sourceforge commit IDs&lt;br /&gt;
* make filters/conversions configurable via checkboxes (nowiki, wrap in alert/note boxes)&lt;br /&gt;
* make syntax highlighting configurable (language, mode) ?&lt;br /&gt;
* consider using something like the Roles template to turn contributor names into tooltips where contributor roles are shown (core dev, fgdata committer etc)&lt;br /&gt;
* introduce support for tag clouds to help categorize/classify related quotes&lt;br /&gt;
* consider making transformations optional/configurable using check boxes in the jQuery dialog&lt;br /&gt;
* add new input method, for quotes that need to be updated/converted (added script version specifically for this purpose), should also add extraction/processing date&lt;br /&gt;
* investigate why not all mailing list archives/postings are supported correctly: http://sourceforge.net/p/flightgear/mailman/message/8090479/ (problem traced to &amp;lt;code&amp;gt;getPostID()&amp;lt;/code&amp;gt;)&lt;br /&gt;
* explore having a ref-only mode without using cquotes, i.e. just copy/paste quotes with proper ref tags and a references section, to rewrite the whole thing (possibly with templates for different purposes, e.g. newsletter/changelog) {{Done}}&lt;br /&gt;
* should use Template:Forumref (category:link templates)&lt;br /&gt;
* should be updated to use the new repo/flightgear file templates created by Johan &amp;amp; RedLeader {{Not done}}&lt;br /&gt;
* resolve links to forum threads to look up the title for the topic/posting, so that the posting's title can be used for those links, instead of just the URL - we can probably do that by making an AJAX call to open URLs asynchronously and extract the title for the thread/posting to come up with something like &amp;lt;code&amp;gt;[http://forum.flightgear.org/viewtopic.php?f=4&amp;amp;t=24421 A call to developers-Lockheed -L188 Electra]&amp;lt;/code&amp;gt; ([http://forum.flightgear.org/viewtopic.php?f=4&amp;amp;t=26562&amp;amp;p=247325&amp;amp;hilit=links#p247347]) {{Progressbar|50}}&lt;br /&gt;
* convert quoted bug tracker URLs to use the issue template on the wiki {{not done}}&lt;br /&gt;
* do regex/xpath validation, and display any errors (e.g. template/theme changes on the forum would currently break the script) {{Progressbar|60}}&lt;br /&gt;
* increased focus on supporting different output formats, maybe using a simple [http://www.jquery-steps.com/ jQuery based wizard] (wiki, forum, newsletter, changelog) {{Not done}}&lt;br /&gt;
* token matching for keywords/acronyms to link to the corresponding wiki articles (e.g. Nasal, Canvas, FG_ROOT, FG_HOME etc) {{Not done}}&lt;br /&gt;
* Add support for [http://sourceforge.net/p/flightgear/codetickets/ tickets], merge requests comments and [http://www.fguk.eu/index.php/forum/index FGUK forum]. (also see [[FlightGear wiki talk:Instant-Cquotes#more sources]])&lt;br /&gt;
* GET-encoded SID arguments should be stripped from forum URLs. {{Not done}}&lt;br /&gt;
* Links to repositories should be converted to use wiki templates. {{Not done}}&lt;br /&gt;
* The {{Abbr|regexes|regular expressions}} used may fail if the HTML DOM of the source changes (e.g., phpBB/theme update)&lt;br /&gt;
** Show a warning when that's the case. {{Progressbar|70}} (see the self-check dialog)&lt;br /&gt;
** Try multiple regexes in order. {{Progressbar|30}} (see the self-check dialog)&lt;br /&gt;
* Use the script to update previously created Cquotes automatically&lt;br /&gt;
** Instead of using the &amp;lt;code&amp;gt;getSelection()&amp;lt;/code&amp;gt; helper, we could register a match for &amp;lt;tt&amp;gt;wiki.flightgear.org&amp;lt;/tt&amp;gt; with &amp;lt;code&amp;gt;action=edit&amp;lt;/code&amp;gt; set, so that we can directly process all text of an edited page, using AJAX calls to open the URL in the background. {{Progressbar|40}} (see the self-check dialog, available via the greasemonkey menu)&lt;br /&gt;
** See [https://www.mediawiki.org/wiki/API:Edit#Editing_via_Ajax MW:API:Edit § Editing via Ajax]&lt;br /&gt;
&lt;br /&gt;
=== Changelog ===&lt;br /&gt;
{{Note|Contributors are invited to document their changes here, please also add your wiki handle so that others can more easily get in touch.}}&lt;br /&gt;
&lt;br /&gt;
* first stab at implementing unit tests by adding a vector with URLS to be downloaded and fields to be matched (WIP), shown in a jQuery dialog&lt;br /&gt;
* support for persistent settings and a jQuery setup dialog with persistence&lt;br /&gt;
* hosting is moved, to allow auto-updates [http://www.greasespot.net/2012/02/automatic-script-updates-come-to.html] [https://wiki.greasespot.net/Metadata_Block#.40updateURL] [http://stackoverflow.com/questions/15095055/why-isnt-my-greasemonkey-script-updating]&lt;br /&gt;
* changed to ref-only quotes for now, not using the FGCquote template anymore, due to its obnoxious appearance on quote-heavy pages (should probably become a runtime option instead)&lt;br /&gt;
* updated to use https for forum postings&lt;br /&gt;
* add version info to each created quote, i.e. for future updates&lt;br /&gt;
* add helper for opening websites asynchronously using AJAX (also via GM helper API)&lt;br /&gt;
* display version number in output dialog&lt;br /&gt;
* begin using the GreaseMonkey API for setting clipboard content&lt;br /&gt;
&lt;br /&gt;
== The script ==&lt;br /&gt;
&amp;lt;gallery mode=packed widths=230px heights=230px&amp;gt;&lt;br /&gt;
Instant-cquotes-revamped.png|Instant cquotes: Revamped user interface exposes script internals to make the script better configurable at runtime&lt;br /&gt;
Instant-cquotes-template-editor.png|Instant cquotes now features a simple built-in template editor with support for variable substitution, so that wiki templates can be more easily customized&lt;br /&gt;
Instant-cquotes-with-wikimedia-API-integration.png|Screenshot showing instant-cquotes with wikimedia API integration to fetch articles/sections and populate dropdown menus accordingly&lt;br /&gt;
Instant-cquotes-on-steroids-with-watchlist-support.png|Screenshot showing the JQuery-mode of the instant cquotes script with built-in support for fetching a user's wiki/watchlist to edit/update articles in a semi-automated fashion&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
{{PD-author|FlightGear contributors}}&lt;br /&gt;
&lt;br /&gt;
{{Note|Anybody interested in contributing to the code is invited to directly edit this wiki article. From 05/2016, the script is hosted on GreasyFork to allow automatic updates. If you'd like to see your changes applied, please bump the version number and [[User:Elgaton|Elgaton]] will upload it in the state it was when the version number was bumped. ''Make sure to perform thorough testing'' before the bump to prevent unexpected breakage; it is generally a good idea to validate your changes using an online syntax checker, e.g.:&lt;br /&gt;
* http://jshint.com/ &lt;br /&gt;
* http://esprima.org/demo/validate.html&lt;br /&gt;
* http://codebeautify.org/jsvalidate&lt;br /&gt;
&amp;lt;p/&amp;gt;Thank you!}}&lt;br /&gt;
&lt;br /&gt;
Changes that should be mentioned in the changelog, should be added below (and moved to the [[#Changelog]] section subsequently:&lt;br /&gt;
&lt;br /&gt;
* preparations for adding support to download fgdata related files like options.xml to automatically regex known CLI commands&lt;br /&gt;
* preparatory work for adding a speech-rewrite engine to assist in converting 1st person speech to 3rd person&lt;br /&gt;
* framework for encapsulating userscript specifics in an environment hash to provide better updating/porting support&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;// ==UserScript==&lt;br /&gt;
// @name        Instant-Cquotes&lt;br /&gt;
// @name:it     Instant-Cquotes&lt;br /&gt;
// @license     public domain&lt;br /&gt;
// @version     0.39&lt;br /&gt;
// @date        2016-05-05&lt;br /&gt;
// @description Automatically converts selected FlightGear mailing list and forum quotes into post-processed MediaWiki markup (i.e. cquotes).&lt;br /&gt;
// @description:it Converte automaticamente citazioni dalla mailing list e dal forum di FlightGear in marcatori MediaWiki (cquote).&lt;br /&gt;
// @author      Hooray, bigstones, Philosopher, Red Leader &amp;amp; Elgaton (2013-2016)&lt;br /&gt;
// @supportURL  http://wiki.flightgear.org/FlightGear_wiki:Instant-Cquotes&lt;br /&gt;
// @icon        http://wiki.flightgear.org/images/2/25/Quotes-logo-200x200.png&lt;br /&gt;
// @match       https://sourceforge.net/p/flightgear/mailman/*&lt;br /&gt;
// @match       http://sourceforge.net/p/flightgear/mailman/*&lt;br /&gt;
// @match       https://forum.flightgear.org/*&lt;br /&gt;
// @match       http://wiki.flightgear.org/*&lt;br /&gt;
// @namespace   http://wiki.flightgear.org/FlightGear_wiki:Instant-Cquotes&lt;br /&gt;
// @run-at      document-start&lt;br /&gt;
// @require     https://code.jquery.com/jquery-1.10.2.js&lt;br /&gt;
// @require     https://code.jquery.com/ui/1.11.4/jquery-ui.js&lt;br /&gt;
// @require     https://cdn.jsdelivr.net/genetic.js/0.1.14/dist.js&lt;br /&gt;
// @require     https://cdn.jsdelivr.net/synaptic/1.0.4/synaptic.min.js&lt;br /&gt;
// @resource    jQUI_CSS https://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css&lt;br /&gt;
// @resource    myLogo http://wiki.flightgear.org/images/2/25/Quotes-logo-200x200.png&lt;br /&gt;
// @grant       GM_registerMenuCommand&lt;br /&gt;
// @grant       GM_setValue&lt;br /&gt;
// @grant       GM_getValue&lt;br /&gt;
// @grant       GM_addStyle&lt;br /&gt;
// @grant       GM_getResourceText&lt;br /&gt;
// @grant       GM_getResourceURL&lt;br /&gt;
// @grant       GM_setClipboard&lt;br /&gt;
// @grant       GM_xmlhttpRequest&lt;br /&gt;
// @noframes&lt;br /&gt;
// ==/UserScript==&lt;br /&gt;
//&lt;br /&gt;
// This work has been released into the public domain by their authors. This&lt;br /&gt;
// applies worldwide.&lt;br /&gt;
// In some countries this may not be legally possible; if so:&lt;br /&gt;
// The authors grant anyone the right to use this work for any purpose, without&lt;br /&gt;
// any conditions, unless such conditions are required by law.&lt;br /&gt;
//&lt;br /&gt;
// This script has a number of dependencies that are implicitly satisfied when run as a user script &lt;br /&gt;
// via GreaseMonkey/TamperMonkey; however, these need to be explicitly handled when using a different mode (e.g. firefox/android):&lt;br /&gt;
// &lt;br /&gt;
// - jQuery - user interface (REQUIRED)&lt;br /&gt;
// - genetic-js - genetic programming (OPTIONAL/EXPERIMENTAL)&lt;br /&gt;
// - synaptic - neural networks (OPTIONAL/EXPERIMENTAL)&lt;br /&gt;
// &lt;br /&gt;
// &lt;br /&gt;
&lt;br /&gt;
/* Here are some TODOs&lt;br /&gt;
 * - support RSS feeds http://dir.gmane.org/gmane.games.flightgear.devel/&lt;br /&gt;
 * - move event handling/processing to the CONFIG hash&lt;br /&gt;
 * - use try/catch more widely&lt;br /&gt;
 * - wrap function calls in try/call for better debugging/diagnostics&lt;br /&gt;
 * - add helpers for [].forEach.call, map, apply and call&lt;br /&gt;
 * - replace for/in, for/of, let statements for better compatibility (dont require ES6)&lt;br /&gt;
 * - for the same reason, replace use of functions with default params &lt;br /&gt;
 * - isolate UI (e.g. JQUERY) code in UserInterface hash&lt;br /&gt;
 * - expose regex/transformations via the UI&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
'use strict';&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// TODO: move to GreaseMonkey/UI host&lt;br /&gt;
// prevent conflicts with jQuery used on webpages: https://wiki.greasespot.net/Third-Party_Libraries#jQuery&lt;br /&gt;
// http://stackoverflow.com/a/5014220&lt;br /&gt;
this.$ = this.jQuery = jQuery.noConflict(true);&lt;br /&gt;
&lt;br /&gt;
// this hash is just intended to help isolate UI specifics&lt;br /&gt;
// so that we don't need to maintain/port tons of code &lt;br /&gt;
&lt;br /&gt;
var UserInterface = {&lt;br /&gt;
  get: function() {&lt;br /&gt;
    return UserInterface.DEFAULT;&lt;br /&gt;
  },&lt;br /&gt;
  &lt;br /&gt;
 CONSOLE: {&lt;br /&gt;
   &lt;br /&gt;
 }, // CONSOLE (shell, mainly useful for testing)&lt;br /&gt;
  &lt;br /&gt;
 DEFAULT: {&lt;br /&gt;
  alert: function(msg) {return window.alert(msg);     },&lt;br /&gt;
  prompt: function(msg) {return window.prompt(msg);  }, &lt;br /&gt;
  confirm: function(msg) {return window.confirm(msg); },&lt;br /&gt;
  dialog: null,&lt;br /&gt;
  selection: null,&lt;br /&gt;
  populateWatchlist: function() {&lt;br /&gt;
    &lt;br /&gt;
  },&lt;br /&gt;
  populateEditSections: function() {&lt;br /&gt;
    &lt;br /&gt;
  }&lt;br /&gt;
 &lt;br /&gt;
 }, // default UI mapping (Browser/User script)&lt;br /&gt;
  &lt;br /&gt;
  JQUERY: {&lt;br /&gt;
    &lt;br /&gt;
  } // JQUERY &lt;br /&gt;
  &lt;br /&gt;
}; // UserInterface&lt;br /&gt;
&lt;br /&gt;
var UI = UserInterface.get(); // DEFAULT for now&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// This hash is intended to help encapsulate platform specifics (browser/scripting host)&lt;br /&gt;
// Ideally, all APIs that are platform specific should be kept here&lt;br /&gt;
// This should make it much easier to update/port and maintain the script in the future&lt;br /&gt;
var Environment = {&lt;br /&gt;
  getHost: function(xpi=false) {&lt;br /&gt;
 &lt;br /&gt;
     if(xpi) {&lt;br /&gt;
       Environment.scriptEngine = 'firefox addon';&lt;br /&gt;
       console.log('in firefox xpi/addon mode');&lt;br /&gt;
       return Environment.FirefoxAddon; // HACK for testing the xpi mode (firefox addon)&lt;br /&gt;
     }&lt;br /&gt;
    &lt;br /&gt;
    // This will determine the script engine in use: http://stackoverflow.com/questions/27487828/how-to-detect-if-a-userscript-is-installed-from-the-chrome-store&lt;br /&gt;
    if (typeof(GM_info) === 'undefined') {&lt;br /&gt;
    Environment.scriptEngine = &amp;quot;plain Chrome (Or Opera, or scriptish, or Safari, or rarer)&amp;quot;;&lt;br /&gt;
    // See http://stackoverflow.com/a/2401861/331508 for optional browser sniffing code.&lt;br /&gt;
   }&lt;br /&gt;
   else {&lt;br /&gt;
    Environment.scriptEngine = GM_info.scriptHandler  ||  &amp;quot;Greasemonkey&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
   console.log ('Instant cquotes is running on ' + Environment.scriptEngine + '.');&lt;br /&gt;
    &lt;br /&gt;
   //console.log(&amp;quot;not in firefox addon mode...&amp;quot;);&lt;br /&gt;
    // See also: https://wiki.greasespot.net/Cross-browser_userscripting&lt;br /&gt;
    return Environment.GreaseMonkey; // return the only/default host (for now)&lt;br /&gt;
  },&lt;br /&gt;
  &lt;br /&gt;
  validate: function(host) {&lt;br /&gt;
    if (host.get_persistent('startup.disable_validation',false)) return;&lt;br /&gt;
    &lt;br /&gt;
    if(Environment.scriptEngine !== &amp;quot;Greasemonkey&amp;quot;) &lt;br /&gt;
      console.log(&amp;quot;NOTE: This script has not been tested with script engines other than GreaseMonkey recently!&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    var dependencies = [&lt;br /&gt;
      {name:'jQuery', test: function() {} },&lt;br /&gt;
      {name:'genetic.js', test: function() {} },&lt;br /&gt;
      {name:'synaptic', test: function() {} },&lt;br /&gt;
    ];&lt;br /&gt;
    &lt;br /&gt;
    [].forEach.call(dependencies, function(dep) {&lt;br /&gt;
      console.log(&amp;quot;Checking for dependency:&amp;quot;+dep.name);&lt;br /&gt;
      var status=false;&lt;br /&gt;
      try {&lt;br /&gt;
      dep.test.call(undefined);&lt;br /&gt;
      status=true;&lt;br /&gt;
      }&lt;br /&gt;
      catch(e) {&lt;br /&gt;
      status=false;       &lt;br /&gt;
      }&lt;br /&gt;
      finally {&lt;br /&gt;
        var success = (status)?'==&amp;gt; success':'==&amp;gt; failed';&lt;br /&gt;
        console.log(success);&lt;br /&gt;
        return status;&lt;br /&gt;
      }&lt;br /&gt;
    });&lt;br /&gt;
  }, // validate&lt;br /&gt;
  &lt;br /&gt;
  // this contains unit tests for checking crucial APIs that must work for the script to work correctly&lt;br /&gt;
  // for the time being, most of these are stubs waiting to be filled in&lt;br /&gt;
  // for a working example, refer to the JSON test at the end&lt;br /&gt;
  // TODO: add jQuery tests&lt;br /&gt;
  APITests: [&lt;br /&gt;
     {name:'download', test: function(recipient) {recipient(true);}  },&lt;br /&gt;
     {name:'make_doc', test: function(recipient) { recipient(true);}   },&lt;br /&gt;
     {name:'eval_xpath', test: function(recipient) { recipient(true);} },&lt;br /&gt;
     {name:'JSON de/serialization', test: function(recipient) {&lt;br /&gt;
       //console.log(&amp;quot;running json test&amp;quot;);&lt;br /&gt;
       var identifier = 'unit_tests.json_serialization';&lt;br /&gt;
       var hash1 = {x:1,y:2,z:3};&lt;br /&gt;
       Host.set_persistent(identifier, hash1, true);&lt;br /&gt;
       var hash2 = Host.get_persistent(identifier,null,true);&lt;br /&gt;
       &lt;br /&gt;
       recipient(JSON.stringify(hash1) === JSON.stringify(hash2));&lt;br /&gt;
     } // callback &lt;br /&gt;
     },&lt;br /&gt;
    &lt;br /&gt;
    // downloads a posting and tries to transform it to 3rd person speech ...&lt;br /&gt;
    // TODO: add another test to check forum postings&lt;br /&gt;
    {name:'text/speech transformation', test: function(recipient) {&lt;br /&gt;
    &lt;br /&gt;
    // the posting we want to download&lt;br /&gt;
    var url='https://sourceforge.net/p/flightgear/mailman/message/35066974/';&lt;br /&gt;
    Host.downloadPosting(url, function (result) {&lt;br /&gt;
      &lt;br /&gt;
    // only process the first sentence by using comma/dot as delimiter&lt;br /&gt;
    var firstSentence = result.content.substring(result.content.indexOf(',')+1, result.content.indexOf('.'));&lt;br /&gt;
      &lt;br /&gt;
    var transformed = transformSpeech(firstSentence, result.author, null, speechTransformations );&lt;br /&gt;
    console.log(&amp;quot;3rd person speech transformation:\n&amp;quot;+transformed);   &lt;br /&gt;
    &lt;br /&gt;
    recipient(true);&lt;br /&gt;
    }); // downloadPosting() &lt;br /&gt;
        &lt;br /&gt;
  }// test()&lt;br /&gt;
    }, // end of speech transform test&lt;br /&gt;
    {&lt;br /&gt;
      name:&amp;quot;download $FG_ROOT/options.xml&amp;quot;, test: function(recipient) {&lt;br /&gt;
        downloadOptionsXML();&lt;br /&gt;
        recipient(true);&lt;br /&gt;
      } // test&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
  ], // end of APITests&lt;br /&gt;
  &lt;br /&gt;
  runAPITests: function(host, recipient) {&lt;br /&gt;
    console.log(&amp;quot;Running API tests&amp;quot;);&lt;br /&gt;
    for(let test of Environment.APITests ) {&lt;br /&gt;
      //var test = Environment.APITests[t];&lt;br /&gt;
      // invoke the callback passed, with the hash containing the test specs, so that the console/log or a div can be updated showing the test results&lt;br /&gt;
      &lt;br /&gt;
      recipient.call(undefined, test);&lt;br /&gt;
      &lt;br /&gt;
    } // foreach test&lt;br /&gt;
  }, // runAPITests&lt;br /&gt;
  &lt;br /&gt;
  /*&lt;br /&gt;
   * ===================================================================================================================================================&lt;br /&gt;
   *&lt;br /&gt;
   */&lt;br /&gt;
  &lt;br /&gt;
  // NOTE: This mode/environment is WIP and highly experimental ...&lt;br /&gt;
  // To see this working, you need to package up the whole file as a firefox xpi using &amp;quot;jpm xpi&amp;quot;&lt;br /&gt;
  // and then start the whole thing via &amp;quot;jpm run&amp;quot;, to do that, you also need a matching package.json (i.e. via jpm init) &lt;br /&gt;
  // ALSO: you will have to explicitly install any dependencies using jpm&lt;br /&gt;
  FirefoxAddon: {&lt;br /&gt;
  	init: function() {&lt;br /&gt;
		console.log(&amp;quot;Firefox addon mode ...&amp;quot;);&lt;br /&gt;
  	},&lt;br /&gt;
	getScriptVersion: function() {&lt;br /&gt;
		return '0.36'; // FIXME&lt;br /&gt;
	},&lt;br /&gt;
	dbLog: function(msg) {&lt;br /&gt;
		console.log(msg);&lt;br /&gt;
	},&lt;br /&gt;
	addEventListener: function(ev, cb) {&lt;br /&gt;
&lt;br /&gt;
	require(&amp;quot;sdk/tabs&amp;quot;).on(&amp;quot;ready&amp;quot;, logURL);&lt;br /&gt;
 	function logURL(tab) {&lt;br /&gt;
  		console.log(&amp;quot;URL loaded:&amp;quot; + tab.url);&lt;br /&gt;
	}	&lt;br /&gt;
	},&lt;br /&gt;
    &lt;br /&gt;
	registerConfigurationOption: function(name, callback, hook) {&lt;br /&gt;
	// https://developer.mozilla.org/en-US/Add-ons/SDK/Tutorials/Add_a_Context_Menu_Item&lt;br /&gt;
		console.log(&amp;quot;config menu support n/a in firefox mode&amp;quot;);&lt;br /&gt;
 // https://developer.mozilla.org/en-US/Add-ons/SDK/Tutorials/Using_third-party_modules_%28jpm%29  &lt;br /&gt;
 var menuitems = require(&amp;quot;menuitem&amp;quot;);&lt;br /&gt;
 var menuitem = menuitems.Menuitem({&lt;br /&gt;
  id: &amp;quot;clickme&amp;quot;,&lt;br /&gt;
  menuid: &amp;quot;menu_ToolsPopup&amp;quot;,&lt;br /&gt;
  label: name,&lt;br /&gt;
  onCommand: function() {&lt;br /&gt;
    console.log(&amp;quot;menuitem clicked:&amp;quot;);&lt;br /&gt;
    callback();&lt;br /&gt;
  },&lt;br /&gt;
  insertbefore: &amp;quot;menu_pageInfo&amp;quot;&lt;br /&gt;
});&lt;br /&gt;
	},&lt;br /&gt;
    &lt;br /&gt;
	registerTrigger: function() {&lt;br /&gt;
		// https://developer.mozilla.org/en-US/Add-ons/SDK/Tutorials/Add_a_Context_Menu_Item&lt;br /&gt;
		// https://developer.mozilla.org/en-US/Add-ons/SDK/High-Level_APIs/context-menu#Item%28options%29&lt;br /&gt;
		var contextMenu = require(&amp;quot;sdk/context-menu&amp;quot;);&lt;br /&gt;
		var menuItem = contextMenu.Item({&lt;br /&gt;
  		label: &amp;quot;Instant Cquote&amp;quot;,&lt;br /&gt;
  		context: contextMenu.SelectionContext(),&lt;br /&gt;
      // https://developer.mozilla.org/en/Add-ons/SDK/Guides/Two_Types_of_Scripts&lt;br /&gt;
      // https://developer.mozilla.org/en-US/Add-ons/SDK/Guides/Content_Scripts&lt;br /&gt;
  		contentScript: 'self.on(&amp;quot;click&amp;quot;, function () {' +&lt;br /&gt;
                 '  var text = window.getSelection().toString();' +&lt;br /&gt;
                 '  self.postMessage(text);' +&lt;br /&gt;
                 '});',&lt;br /&gt;
  		onMessage: function (selectionText) {&lt;br /&gt;
    		console.log(selectionText);&lt;br /&gt;
        instantCquote(selectionText);&lt;br /&gt;
  		}&lt;br /&gt;
	});&lt;br /&gt;
  &lt;br /&gt;
    // for selection handling stuff, see: https://developer.mozilla.org/en-US/Add-ons/SDK/High-Level_APIs/selection&lt;br /&gt;
    &lt;br /&gt;
    function myListener() {&lt;br /&gt;
  console.log(&amp;quot;A selection has been made.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
var selection = require(&amp;quot;sdk/selection&amp;quot;);&lt;br /&gt;
selection.on('select', myListener);&lt;br /&gt;
    &lt;br /&gt;
	}, //registerTrigger&lt;br /&gt;
    &lt;br /&gt;
	get_persistent: function(key, default_value) {&lt;br /&gt;
    // https://developer.mozilla.org/en-US/Add-ons/SDK/High-Level_APIs/simple-storage&lt;br /&gt;
    var ss = require(&amp;quot;sdk/simple-storage&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    console.log(&amp;quot;firefox mode does not yet have persistence support&amp;quot;);&lt;br /&gt;
    return default_value;},&lt;br /&gt;
	set_persistent: function(key, value) {&lt;br /&gt;
		console.log(&amp;quot;firefox persistence stubs not yet filled in !&amp;quot;);&lt;br /&gt;
	},&lt;br /&gt;
    &lt;br /&gt;
  &lt;br /&gt;
	set_clipboard: function(content) {&lt;br /&gt;
	// https://developer.mozilla.org/en-US/Add-ons/SDK/High-Level_APIs/clipboard&lt;br /&gt;
    &lt;br /&gt;
	//console.log('clipboard stub not yet filled in ...');&lt;br /&gt;
    var clipboard = require(&amp;quot;sdk/clipboard&amp;quot;);&lt;br /&gt;
    clipboard.set(content);&lt;br /&gt;
	} //set_cliipboard&lt;br /&gt;
    &lt;br /&gt;
  }, // end of FireFox addon config&lt;br /&gt;
  &lt;br /&gt;
  // placeholder for now ...&lt;br /&gt;
  Android: {&lt;br /&gt;
    // NOP&lt;br /&gt;
  }, // Android&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  ///////////////////////////////////////&lt;br /&gt;
  // supported  script engines:&lt;br /&gt;
  ///////////////////////////////////////&lt;br /&gt;
  &lt;br /&gt;
  GreaseMonkey: {&lt;br /&gt;
  // TODO: move environment specific initialization code here  &lt;br /&gt;
  init: function() {&lt;br /&gt;
  // Check if Greasemonkey/Tampermonkey is available&lt;br /&gt;
  try {&lt;br /&gt;
  // TODO: add version check for clipboard API and check for TamperMonkey/Scriptish equivalents ?&lt;br /&gt;
  GM_addStyle(GM_getResourceText('jQUI_CSS'));&lt;br /&gt;
  } // try&lt;br /&gt;
  catch (error) {&lt;br /&gt;
  console.log('Could not add style or determine script version');&lt;br /&gt;
  } // catch&lt;br /&gt;
&lt;br /&gt;
  var commands = [&lt;br /&gt;
  {name:'Setup quotes',callback:setupDialog, hook:'S' },&lt;br /&gt;
  {name:'Check quotes',callback:selfCheckDialog, hook:'C' }&lt;br /&gt;
  ];&lt;br /&gt;
      &lt;br /&gt;
  for (let c of commands ) {&lt;br /&gt;
   this.registerConfigurationOption(c.name, c.callback, c.hook);&lt;br /&gt;
  }  &lt;br /&gt;
     &lt;br /&gt;
  }, // init()&lt;br /&gt;
    &lt;br /&gt;
  getScriptVersion: function() {&lt;br /&gt;
  return GM_info.script.version;  &lt;br /&gt;
  },&lt;br /&gt;
    &lt;br /&gt;
  dbLog: function (message) {&lt;br /&gt;
  if (Boolean(DEBUG)) {&lt;br /&gt;
    console.log('Instant cquotes:' + message);&lt;br /&gt;
  }&lt;br /&gt;
  }, // dbLog()&lt;br /&gt;
    &lt;br /&gt;
  registerConfigurationOption: function(name,callback,hook) {&lt;br /&gt;
  // https://wiki.greasespot.net/GM_registerMenuCommand&lt;br /&gt;
  // https://wiki.greasespot.net/Greasemonkey_Manual:Monkey_Menu#The_Menu&lt;br /&gt;
    GM_registerMenuCommand(name, callback, hook);&lt;br /&gt;
  }, //registerMenuCommand()&lt;br /&gt;
    &lt;br /&gt;
  registerTrigger: function() {&lt;br /&gt;
    &lt;br /&gt;
    // TODO: we can use the following callback non-interactively, i.e. to trigger background tasks&lt;br /&gt;
// http://javascript.info/tutorial/onload-ondomcontentloaded&lt;br /&gt;
document.addEventListener(&amp;quot;DOMContentLoaded&amp;quot;, function(event) {&lt;br /&gt;
    console.log(&amp;quot;Instant Cquotes: DOM fully loaded and parsed&amp;quot;);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
window.addEventListener('load', init); // page fully loaded&lt;br /&gt;
Host.dbLog('Instant Cquotes: page load handler registered');&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    // Initialize (matching page loaded)&lt;br /&gt;
function init() {&lt;br /&gt;
  console.log('Instant Cquotes: page load handler invoked');&lt;br /&gt;
  var profile = getProfile();&lt;br /&gt;
  &lt;br /&gt;
  Host.dbLog(&amp;quot;Profile type is:&amp;quot;+profile.type);&lt;br /&gt;
  &lt;br /&gt;
  // Dispatch to correct event handler (depending on website/URL)&lt;br /&gt;
  // TODO: this stuff could/should be moved into the config hash itself&lt;br /&gt;
  &lt;br /&gt;
  if (profile.type=='wiki') {&lt;br /&gt;
    profile.event_handler(); // just for testing&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
   &lt;br /&gt;
    Host.dbLog('using default mode');&lt;br /&gt;
    document.onmouseup = instantCquote;&lt;br /&gt;
    // HACK: preparations for moving the the event/handler logic also into the profile hash, so that the wiki (edit mode) can be handled equally&lt;br /&gt;
    //eval(profile.event+&amp;quot;=instantCquote&amp;quot;);&lt;br /&gt;
     &lt;br /&gt;
} // init()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
  }, // registerTrigger&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
   download: function (url, callback, method='GET') {&lt;br /&gt;
  // http://wiki.greasespot.net/GM_xmlhttpRequest&lt;br /&gt;
     try {&lt;br /&gt;
  GM_xmlhttpRequest({&lt;br /&gt;
    method: method,&lt;br /&gt;
    url: url,&lt;br /&gt;
    onload: callback&lt;br /&gt;
  });&lt;br /&gt;
     }catch(e) {&lt;br /&gt;
       console.log(&amp;quot;download did not work&amp;quot;);&lt;br /&gt;
     }&lt;br /&gt;
  }, // download()&lt;br /&gt;
    &lt;br /&gt;
    // is only intended to work with archives supported by the  hash&lt;br /&gt;
    downloadPosting: function (url, EventHandler) {&lt;br /&gt;
      &lt;br /&gt;
    Host.download(url, function (response) {&lt;br /&gt;
    var profile = getProfile(url);&lt;br /&gt;
    var blob = response.responseText;&lt;br /&gt;
    var doc = Host.make_doc(blob,'text/html'); &lt;br /&gt;
    var result = {}; // hash to be returned&lt;br /&gt;
    &lt;br /&gt;
    [].forEach.call(['author','date','title','content'], function(field) {&lt;br /&gt;
      var xpath_query = '//' + profile[field].xpath;&lt;br /&gt;
      try {&lt;br /&gt;
       var value = Host.eval_xpath(doc, xpath_query).stringValue; &lt;br /&gt;
       //UI.alert(&amp;quot;extracted field value:&amp;quot;+value);&lt;br /&gt;
        &lt;br /&gt;
        // now apply all transformations, if any&lt;br /&gt;
       value = applyTransformations(value, profile[field].transform );&lt;br /&gt;
        &lt;br /&gt;
       result[field]=value; // store the extracted/transormed value in the hash that we pass on&lt;br /&gt;
      } // try&lt;br /&gt;
      catch(e) {&lt;br /&gt;
        UI.alert(&amp;quot;downloadPosting failed:\n&amp;quot;+ e.message);&lt;br /&gt;
      } // catch&lt;br /&gt;
    }); // forEach field&lt;br /&gt;
    &lt;br /&gt;
    EventHandler(result); // pass the result to the handler&lt;br /&gt;
    }); // call to Host.download() &lt;br /&gt;
      &lt;br /&gt;
    }, // downloadPosting()&lt;br /&gt;
    &lt;br /&gt;
    // TODO: add makeAJAXCall, and makeWikiCall here&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
    // turn a string/text blob into a DOM tree that can be queried (e.g. for xpath expressions)&lt;br /&gt;
    // FIXME: this is browser specific not GM specific ...&lt;br /&gt;
    make_doc: function(text, type='text/html') {&lt;br /&gt;
      // to support other browsers, see: https://developer.mozilla.org/en/docs/Web/API/DOMParser&lt;br /&gt;
      return new DOMParser().parseFromString(text,type);&lt;br /&gt;
    }, // make DOM document&lt;br /&gt;
    &lt;br /&gt;
    // xpath handling may be handled separately depending on browser/platform, so better encapsulate this&lt;br /&gt;
    // FIXME: this is browser specific not GM specific ...&lt;br /&gt;
    eval_xpath: function(doc, xpath, type=XPathResult.STRING_TYPE) {&lt;br /&gt;
      return doc.evaluate(xpath, doc, null, type, null);&lt;br /&gt;
    }, // eval_xpath&lt;br /&gt;
    &lt;br /&gt;
    set_persistent: function(key, value, json=false) &lt;br /&gt;
    {&lt;br /&gt;
      // transparently stringify to json&lt;br /&gt;
      if(json) {&lt;br /&gt;
        // http://stackoverflow.com/questions/16682150/store-a-persistent-list-between-sessions&lt;br /&gt;
        value = JSON.stringify (value);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      // https://wiki.greasespot.net/GM_setValue&lt;br /&gt;
      GM_setValue(key, value);&lt;br /&gt;
      //UI.alert('Saved value for key\n'+key+':'+value);&lt;br /&gt;
    }, // set_persistent&lt;br /&gt;
    &lt;br /&gt;
    get_persistent: function(key, default_value, json=false) {&lt;br /&gt;
     // https://wiki.greasespot.net/GM_getValue&lt;br /&gt;
    &lt;br /&gt;
      var value=GM_getValue(key, default_value);&lt;br /&gt;
      // transparently support JSON: http://stackoverflow.com/questions/16682150/store-a-persistent-list-between-sessions&lt;br /&gt;
      if(json) {&lt;br /&gt;
        value = JSON.parse (value)  ||  {};&lt;br /&gt;
      }&lt;br /&gt;
      return value;&lt;br /&gt;
    }, // get_persistent&lt;br /&gt;
&lt;br /&gt;
   setClipboard: function(msg) {&lt;br /&gt;
   // this being a greasemonkey user-script, we are not &lt;br /&gt;
   // subject to usual browser restrictions&lt;br /&gt;
   // http://wiki.greasespot.net/GM_setClipboard&lt;br /&gt;
   GM_setClipboard(msg);&lt;br /&gt;
  }, // setClipboard()&lt;br /&gt;
    &lt;br /&gt;
    getTemplate: function() {&lt;br /&gt;
    &lt;br /&gt;
    // hard-coded default template&lt;br /&gt;
    var template = '$CONTENT&amp;lt;ref&amp;gt;{{cite web\n' +&lt;br /&gt;
  '  |url    =  $URL \n' +&lt;br /&gt;
  '  |title  =  &amp;lt;nowiki&amp;gt; $TITLE &amp;lt;/nowiki&amp;gt; \n' +&lt;br /&gt;
  '  |author =  &amp;lt;nowiki&amp;gt; $AUTHOR &amp;lt;/nowiki&amp;gt; \n' +&lt;br /&gt;
  '  |date   =  $DATE \n' +&lt;br /&gt;
  '  |added  =  $ADDED \n' +&lt;br /&gt;
  '  |script_version = $SCRIPT_VERSION \n' +&lt;br /&gt;
  '  }}&amp;lt;/ref&amp;gt;\n';&lt;br /&gt;
     &lt;br /&gt;
    // return a saved template if found, fall back to hard-coded one above otherwise&lt;br /&gt;
    return Host.get_persistent('default_template', template);&lt;br /&gt;
    &lt;br /&gt;
  } // getTemplate&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
  } // end of GreaseMonkey environment, add other environments below&lt;br /&gt;
  &lt;br /&gt;
}; // Environment hash - intended to help encapsulate host specific stuff (APIs)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// the first thing we need to do is to determine what APIs are available&lt;br /&gt;
// and store everything in a Host hash, which is subsequently used for API lookups&lt;br /&gt;
// the Host hash contains all platform/browser-specific APIs&lt;br /&gt;
var Host = Environment.getHost();&lt;br /&gt;
Environment.validate(Host); // this checks the obtained host to see if all required dependencies are available&lt;br /&gt;
Host.init(); // run environment specific initialization code (e.g. logic for GreaseMonkey setup)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// move DEBUG handling to a persistent configuration flag so that we can configure this using a jQuery dialog (defaulted to false)&lt;br /&gt;
// TODO: move DEBUG variable to Environment hash / init() routine&lt;br /&gt;
var DEBUG = Host.get_persistent('debug_mode_enabled', false);&lt;br /&gt;
Host.dbLog(&amp;quot;Debug mode is:&amp;quot;+DEBUG);&lt;br /&gt;
function DEBUG_mode() {&lt;br /&gt;
  // reset script invocation counter for testing purposes&lt;br /&gt;
  Host.dbLog('Resetting script invocation counter');&lt;br /&gt;
  Host.set_persistent(GM_info.script.version, 0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if (DEBUG)&lt;br /&gt;
DEBUG_mode();&lt;br /&gt;
&lt;br /&gt;
// hash with supported websites/URLs,  includes xpath and regex expressions to extract certain fields, and a vector with optional transformations for post-processing each field&lt;br /&gt;
&lt;br /&gt;
var CONFIG = {&lt;br /&gt;
  // WIP: the first entry is special, i.e. it's not an actual list archive (source), but only added here so that the same script can be used&lt;br /&gt;
  // for editing the FlightGear wiki&lt;br /&gt;
  &lt;br /&gt;
  'FlightGear.wiki': {&lt;br /&gt;
    type: 'wiki',&lt;br /&gt;
    enabled: false,&lt;br /&gt;
    event: 'document.onmouseup', // when to invoke the event handler&lt;br /&gt;
    // TODO: move downloadWatchlist() etc here&lt;br /&gt;
    event_handler: function () {&lt;br /&gt;
      console.log('FlightGear wiki handler active (waiting to be populated)');&lt;br /&gt;
      // this is where the logic for a wiki mode can be added over time (for now, it's a NOP)&lt;br /&gt;
    &lt;br /&gt;
    //for each supported mode, invoke the trigger and call the corresponding handler&lt;br /&gt;
    [].forEach.call(CONFIG['FlightGear.wiki'].modes, function(mode) {&lt;br /&gt;
      //dbLog(&amp;quot;Checking trigger:&amp;quot;+mode.name);&lt;br /&gt;
      if(mode.trigger() ) {&lt;br /&gt;
        mode.handler();&lt;br /&gt;
      }&lt;br /&gt;
    });&lt;br /&gt;
      &lt;br /&gt;
    }, // the event handler to be invoked&lt;br /&gt;
    url_reg: '^(http|https)://wiki.flightgear.org', // ignore for now: not currently used by the wiki mode&lt;br /&gt;
    &lt;br /&gt;
    modes: [&lt;br /&gt;
      { name:'process-editSections',&lt;br /&gt;
        trigger: function() {return true;}, // match URL regex - return true for always match&lt;br /&gt;
       &lt;br /&gt;
        // the code implementing the mode&lt;br /&gt;
        handler: function() {&lt;br /&gt;
                &lt;br /&gt;
    var editSections = document.getElementsByClassName('mw-editsection');&lt;br /&gt;
    console.log('FlightGear wiki article, number of edit sections: '+editSections.length);&lt;br /&gt;
   &lt;br /&gt;
    // for now, just rewrite edit sections and add a note to them&lt;br /&gt;
   &lt;br /&gt;
     [].forEach.call(editSections, function (sec) {&lt;br /&gt;
       sec.appendChild(&lt;br /&gt;
         document.createTextNode(' (instant-cquotes is lurking) ')&lt;br /&gt;
       );&lt;br /&gt;
     }); //forEach section&lt;br /&gt;
        } // handler&lt;br /&gt;
       &lt;br /&gt;
       &lt;br /&gt;
      } // process-editSections&lt;br /&gt;
      // TODO: add other wiki modes below &lt;br /&gt;
      &lt;br /&gt;
    ] // modes&lt;br /&gt;
    &lt;br /&gt;
  }, // end of wiki profile&lt;br /&gt;
  &lt;br /&gt;
  'Sourceforge Mailing list': {&lt;br /&gt;
    enabled: true,&lt;br /&gt;
    type: 'archive',&lt;br /&gt;
    event: 'document.onmouseup', // when to invoke the event handler&lt;br /&gt;
    event_handler: instantCquote, // the event handler to be invoked&lt;br /&gt;
    url_reg: '^(http|https)://sourceforge.net/p/flightgear/mailman/.*/',&lt;br /&gt;
    content: {&lt;br /&gt;
      xpath: 'tbody/tr[2]/td/pre/text()', // NOTE this is only used by the downloadPosting  helper to retrieve the posting without having a selection (TODO:add content xpath to forum hash)&lt;br /&gt;
      selection: getSelectedText,&lt;br /&gt;
      idStyle: /msg[0-9]{8}/,&lt;br /&gt;
      parentTag: [&lt;br /&gt;
        'tagName',&lt;br /&gt;
        'PRE'&lt;br /&gt;
      ],&lt;br /&gt;
      transform: [],&lt;br /&gt;
    }, // content recipe&lt;br /&gt;
    // vector with tests to be executed for sanity checks (unit testing)&lt;br /&gt;
    tests: [&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://sourceforge.net/p/flightgear/mailman/message/35059454/',&lt;br /&gt;
        author: 'Erik Hofman',&lt;br /&gt;
        date: 'May 3rd, 2016', // NOTE: using the transformed date here &lt;br /&gt;
        title: 'Re: [Flightgear-devel] Auto altimeter setting at startup (?)'&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://sourceforge.net/p/flightgear/mailman/message/35059961/',&lt;br /&gt;
        author: 'Ludovic Brenta',&lt;br /&gt;
        date: 'May 3rd, 2016',&lt;br /&gt;
        title: 'Re: [Flightgear-devel] dual-control-tools and the limit on packet size'&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://sourceforge.net/p/flightgear/mailman/message/20014126/',&lt;br /&gt;
        author: 'Tim Moore',&lt;br /&gt;
        date: 'Aug 4th, 2008',&lt;br /&gt;
        title: 'Re: [Flightgear-devel] Cockpit displays (rendering, modelling)'&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://sourceforge.net/p/flightgear/mailman/message/23518343/',&lt;br /&gt;
        author: 'Tim Moore',&lt;br /&gt;
        date: 'Sep 10th, 2009',&lt;br /&gt;
        title: '[Flightgear-devel] Atmosphere patch from John Denker'&lt;br /&gt;
      } // add other tests below&lt;br /&gt;
&lt;br /&gt;
    ], // end of vector with self-tests&lt;br /&gt;
    // regex/xpath and transformations for extracting various required fields&lt;br /&gt;
    author: {&lt;br /&gt;
      xpath: 'tbody/tr[1]/td/div/small/text()',&lt;br /&gt;
      transform: [extract(/From: (.*) &amp;lt;.*@.*&amp;gt;/)]&lt;br /&gt;
    },&lt;br /&gt;
    title: {&lt;br /&gt;
      xpath: 'tbody/tr[1]/td/div/div[1]/b/a/text()',&lt;br /&gt;
      transform:[]&lt;br /&gt;
    },&lt;br /&gt;
    date: {&lt;br /&gt;
      xpath: 'tbody/tr[1]/td/div/small/text()',&lt;br /&gt;
      transform: [extract(/- (.*-.*-.*) /)]&lt;br /&gt;
    },&lt;br /&gt;
    url: {&lt;br /&gt;
      xpath: 'tbody/tr[1]/td/div/div[1]/b/a/@href',&lt;br /&gt;
      transform: [prepend('https://sourceforge.net')]&lt;br /&gt;
    }&lt;br /&gt;
  }, // end of mailing list profile&lt;br /&gt;
  // next website/URL (forum)&lt;br /&gt;
  'FlightGear forum': {&lt;br /&gt;
    enabled: true,&lt;br /&gt;
    type: 'archive',&lt;br /&gt;
    event: 'document.onmouseup', // when to invoke the event handler (not used atm)&lt;br /&gt;
    event_handler: null, // the event handler to be invoked (not used atm)&lt;br /&gt;
    url_reg: /https:\/\/forum\.flightgear\.org\/.*/,&lt;br /&gt;
    content: {&lt;br /&gt;
      xpath: '', //TODO: this must be added for downloadPosting() to work, or it cannot extract contents&lt;br /&gt;
      selection: getSelectedHtml,&lt;br /&gt;
      idStyle: /p[0-9]{6}/,&lt;br /&gt;
      parentTag: [&lt;br /&gt;
        'className',&lt;br /&gt;
        'content',&lt;br /&gt;
        'postbody'&lt;br /&gt;
      ],&lt;br /&gt;
      transform: [&lt;br /&gt;
        removeComments,&lt;br /&gt;
        forum_quote2cquote,&lt;br /&gt;
        forum_smilies2text,&lt;br /&gt;
        forum_fontstyle2wikistyle,&lt;br /&gt;
        forum_code2syntaxhighlight,&lt;br /&gt;
        img2link,&lt;br /&gt;
        a2wikilink,&lt;br /&gt;
        vid2wiki,&lt;br /&gt;
        list2wiki,&lt;br /&gt;
        forum_br2newline&lt;br /&gt;
      ]&lt;br /&gt;
    },&lt;br /&gt;
    // vector with tests to be executed for sanity checks (unit testing)&lt;br /&gt;
    // postings will be downloaded using the URL specified, and then the author/title &lt;br /&gt;
    // fields extracted using the outer regex and matched against what is expected&lt;br /&gt;
    // NOTE: forum postings can be edited, so that these tests would fail - thus, it makes sense to pick locked topics/postings for such tests&lt;br /&gt;
    tests: [&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://forum.flightgear.org/viewtopic.php?f=18&amp;amp;p=284108#p284108',&lt;br /&gt;
        author: 'mickybadia',&lt;br /&gt;
        date: 'May 3rd, 2016',&lt;br /&gt;
        title: 'OSM still PNG maps'&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://forum.flightgear.org/viewtopic.php?f=19&amp;amp;p=284120#p284120',&lt;br /&gt;
        author: 'Thorsten',&lt;br /&gt;
        date: 'May 3rd, 2016',&lt;br /&gt;
        title: 'Re: FlightGear\'s Screenshot Of The Month MAY 2016'&lt;br /&gt;
      },&lt;br /&gt;
       {&lt;br /&gt;
        url: 'https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;t=29279&amp;amp;p=283455#p283446',&lt;br /&gt;
        author: 'Hooray',&lt;br /&gt;
         date: 'Apr 25th, 2016',&lt;br /&gt;
        title: 'Re: Best way to learn Canvas?'&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://forum.flightgear.org/viewtopic.php?f=4&amp;amp;t=1460&amp;amp;p=283994#p283994',&lt;br /&gt;
        author: 'bugman',&lt;br /&gt;
        date: 'May 2nd, 2016',&lt;br /&gt;
        title: 'Re: eurofighter typhoon'&lt;br /&gt;
      } // add other tests below&lt;br /&gt;
&lt;br /&gt;
    ], // end of vector with self-tests&lt;br /&gt;
    author: {&lt;br /&gt;
      xpath: 'div/div[1]/p/strong/a/text()',&lt;br /&gt;
      transform: [] // no transformations applied&lt;br /&gt;
    },&lt;br /&gt;
    title: {&lt;br /&gt;
      xpath: 'div/div[1]/h3/a/text()',&lt;br /&gt;
      transform: [] // no transformations applied&lt;br /&gt;
    },&lt;br /&gt;
    date: {&lt;br /&gt;
      xpath: 'div/div[1]/p/text()[2]',&lt;br /&gt;
      transform: [extract(/» (.*?[0-9]{4})/)]&lt;br /&gt;
    },&lt;br /&gt;
    url: {&lt;br /&gt;
      xpath: 'div/div[1]/p/a/@href',&lt;br /&gt;
      transform: [&lt;br /&gt;
        extract(/\.(.*)/),&lt;br /&gt;
        prepend('https://forum.flightgear.org')&lt;br /&gt;
      ] // transform vector&lt;br /&gt;
    } // url&lt;br /&gt;
  } // forum &lt;br /&gt;
}; // CONFIG has&lt;br /&gt;
&lt;br /&gt;
// hash to map URLs (wiki article, issue tracker, sourceforge link, forum thread etc) to existing wiki templates&lt;br /&gt;
var MatchURL2Templates = [&lt;br /&gt;
  // placeholder for now&lt;br /&gt;
 {&lt;br /&gt;
   name: 'rewrite sourceforge code links',&lt;br /&gt;
   url_reg: '',&lt;br /&gt;
   handler: function() {&lt;br /&gt;
   &lt;br /&gt;
 } // handler&lt;br /&gt;
  &lt;br /&gt;
 } // add other templates below&lt;br /&gt;
  &lt;br /&gt;
]; // MatchURL2Templates&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// output methods (alert and jQuery for now)&lt;br /&gt;
var OUTPUT = {&lt;br /&gt;
  // Shows a window.prompt() message box&lt;br /&gt;
  msgbox: function (msg) {&lt;br /&gt;
    UI.prompt('Copy to clipboard ' + Host.getScriptVersion(), msg);&lt;br /&gt;
    Host.setClipboard(msg);&lt;br /&gt;
  }, // msgbox&lt;br /&gt;
  &lt;br /&gt;
  // this is currently work-in-progress, and will need to be refactored sooner or later&lt;br /&gt;
  // for now, functionality matters more than elegant design/code :)&lt;br /&gt;
  jQueryTabbed: function(msg, original) {&lt;br /&gt;
  // FIXME: using backtics here makes the whole thing require ES6  ....&lt;br /&gt;
  var markup = $(`&amp;lt;div id=&amp;quot;tabs&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;ul&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#selection&amp;quot;&amp;gt;Selection&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#articles&amp;quot;&amp;gt;Articles&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#templates&amp;quot;&amp;gt;Templates&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#development&amp;quot;&amp;gt;Development&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#settings&amp;quot;&amp;gt;Settings&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#help&amp;quot;&amp;gt;Help&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#about&amp;quot;&amp;gt;About&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;/ul&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;selection&amp;quot;&amp;gt;This tab contains your extracted and post-processed selection, converted to proper wikimedia markup, including proper attribution.&lt;br /&gt;
  &amp;lt;div id=&amp;quot;content&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;label for=&amp;quot;template_select&amp;quot;&amp;gt;Select a template&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;select name=&amp;quot;template_select&amp;quot; id=&amp;quot;template_select&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;option&amp;gt;default&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option&amp;gt;cquote&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;/select&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;options&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Note this is work-in-progress, i.e. not yet fully functional&amp;lt;/b&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
    &amp;lt;label for=&amp;quot;article_select&amp;quot;&amp;gt;Select an article to update&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;select name=&amp;quot;article_select&amp;quot; id=&amp;quot;article_select&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;news&amp;quot; label=&amp;quot;News&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;support&amp;quot; label=&amp;quot;Support&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;release&amp;quot; label=&amp;quot;Release&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;develop&amp;quot; label=&amp;quot;Development&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;watchlist&amp;quot; label=&amp;quot;Watchlist&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;/select&amp;gt;&lt;br /&gt;
    &amp;lt;p/&amp;gt;&lt;br /&gt;
    &amp;lt;label for=&amp;quot;section_select&amp;quot;&amp;gt;Select section:&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;select name=&amp;quot;section_select&amp;quot; id=&amp;quot;section_select&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;/select&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;articles&amp;quot;&amp;gt;This tab contains articles that you can directly access/edit using the mediawiki API&amp;lt;br/&amp;gt;&lt;br /&gt;
  Note: The watchlist is retrieved dynamically, so does not need to be edited here&amp;lt;br/&amp;gt;&lt;br /&gt;
    &amp;lt;label for=&amp;quot;article_select&amp;quot;&amp;gt;Select an article&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;select name=&amp;quot;article_select&amp;quot; id=&amp;quot;article_select&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;news&amp;quot; label=&amp;quot;News&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;support&amp;quot; label=&amp;quot;Support&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;develop&amp;quot; label=&amp;quot;Development&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;release&amp;quot; label=&amp;quot;Release&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;!-- the watchlist is retrieved dynamically, so omit it here &lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;watchlist&amp;quot; label=&amp;quot;Watchlist&amp;quot;/&amp;gt;&lt;br /&gt;
    --&amp;gt;&lt;br /&gt;
    &amp;lt;/select&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;button id=&amp;quot;article_new&amp;quot;&amp;gt;New&amp;lt;/button&amp;gt;&lt;br /&gt;
   &amp;lt;button id=&amp;quot;article_remove&amp;quot;&amp;gt;Remove&amp;lt;/button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div id=&amp;quot;edit_article&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;label for=&amp;quot;article_name&amp;quot;&amp;gt;Article&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;text&amp;quot; id=&amp;quot;article_name&amp;quot; name=&amp;quot;article_name&amp;quot;&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;label for=&amp;quot;article_url&amp;quot;&amp;gt;Link&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;text&amp;quot; id=&amp;quot;article_url&amp;quot; name=&amp;quot;article_url&amp;quot;&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;button id=&amp;quot;article_save&amp;quot;&amp;gt;Save&amp;lt;/button&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;templates&amp;quot;&amp;gt;This tab contains templates for different types of articles (newsletter, changelog, release plan etc)&amp;lt;p/&amp;gt;&lt;br /&gt;
  For now, this is WIP - in the future, there will be a dropdown menu added and all templates will be editable.&amp;lt;p/&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;template_header&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;label for=&amp;quot;template_select&amp;quot;&amp;gt;Select a template&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;select name=&amp;quot;template_select&amp;quot; id=&amp;quot;template_select&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;option&amp;gt;default&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option&amp;gt;cquote&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;/select&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;template_area&amp;quot;/&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;template_controls&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;button id=&amp;quot;template_save&amp;quot;&amp;gt;Save&amp;lt;/button&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;development&amp;quot;&amp;gt;This tab is a placeholder for features currently under development&amp;lt;p/&amp;gt;&lt;br /&gt;
  &amp;lt;button id=&amp;quot;evolve_regex&amp;quot;&amp;gt;Evolve regex&amp;lt;/button&amp;gt;&amp;lt;p/&amp;gt;&lt;br /&gt;
  &amp;lt;button id=&amp;quot;test_perceptron&amp;quot;&amp;gt;Test Perceptron&amp;lt;/button&amp;gt;&amp;lt;p/&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;output&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table id=&amp;quot;results&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;thead&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
     &amp;lt;th&amp;gt;Generation&amp;lt;/th&amp;gt;&lt;br /&gt;
     &amp;lt;th&amp;gt;Fitness&amp;lt;/th&amp;gt;&lt;br /&gt;
     &amp;lt;th&amp;gt;Expression&amp;lt;/th&amp;gt;&lt;br /&gt;
     &amp;lt;th&amp;gt;Result&amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
  &amp;lt;/thead&amp;gt;&lt;br /&gt;
  &amp;lt;tbody&amp;gt;&lt;br /&gt;
  &amp;lt;/tbody&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt; &lt;br /&gt;
&lt;br /&gt;
   &amp;lt;!--&lt;br /&gt;
   &amp;lt;textarea id=&amp;quot;devel_output&amp;quot; lines=&amp;quot;10&amp;quot;&amp;gt;&amp;lt;/textarea&amp;gt;&amp;lt;p/&amp;gt;&lt;br /&gt;
  --&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div id=&amp;quot;settings&amp;quot;&amp;gt;This tab will contain script specific settings&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;help&amp;quot;&amp;gt;One day, this tab may contain help....&amp;lt;p/&amp;gt;&amp;lt;button id=&amp;quot;helpButton&amp;quot;&amp;gt;Instant Cquotes&amp;lt;/button&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;about&amp;quot;&amp;gt;show some  script related information here&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;`); // tabs div&lt;br /&gt;
    &lt;br /&gt;
   var evolve_regex = $('div#development button#evolve_regex', markup);&lt;br /&gt;
   evolve_regex.click(function() {&lt;br /&gt;
     //alert(&amp;quot;Evolve regex&amp;quot;);&lt;br /&gt;
     evolve_expression_test();&lt;br /&gt;
   });&lt;br /&gt;
    &lt;br /&gt;
   var test_perceptron = $('div#development button#test_perceptron', markup);&lt;br /&gt;
   test_perceptron.click(function() {&lt;br /&gt;
     alert(&amp;quot;Test perceptron&amp;quot;);&lt;br /&gt;
   });&lt;br /&gt;
   &lt;br /&gt;
    &lt;br /&gt;
    // add dynamic elements to each tab&lt;br /&gt;
    &lt;br /&gt;
   // NOTE: this affects all template selectors, on all tabs&lt;br /&gt;
   $('select#template_select', markup).change(function() {&lt;br /&gt;
     UI.alert(&amp;quot;Sorry, templates are not yet fully implemented (WIP)&amp;quot;);&lt;br /&gt;
   });&lt;br /&gt;
    &lt;br /&gt;
   var help = $('#helpButton', markup);&lt;br /&gt;
   help.button();&lt;br /&gt;
   help.click(function() {&lt;br /&gt;
     window.open(&amp;quot;http://wiki.flightgear.org/FlightGear_wiki:Instant-Cquotes&amp;quot;);&lt;br /&gt;
   });&lt;br /&gt;
    &lt;br /&gt;
   // rows=&amp;quot;10&amp;quot;cols=&amp;quot;80&amp;quot; style=&amp;quot; width: 420px; height: 350px&amp;quot;&lt;br /&gt;
   var textarea = $('&amp;lt;textarea id=&amp;quot;quotedtext&amp;quot; rows=&amp;quot;20&amp;quot; cols=&amp;quot;70&amp;quot;/&amp;gt;');&lt;br /&gt;
   textarea.val(msg);&lt;br /&gt;
   $('#selection #content', markup).append(textarea);&lt;br /&gt;
  &lt;br /&gt;
   var templateArea = $('&amp;lt;textarea id=&amp;quot;template-edit&amp;quot; rows=&amp;quot;20&amp;quot; cols=&amp;quot;70&amp;quot;/&amp;gt;');&lt;br /&gt;
   templateArea.val( Host.getTemplate() );&lt;br /&gt;
   $('div#templates div#template_area', markup).append(templateArea);&lt;br /&gt;
   &lt;br /&gt;
   //$('#templates', markup).append($('&amp;lt;button&amp;gt;'));&lt;br /&gt;
    $('div#templates div#template_controls button#template_save',markup).button().click(function() {&lt;br /&gt;
      //UI.alert(&amp;quot;Saving template:\n&amp;quot;+templateArea.val() );&lt;br /&gt;
      &lt;br /&gt;
      Host.set_persistent('default_template',templateArea.val() );&lt;br /&gt;
    }); // save template&lt;br /&gt;
    &lt;br /&gt;
  // TODO: Currently, this is hard-coded, but should be made customizable via the &amp;quot;articles&amp;quot; tab at some point ...&lt;br /&gt;
  var articles = [&lt;br /&gt;
    // NOTE: category must match an existing &amp;lt;optgroup&amp;gt; above, title must match an existing wiki article&lt;br /&gt;
    {category:'support', name:'Frequently asked questions', url:''},&lt;br /&gt;
    {category:'support', name:'Asking for help', url:''},&lt;br /&gt;
    {category:'news', name:'Next newsletter', url:''},&lt;br /&gt;
    {category:'news', name:'Next changelog', url:''},&lt;br /&gt;
    {category:'release', name:'Release plan/Lessons learned', url:''}, // TODO: use wikimedia template&lt;br /&gt;
    {category:'develop', name:'Nasal library', url:''},&lt;br /&gt;
    {category:'develop', name:'Canvas Snippets', url:''},&lt;br /&gt;
    &lt;br /&gt;
  ];&lt;br /&gt;
    &lt;br /&gt;
    // TODO: this should be moved elsewhere&lt;br /&gt;
    function updateArticleList(selector) {&lt;br /&gt;
    $.each(articles, function (i, article) {&lt;br /&gt;
    $(selector+ ' optgroup#'+article.category, markup).append($('&amp;lt;option&amp;gt;', { &lt;br /&gt;
        value: article.name, // FIXME: just a placeholder for now&lt;br /&gt;
        text : article.name &lt;br /&gt;
    })); //append option&lt;br /&gt;
   }); // foreach&lt;br /&gt;
    } // updateArticleList&lt;br /&gt;
    &lt;br /&gt;
    // add the article list to the corresponding dropdown menus&lt;br /&gt;
    updateArticleList('select#article_select');&lt;br /&gt;
        &lt;br /&gt;
    // populate watchlist (prototype for now)&lt;br /&gt;
    // TODO: generalize &amp;amp; refactor: url, format&lt;br /&gt;
      &lt;br /&gt;
    // https://www.mediawiki.org/wiki/API:Watchlist&lt;br /&gt;
    // http://wiki.flightgear.org/api.php?action=query&amp;amp;list=watchlist&lt;br /&gt;
      var watchlist_url = 'http://wiki.flightgear.org/api.php?action=query&amp;amp;list=watchlist&amp;amp;format=json';&lt;br /&gt;
      Host.download(watchlist_url, function(response) {&lt;br /&gt;
        try {&lt;br /&gt;
       var watchlist = JSON.parse(response.responseText);&lt;br /&gt;
            &lt;br /&gt;
       //$('div#options select#section_select', markup).empty(); // delete all sections&lt;br /&gt;
      &lt;br /&gt;
      $.each(watchlist.query.watchlist, function (i, article) {&lt;br /&gt;
      $('div#options select#article_select optgroup#watchlist', markup).append($('&amp;lt;option&amp;gt;', { &lt;br /&gt;
        value: article.title, //FIXME just a placeholder for now&lt;br /&gt;
        text : article.title &lt;br /&gt;
    }));&lt;br /&gt;
   }); //foreach section&lt;br /&gt;
&lt;br /&gt;
        }&lt;br /&gt;
        catch (e) {&lt;br /&gt;
          UI.alert(&amp;quot;Could not download wiki watchlist\n&amp;quot;+watchlist.error.info);&lt;br /&gt;
        }&lt;br /&gt;
      }); // download &amp;amp; populate watchlist&lt;br /&gt;
      &lt;br /&gt;
    &lt;br /&gt;
    // register an event handler for the main tab, so that article specific sections can be retrieved&lt;br /&gt;
    $('div#options select#article_select', markup).change(function() {&lt;br /&gt;
      var article = this.value;&lt;br /&gt;
      &lt;br /&gt;
    // HACK: try to get a login token (actually not needed just for reading ...)&lt;br /&gt;
    Host.download('http://wiki.flightgear.org/api.php?action=query&amp;amp;prop=info|revisions&amp;amp;intoken=edit&amp;amp;rvprop=timestamp&amp;amp;titles=Main%20Page', function (response) {&lt;br /&gt;
    var message = 'FlightGear wiki login status (AJAX):';&lt;br /&gt;
    var status = response.statusText;&lt;br /&gt;
    &lt;br /&gt;
    // populate dropdown menu with article sections&lt;br /&gt;
    if (status === 'OK') {&lt;br /&gt;
    &lt;br /&gt;
      // Resolve redirects: https://www.mediawiki.org/wiki/API:Query#Resolving_redirects&lt;br /&gt;
      var section_url = 'http://wiki.flightgear.org/api.php?action=parse&amp;amp;page='+encodeURIComponent(article)+'&amp;amp;prop=sections&amp;amp;format=json&amp;amp;redirects';&lt;br /&gt;
      Host.download(section_url, function(response) {&lt;br /&gt;
        try {&lt;br /&gt;
       var sections = JSON.parse(response.responseText);&lt;br /&gt;
            &lt;br /&gt;
       $('div#options select#section_select', markup).empty(); // delete all sections&lt;br /&gt;
      &lt;br /&gt;
      $.each(sections.parse.sections, function (i, section) {&lt;br /&gt;
      $('div#options select#section_select', markup).append($('&amp;lt;option&amp;gt;', { &lt;br /&gt;
        value: section.line, //FIXME just a placeholder for now&lt;br /&gt;
        text : section.line &lt;br /&gt;
    }));&lt;br /&gt;
   }); //foreach section&lt;br /&gt;
&lt;br /&gt;
        }&lt;br /&gt;
        catch (e) {&lt;br /&gt;
          UI.alert(e.message);&lt;br /&gt;
        }&lt;br /&gt;
             &lt;br /&gt;
      }); //download sections&lt;br /&gt;
     &lt;br /&gt;
      &lt;br /&gt;
      &lt;br /&gt;
    } // login status is OK&lt;br /&gt;
&lt;br /&gt;
      &lt;br /&gt;
  }); // Host.download() call, i.e. we have a login token&lt;br /&gt;
      &lt;br /&gt;
    }); // on select change&lt;br /&gt;
    &lt;br /&gt;
  // init the tab stuff&lt;br /&gt;
  markup.tabs();&lt;br /&gt;
  &lt;br /&gt;
  var diagParam = {&lt;br /&gt;
      title: 'Instant Cquotes ' + Host.getScriptVersion(),&lt;br /&gt;
      modal: true,&lt;br /&gt;
      width: 700,&lt;br /&gt;
      buttons: [&lt;br /&gt;
        {&lt;br /&gt;
          text:'reported speech',&lt;br /&gt;
          click: function() {&lt;br /&gt;
            textarea.val(createCquote(original,true));&lt;br /&gt;
          }&lt;br /&gt;
        },&lt;br /&gt;
        &lt;br /&gt;
        {&lt;br /&gt;
          text: 'Copy',&lt;br /&gt;
          click: function () {&lt;br /&gt;
            Host.setClipboard(msg);&lt;br /&gt;
            $(this).dialog('close');&lt;br /&gt;
          }&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
      ]&lt;br /&gt;
  };&lt;br /&gt;
    &lt;br /&gt;
  // actually show our tabbed dialog using the params above&lt;br /&gt;
  markup.dialog(diagParam);&lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
  } // jQueryTabbed() &lt;br /&gt;
  &lt;br /&gt;
}; // output methods&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// TODO: we can use an online API to  help with some of this: http://www.eslnow.org/reported-speech-converter/&lt;br /&gt;
// See also: http://blog.mashape.com/list-of-25-natural-language-processing-apis/&lt;br /&gt;
// http://text-processing.com/docs/phrases.html&lt;br /&gt;
// http://www.alchemyapi.com/&lt;br /&gt;
// https://words.bighugelabs.com/api.php&lt;br /&gt;
// https://www.wordsapi.com/&lt;br /&gt;
// http://www.dictionaryapi.com/&lt;br /&gt;
// https://www.textrazor.com/&lt;br /&gt;
// http://www.programmableweb.com/news/how-5-natural-language-processing-apis-stack/analysis/2014/07/28&lt;br /&gt;
&lt;br /&gt;
var speechTransformations = [&lt;br /&gt;
// TODO: support aliasing using vectors: would/should &lt;br /&gt;
// ordering is crucial here (most specific first, least specific/most generic last)&lt;br /&gt;
 &lt;br /&gt;
// first, we start off  by expanding short forms: http://www.learnenglish.de/grammar/shortforms.html&lt;br /&gt;
// http://www.macmillandictionary.com/thesaurus-category/british/short-forms&lt;br /&gt;
 &lt;br /&gt;
  {query:/couldn\'t/gi, replacement:'could not'},&lt;br /&gt;
  {query:/I could not/gi, replacement:'$author could not'},&lt;br /&gt;
  &lt;br /&gt;
  {query:/I\'m/gi, replacement:'I am'},&lt;br /&gt;
  {query:/I am/gi, replacement:'$author is'},&lt;br /&gt;
  &lt;br /&gt;
  {query:/I\'ve/, replacement:'I have'},&lt;br /&gt;
  {query:/I have had/, replacement:'$author had'},&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  {query:/can(\'|\’)t/gi, replacement:'cannot'},&lt;br /&gt;
  &lt;br /&gt;
  {query:/I(\'|\’)ll/gi, replacement:'$author will'},&lt;br /&gt;
  {query:/I(\'|\’)d/gi, replacement:'$author would'},&lt;br /&gt;
  &lt;br /&gt;
  {query:/I have done/gi, replacement:'$author has done'},&lt;br /&gt;
  {query:/I\'ve done/gi, replacement:'$author has done'}, //FIXME. queries should really be vectors ...&lt;br /&gt;
  &lt;br /&gt;
  {query:/I believe/gi, replacement:'$author suggested'},&lt;br /&gt;
  {query:/I think/gi, replacement:'$author suggested'},&lt;br /&gt;
  {query:/I guess/gi, replacement:'$author believes'},&lt;br /&gt;
  &lt;br /&gt;
  {query:/I can see that/gi, replacement:'$author suggested that'},&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  {query:/I have got/gi, replacement:'$author has got'},&lt;br /&gt;
  {query:/I\'ve got/gi, replacement:'$author has got'},&lt;br /&gt;
  &lt;br /&gt;
  {query:/I\'d suggest/gi, replacement:'$author would suggest'},&lt;br /&gt;
  &lt;br /&gt;
  {query:/I\’m prototyping/gi, replacement:'$author is prototyping'},&lt;br /&gt;
  &lt;br /&gt;
  {query:/I myself/gi, replacement:'$author himself'},&lt;br /&gt;
  {query:/I am/gi, replacement:' $author is'},&lt;br /&gt;
  &lt;br /&gt;
  {query:/I can see/gi, replacement:'$author can see'},&lt;br /&gt;
  {query:/I can/gi, replacement:'$author can'},&lt;br /&gt;
  {query:/I have/gi, replacement:'$author has'},&lt;br /&gt;
  {query:/I should/g, replacement:'$author should'},&lt;br /&gt;
  {query:/I shall/gi, replacement:'$author shall'},&lt;br /&gt;
  {query:/I may/gi, replacement:'$author may'},&lt;br /&gt;
  {query:/I will/gi, replacement:'$author will'},&lt;br /&gt;
  {query:/I would/gi, replacement:'$author would'},&lt;br /&gt;
  {query:/by myself/gi, replacement:'by $author'},&lt;br /&gt;
  {query:/and I/gi, replacement:'and $author'},&lt;br /&gt;
  {query:/and me/gi, replacement:'and $author'},&lt;br /&gt;
  {query:/and myself/gi, replacement:'and $author'}&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  // least specific stuff last (broad/generic stuff is kept as is, with author clarification added in parentheses)&lt;br /&gt;
  /*&lt;br /&gt;
  {query:/I/, replacement:'I ($author)'},&lt;br /&gt;
  &lt;br /&gt;
  {query:/me/, replacement:'me ($author)'},&lt;br /&gt;
  {query:/my/, replacement:'my ($author)'},&lt;br /&gt;
  {query:/myself/, replacement:'myself ($author)'},&lt;br /&gt;
  {query:/mine/, replacement:'$author'}&lt;br /&gt;
  */&lt;br /&gt;
];&lt;br /&gt;
&lt;br /&gt;
// try to assist in transforming speech using the transformation vector passed in&lt;br /&gt;
// still needs to be exposed via the UI&lt;br /&gt;
function transformSpeech(text, author, gender, transformations) {&lt;br /&gt;
  // WIP: foreach transformation in vector, replace the search pattern with the matched string (replacing author/gender as applicable)&lt;br /&gt;
  //alert(&amp;quot;text to be transformed:\n&amp;quot;+text);&lt;br /&gt;
  for(var i=0;i&amp;lt; transformations.length; i++) {&lt;br /&gt;
    var token = transformations[i];&lt;br /&gt;
    // patch the replacement string using the correct author name &lt;br /&gt;
    var replacement = token.replacement.replace(/\$author/gi, author);&lt;br /&gt;
    text = text.replace(token.query, replacement);&lt;br /&gt;
  } // end of token transformation&lt;br /&gt;
  console.log(&amp;quot;transformed text is:&amp;quot;+text);&lt;br /&gt;
  return text;&lt;br /&gt;
} // transformSpeech&lt;br /&gt;
&lt;br /&gt;
// run a self-test&lt;br /&gt;
&lt;br /&gt;
(function() {&lt;br /&gt;
var author =&amp;quot;John Doe&amp;quot;;&lt;br /&gt;
var transformed = transformSpeech(&amp;quot;I have decided to commit a new feature&amp;quot;, author, null, speechTransformations );&lt;br /&gt;
if (transformed !== author+&amp;quot; has decided to commit a new feature&amp;quot;)&lt;br /&gt;
  Host.dbLog(&amp;quot;FIXME: Speech transformations are not working correctly&amp;quot;);&lt;br /&gt;
}) ();&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
var MONTHS = [&lt;br /&gt;
  'Jan',&lt;br /&gt;
  'Feb',&lt;br /&gt;
  'Mar',&lt;br /&gt;
  'Apr',&lt;br /&gt;
  'May',&lt;br /&gt;
  'Jun',&lt;br /&gt;
  'Jul',&lt;br /&gt;
  'Aug',&lt;br /&gt;
  'Sep',&lt;br /&gt;
  'Oct',&lt;br /&gt;
  'Nov',&lt;br /&gt;
  'Dec'&lt;br /&gt;
];&lt;br /&gt;
// Conversion for forum emoticons&lt;br /&gt;
var EMOTICONS = [&lt;br /&gt;
  [/:shock:/g,&lt;br /&gt;
  'O_O'],&lt;br /&gt;
  [&lt;br /&gt;
    /:lol:/g,&lt;br /&gt;
    '(lol)'&lt;br /&gt;
  ],&lt;br /&gt;
  [&lt;br /&gt;
    /:oops:/g,&lt;br /&gt;
    ':$'&lt;br /&gt;
  ],&lt;br /&gt;
  [&lt;br /&gt;
    /:cry:/g,&lt;br /&gt;
    ';('&lt;br /&gt;
  ],&lt;br /&gt;
  [&lt;br /&gt;
    /:evil:/g,&lt;br /&gt;
    '&amp;gt;:)'&lt;br /&gt;
  ],&lt;br /&gt;
  [&lt;br /&gt;
    /:twisted:/g,&lt;br /&gt;
    '3:)'&lt;br /&gt;
  ],&lt;br /&gt;
  [&lt;br /&gt;
    /:roll:/g,&lt;br /&gt;
    '(eye roll)'&lt;br /&gt;
  ],&lt;br /&gt;
  [&lt;br /&gt;
    /:wink:/g,&lt;br /&gt;
    ';)'&lt;br /&gt;
  ],&lt;br /&gt;
  [&lt;br /&gt;
    /:!:/g,&lt;br /&gt;
    '(!)'&lt;br /&gt;
  ],&lt;br /&gt;
  [&lt;br /&gt;
    /:\?:/g,&lt;br /&gt;
    '(?)'&lt;br /&gt;
  ],&lt;br /&gt;
  [&lt;br /&gt;
    /:idea:/g,&lt;br /&gt;
    '(idea)'&lt;br /&gt;
  ],&lt;br /&gt;
  [&lt;br /&gt;
    /:arrow:/g,&lt;br /&gt;
    '(-&amp;gt;)'&lt;br /&gt;
  ],&lt;br /&gt;
  [&lt;br /&gt;
    /:mrgreen:/g,&lt;br /&gt;
    'xD'&lt;br /&gt;
  ]&lt;br /&gt;
];&lt;br /&gt;
// ##################&lt;br /&gt;
// # Main functions #&lt;br /&gt;
// ##################&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// the required trigger is host specific (userscript vs. addon vs. android etc)&lt;br /&gt;
// for now, this merely wraps window.load mapping to the instantCquotoe callback below&lt;br /&gt;
Host.registerTrigger();&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// FIXME: function is currently referenced in CONFIG hash - event_handler, so cannot be easily moved across&lt;br /&gt;
// The main function&lt;br /&gt;
// TODO: split up, so that we can reuse the code elsewhere&lt;br /&gt;
function instantCquote(sel) {&lt;br /&gt;
  var profile = getProfile();&lt;br /&gt;
  &lt;br /&gt;
  // TODO: use config hash here&lt;br /&gt;
  var selection =  document.getSelection(),&lt;br /&gt;
  post_id=0;&lt;br /&gt;
  &lt;br /&gt;
  try {&lt;br /&gt;
    post_id = getPostId(selection, profile);&lt;br /&gt;
  } &lt;br /&gt;
  catch (error) {&lt;br /&gt;
    Host.dbLog('Failed extracting post id\nProfile:' + profile);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  if (selection.toString() === '') {&lt;br /&gt;
    Host.dbLog('No text is selected, aborting function');&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  if (!checkValid(selection, profile)) {&lt;br /&gt;
    Host.dbLog('Selection is not valid, aborting function');&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  try {&lt;br /&gt;
    transformationLoop(profile, post_id);&lt;br /&gt;
  }&lt;br /&gt;
  catch(e) {&lt;br /&gt;
    UI.alert(&amp;quot;Transformation loop:\n&amp;quot;+e.message);&lt;br /&gt;
  }&lt;br /&gt;
} // instantCquote&lt;br /&gt;
&lt;br /&gt;
  // TODO: this needs to be refactored so that it can be also reused by the async/AJAX mode&lt;br /&gt;
  // to extract fields in the background (i.e. move to a separate function)&lt;br /&gt;
function transformationLoop(profile, post_id) {&lt;br /&gt;
  var output = {}, field;&lt;br /&gt;
  Host.dbLog(&amp;quot;Starting extraction/transformation loop&amp;quot;);&lt;br /&gt;
  for (field in profile) {&lt;br /&gt;
    if (field === 'name') continue;&lt;br /&gt;
    if (field ==='type' || field === 'event' || field === 'event_handler') continue; // skip fields that don't contain xpath expressions&lt;br /&gt;
    Host.dbLog(&amp;quot;Extracting field using field id:&amp;quot;+post_id);&lt;br /&gt;
    var fieldData = extractFieldInfo(profile, post_id, field);&lt;br /&gt;
    var transform = profile[field].transform;&lt;br /&gt;
    if (transform !== undefined) {&lt;br /&gt;
      Host.dbLog('Field \'' + field + '\' before transformation:\n\'' + fieldData + '\'');&lt;br /&gt;
      fieldData = applyTransformations(fieldData, transform);&lt;br /&gt;
      Host.dbLog('Field \'' + field + '\' after transformation:\n\'' + fieldData + '\'');&lt;br /&gt;
    }&lt;br /&gt;
    output[field] = fieldData;&lt;br /&gt;
  } // extract and transform all fields for the current profile (website)&lt;br /&gt;
  Host.dbLog(&amp;quot;extraction and transformation loop finished&amp;quot;);&lt;br /&gt;
  output.content = stripWhitespace(output.content);&lt;br /&gt;
  &lt;br /&gt;
  var outputPlain = createCquote(output);&lt;br /&gt;
  outputText(outputPlain, output);&lt;br /&gt;
} // transformationLoop()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/// #############&lt;br /&gt;
&lt;br /&gt;
function runProfileTests() {&lt;br /&gt;
  &lt;br /&gt;
  for (var profile in CONFIG) {&lt;br /&gt;
    if (CONFIG[profile].type != 'archive' || !CONFIG[profile].enabled ) continue; // skip the wiki entry, because it's not an actual archive that we need to test&lt;br /&gt;
    // should be really moved to downloadPostign&lt;br /&gt;
    if (CONFIG[profile].content.xpath === '') console.log(&amp;quot;xpath for content extraction is empty, cannot procedurally extract contents&amp;quot;);&lt;br /&gt;
    for (var test in CONFIG[profile].tests) {&lt;br /&gt;
      var required_data = CONFIG[profile].tests[test];&lt;br /&gt;
      var title = required_data.title;&lt;br /&gt;
      //dbLog('Running test for posting titled:' + title);&lt;br /&gt;
      // fetch posting via getPostingDataAJAX() and compare to the fields we are looking for (author, title, date)&lt;br /&gt;
      //getPostingDataAJAX(profile, required_data.url);&lt;br /&gt;
      //alert(&amp;quot;required title:&amp;quot;+title);&lt;br /&gt;
    } // foreach test&lt;br /&gt;
&lt;br /&gt;
  } // foreach profile (website)&lt;br /&gt;
  &lt;br /&gt;
} //runProfileTests&lt;br /&gt;
&lt;br /&gt;
function selfCheckDialog() {&lt;br /&gt;
  var sections = '&amp;lt;h3&amp;gt;Important APIs:&amp;lt;/h3&amp;gt;&amp;lt;div id=&amp;quot;api_checks&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;';&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  try {&lt;br /&gt;
   runProfileTests.call(undefined); // check website profiles&lt;br /&gt;
  }&lt;br /&gt;
  catch (e) {&lt;br /&gt;
      UI.alert(e.message);&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  for (var profile in CONFIG) {&lt;br /&gt;
    // TODO: also check if enabled or not&lt;br /&gt;
    if (CONFIG[profile].type != 'archive') continue; // skip the wiki entry, because it's not an actual archive that we need to test&lt;br /&gt;
    var test_results = '';&lt;br /&gt;
    for (var test in CONFIG[profile].tests) {&lt;br /&gt;
      // var fieldData = extractFieldInfo(profile, post_id, 'author');&lt;br /&gt;
      test_results += CONFIG[profile].tests[test].title + '&amp;lt;p/&amp;gt;';&lt;br /&gt;
    }&lt;br /&gt;
    sections +='&amp;lt;h3&amp;gt;' + profile + ':&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;'+ CONFIG[profile].url_reg+'&amp;lt;/font&amp;gt;&amp;lt;/h3&amp;gt;&amp;lt;div&amp;gt;&amp;lt;p&amp;gt;' + test_results + '&amp;lt;/p&amp;gt;&amp;lt;/div&amp;gt;\n';&lt;br /&gt;
  }  // https://jqueryui.com/accordion/&lt;br /&gt;
  &lt;br /&gt;
 &lt;br /&gt;
  var checkDlg = $('&amp;lt;div id=&amp;quot;selfCheck&amp;quot; title=&amp;quot;Self Check dialog&amp;quot;&amp;gt;&amp;lt;p&amp;gt;&amp;lt;div id=&amp;quot;accordion&amp;quot;&amp;gt;' + sections + '&amp;lt;/div&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;/div&amp;gt;');&lt;br /&gt;
  &lt;br /&gt;
   // run all API tests, invoke the callback to obtain the status&lt;br /&gt;
  Environment.runAPITests(Host, function(meta) {&lt;br /&gt;
  &lt;br /&gt;
  //console.log('Running API test '+meta.name);&lt;br /&gt;
    &lt;br /&gt;
  meta.test(function(result) {&lt;br /&gt;
   var status = (result)?'success':'fail';&lt;br /&gt;
   var test = $(&amp;quot;&amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&amp;quot;).text('Running API test '+meta.name+':'+status); &lt;br /&gt;
   $('#api_checks', checkDlg).append(test);&lt;br /&gt;
  }); // update tests results&lt;br /&gt;
    &lt;br /&gt;
  }); // runAPITests&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  /*&lt;br /&gt;
  [].forEach.call(CONFIG, function(profile) {&lt;br /&gt;
    alert(&amp;quot;profile is:&amp;quot;+profile);&lt;br /&gt;
  [].forEach.call(CONFIG[profile].tests, function(test) {&lt;br /&gt;
    &lt;br /&gt;
    //UI.alert(test.url);&lt;br /&gt;
    Host.downloadPosting(test.url, function(downloaded) {&lt;br /&gt;
      alert(&amp;quot;downloaded:&amp;quot;);&lt;br /&gt;
      //if (test.title == downloaded.title) alert(&amp;quot;titles match:&amp;quot;+test.title);&lt;br /&gt;
    }); //downloadPosting&lt;br /&gt;
  }); //forEach test&lt;br /&gt;
  }); //forEach profile&lt;br /&gt;
  */&lt;br /&gt;
  &lt;br /&gt;
  //$('#accordion',checkDlg).accordion();&lt;br /&gt;
  checkDlg.dialog({&lt;br /&gt;
    width: 700,&lt;br /&gt;
    height: 500,&lt;br /&gt;
    open: function () {&lt;br /&gt;
      // http://stackoverflow.com/questions/2929487/putting-a-jquery-ui-accordion-in-a-jquery-ui-dialog&lt;br /&gt;
      $('#accordion').accordion({&lt;br /&gt;
        autoHeight: true&lt;br /&gt;
      });&lt;br /&gt;
    }&lt;br /&gt;
  }); // show dialog&lt;br /&gt;
} // selfCheckDialog&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// show a simple configuration dialog (WIP)&lt;br /&gt;
function setupDialog() {&lt;br /&gt;
  //alert(&amp;quot;configuration dialog is not yet implemented&amp;quot;);&lt;br /&gt;
  var checked = (Host.get_persistent('debug_mode_enabled', false) === true) ? 'checked' : '';&lt;br /&gt;
  //dbLog(&amp;quot;value is:&amp;quot;+get_persistent(&amp;quot;debug_mode_enabled&amp;quot;));&lt;br /&gt;
  //dbLog(&amp;quot;persistent debug flag is:&amp;quot;+checked);&lt;br /&gt;
  var setupDiv = $('&amp;lt;div id=&amp;quot;setupDialog&amp;quot; title=&amp;quot;Setup dialog&amp;quot;&amp;gt;NOTE: this configuration dialog is still work-in-progress&amp;lt;/p&amp;gt;&amp;lt;label&amp;gt;&amp;lt;input id=&amp;quot;debugcb&amp;quot; type=&amp;quot;checkbox&amp;quot;' + checked + '&amp;gt;Enable Debug mode&amp;lt;/label&amp;gt;&amp;lt;p/&amp;gt;&amp;lt;div id=&amp;quot;progressbar&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;');&lt;br /&gt;
  setupDiv.click(function () {&lt;br /&gt;
    //alert(&amp;quot;changing persistent debug state&amp;quot;);&lt;br /&gt;
    Host.set_persistent('debug_mode_enabled', $('#debugcb').is(':checked'));&lt;br /&gt;
  });&lt;br /&gt;
  //MediaWiki editing stub, based on: https://www.mediawiki.org/wiki/API:Edit#Editing_via_Ajax&lt;br /&gt;
  //only added here to show some status info in the setup dialog&lt;br /&gt;
  Host.download('http://wiki.flightgear.org/api.php?action=query&amp;amp;prop=info|revisions&amp;amp;intoken=edit&amp;amp;rvprop=timestamp&amp;amp;titles=Main%20Page', function (response) {&lt;br /&gt;
    var message = 'FlightGear wiki login status (AJAX):';&lt;br /&gt;
    var status = response.statusText;&lt;br /&gt;
    var color = (status == 'OK') ? 'green' : 'red';&lt;br /&gt;
    Host.dbLog(message + status);&lt;br /&gt;
    var statusDiv = $('&amp;lt;p&amp;gt;' + message + status + '&amp;lt;/p&amp;gt;').css('color', color);&lt;br /&gt;
    setupDiv.append(statusDiv);&lt;br /&gt;
  });&lt;br /&gt;
  setupDiv.dialog();&lt;br /&gt;
} // setupDialog&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// this  can be used to download/cache $FG_ROOT/options.xml so that fgfs CLI arguments can be recognized and post-processed automatically&lt;br /&gt;
// which can help transforming postings correctly&lt;br /&gt;
function downloadOptionsXML() {&lt;br /&gt;
&lt;br /&gt;
  // download $FG_ROOT/options.xml&lt;br /&gt;
          Host.download(&amp;quot;https://sourceforge.net/p/flightgear/fgdata/ci/next/tree/options.xml?format=raw&amp;quot;, function(response) {&lt;br /&gt;
            var xml = response.responseText;&lt;br /&gt;
            var doc = Host.make_doc(xml, 'text/xml');&lt;br /&gt;
            // https://developer.mozilla.org/en-US/docs/Web/API/XPathResult&lt;br /&gt;
            var options = Host.eval_xpath(doc, '//*/option', XPathResult.ORDERED_NODE_SNAPSHOT_TYPE);&lt;br /&gt;
            &lt;br /&gt;
            // http://help.dottoro.com/ljgnejkp.php&lt;br /&gt;
            Host.dbLog(&amp;quot;Number of options found in options.xml:&amp;quot;+options.snapshotLength);&lt;br /&gt;
            &lt;br /&gt;
            // http://help.dottoro.com/ljtfvvpx.php&lt;br /&gt;
            &lt;br /&gt;
              // https://sourceforge.net/p/flightgear/fgdata/ci/next/tree/options.xml&lt;br /&gt;
              &lt;br /&gt;
            &lt;br /&gt;
          }); // end of options.xml download&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
} // downloadOptionsXML&lt;br /&gt;
&lt;br /&gt;
function getProfile(url=undefined) {&lt;br /&gt;
  &lt;br /&gt;
  if(url === undefined) &lt;br /&gt;
    url=window.location.href;&lt;br /&gt;
  else&lt;br /&gt;
    url=url;&lt;br /&gt;
  &lt;br /&gt;
  Host.dbLog(&amp;quot;getProfile call URL is:&amp;quot;+url);&lt;br /&gt;
  &lt;br /&gt;
  for (var profile in CONFIG) {&lt;br /&gt;
    if (url.match(CONFIG[profile].url_reg) !== null) {&lt;br /&gt;
      Host.dbLog('Matching website profile found');&lt;br /&gt;
      var invocations = Host.get_persistent(Host.getScriptVersion(), 0);&lt;br /&gt;
      Host.dbLog('Number of script invocations for version ' + Host.getScriptVersion() + ' is:' + invocations);&lt;br /&gt;
&lt;br /&gt;
      // determine if we want to show a config dialog&lt;br /&gt;
      if (invocations === 0) {&lt;br /&gt;
        Host.dbLog(&amp;quot;ask for config dialog to be shown&amp;quot;);&lt;br /&gt;
        var response = UI.confirm('This is your first time running version ' + Host.getScriptVersion() + '\nConfigure now?');&lt;br /&gt;
        if (response) {&lt;br /&gt;
                  &lt;br /&gt;
          // show configuration dialog (jQuery)&lt;br /&gt;
          setupDialog();&lt;br /&gt;
        } &lt;br /&gt;
        else {&lt;br /&gt;
        } // don't configure&lt;br /&gt;
&lt;br /&gt;
      }      &lt;br /&gt;
      &lt;br /&gt;
      // increment number of invocations, use the script's version number as the key, to prevent the config dialog from showing up again (except for updated scripts)&lt;br /&gt;
      // FIXME: this is triggered/incremented by each click ...&lt;br /&gt;
      Host.dbLog(&amp;quot;increment number of script invocations&amp;quot;);&lt;br /&gt;
      Host.set_persistent(Host.getScriptVersion(), invocations + 1);&lt;br /&gt;
      return CONFIG[profile];&lt;br /&gt;
    } // matched website profile&lt;br /&gt;
    Host.dbLog('Could not find matching URL in getProfile() call!');&lt;br /&gt;
  } // for each profile&lt;br /&gt;
}// Get the HTML code that is selected&lt;br /&gt;
&lt;br /&gt;
function getSelectedHtml() {&lt;br /&gt;
  // From http://stackoverflow.com/a/6668159&lt;br /&gt;
  var html = '',&lt;br /&gt;
  selection = document.getSelection();&lt;br /&gt;
  if (selection.rangeCount) {&lt;br /&gt;
    var container = document.createElement('div');&lt;br /&gt;
    for (var i = 0; i &amp;lt; selection.rangeCount; i++) {&lt;br /&gt;
      container.appendChild(selection.getRangeAt(i).cloneContents());&lt;br /&gt;
    }&lt;br /&gt;
    html = container.innerHTML;&lt;br /&gt;
  }&lt;br /&gt;
  Host.dbLog('instantCquote(): Unprocessed HTML\n\'' + html + '\'');&lt;br /&gt;
  return html;&lt;br /&gt;
}// Gets the selected text&lt;br /&gt;
&lt;br /&gt;
function getSelectedText() {&lt;br /&gt;
  return document.getSelection().toString();&lt;br /&gt;
}// Get the ID of the post&lt;br /&gt;
// (this needs some work so that it can be used by the AJAX mode, without an actual selection)&lt;br /&gt;
&lt;br /&gt;
function getPostId(selection, profile, focus) {&lt;br /&gt;
  if (focus !== undefined) {&lt;br /&gt;
    Host.dbLog(&amp;quot;Trying to get PostId with defined focus&amp;quot;);&lt;br /&gt;
    selection = selection.focusNode.parentNode;&lt;br /&gt;
  } else {&lt;br /&gt;
    Host.dbLog(&amp;quot;Trying to get PostId with undefined focus&amp;quot;);&lt;br /&gt;
    selection = selection.anchorNode.parentNode;&lt;br /&gt;
  }&lt;br /&gt;
  while (selection.id.match(profile.content.idStyle) === null) {&lt;br /&gt;
    selection = selection.parentNode;&lt;br /&gt;
  }&lt;br /&gt;
  Host.dbLog(&amp;quot;Selection id is:&amp;quot;+selection.id);&lt;br /&gt;
  return selection.id;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Checks that the selection is valid&lt;br /&gt;
function checkValid(selection, profile) {&lt;br /&gt;
  var ret = true,&lt;br /&gt;
  selection_cp = {&lt;br /&gt;
  },&lt;br /&gt;
  tags = profile.content.parentTag;&lt;br /&gt;
  for (var n = 0; n &amp;lt; 2; n++) {&lt;br /&gt;
    if (n === 0) {&lt;br /&gt;
      selection_cp = selection.anchorNode.parentNode;&lt;br /&gt;
    } else {&lt;br /&gt;
      selection_cp = selection.focusNode.parentNode;&lt;br /&gt;
    }&lt;br /&gt;
    while (true) {&lt;br /&gt;
      if (selection_cp.tagName === 'BODY') {&lt;br /&gt;
        ret = false;&lt;br /&gt;
        break;&lt;br /&gt;
      } else {&lt;br /&gt;
        var cont = false;&lt;br /&gt;
        for (var i = 0; i &amp;lt; tags.length; i++) {&lt;br /&gt;
          if (selection_cp[tags[0]] === tags[i]) {&lt;br /&gt;
            cont = true;&lt;br /&gt;
            break;&lt;br /&gt;
          }&lt;br /&gt;
        }&lt;br /&gt;
        if (cont) {&lt;br /&gt;
          break;&lt;br /&gt;
        } else {&lt;br /&gt;
          selection_cp = selection_cp.parentNode;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  ret = ret &amp;amp;&amp;amp; (getPostId(selection, profile) === getPostId(selection, profile, 1));&lt;br /&gt;
  return ret;&lt;br /&gt;
}// Extracts the raw text from a certain place, using an XPath&lt;br /&gt;
&lt;br /&gt;
function extractFieldInfo(profile, id, field) {&lt;br /&gt;
  &lt;br /&gt;
  if (field === 'content') {&lt;br /&gt;
    Host.dbLog(&amp;quot;Returning content (selection)&amp;quot;);&lt;br /&gt;
    return profile[field].selection();&lt;br /&gt;
  } else {&lt;br /&gt;
    Host.dbLog(&amp;quot;Extracting field via xpath:&amp;quot;+field);&lt;br /&gt;
    var xpath = '//*[@id=&amp;quot;' + id + '&amp;quot;]/' + profile[field].xpath;&lt;br /&gt;
    return Host.eval_xpath(document, xpath).stringValue; // document.evaluate(xpath, document, null, XPathResult.STRING_TYPE, null).stringValue;&lt;br /&gt;
  }&lt;br /&gt;
}// Change the text using specified transformations&lt;br /&gt;
&lt;br /&gt;
function applyTransformations(fieldInfo, trans) { &lt;br /&gt;
    for (var i = 0; i &amp;lt; trans.length; i++) {&lt;br /&gt;
      fieldInfo = trans[i](fieldInfo);&lt;br /&gt;
      Host.dbLog('applyTransformations(): Multiple transformation, transformation after loop #' + (i + 1) + ':\n\'' + fieldInfo + '\'');&lt;br /&gt;
    }&lt;br /&gt;
    return fieldInfo;&lt;br /&gt;
  &lt;br /&gt;
} //applyTransformations&lt;br /&gt;
&lt;br /&gt;
// Formats the quote&lt;br /&gt;
&lt;br /&gt;
function createCquote(data, indirect_speech=false) {&lt;br /&gt;
 if(!indirect_speech)&lt;br /&gt;
   return nonQuotedRef(data); // conventional/verbatim selection&lt;br /&gt;
  else { &lt;br /&gt;
    // pattern match the content using a vector of regexes&lt;br /&gt;
    data.content = transformSpeech(data.content, data.author, null, speechTransformations );&lt;br /&gt;
    return nonQuotedRef(data);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function nonQuotedRef(data) { //TODO: rename &lt;br /&gt;
  var template = Host.getTemplate();&lt;br /&gt;
  &lt;br /&gt;
  var substituted = template&lt;br /&gt;
  .replace('$CONTENT', data.content)&lt;br /&gt;
  .replace('$URL',data.url)&lt;br /&gt;
  .replace('$TITLE',data.title)  &lt;br /&gt;
  .replace('$AUTHOR',data.author)&lt;br /&gt;
  .replace('$DATE',datef(data.date))&lt;br /&gt;
  .replace('$ADDED',datef(data.date))&lt;br /&gt;
  .replace('$SCRIPT_VERSION', Host.getScriptVersion() );&lt;br /&gt;
  &lt;br /&gt;
  return substituted; &lt;br /&gt;
}// &lt;br /&gt;
&lt;br /&gt;
// Output the text.&lt;br /&gt;
// Tries the jQuery dialog, and falls back to window.prompt()&lt;br /&gt;
&lt;br /&gt;
function outputText(msg, original) {&lt;br /&gt;
  try {&lt;br /&gt;
    OUTPUT.jQueryTabbed(msg, original); &lt;br /&gt;
  } &lt;br /&gt;
  catch (err) {&lt;br /&gt;
    msg = msg.replace(/&amp;amp;lt;\/syntaxhighligh(.)&amp;gt;/g, '&amp;lt;/syntaxhighligh$1');&lt;br /&gt;
    OUTPUT.msgbox(msg);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// #############&lt;br /&gt;
// # Utilities #&lt;br /&gt;
// #############&lt;br /&gt;
&lt;br /&gt;
function extract(regex) {&lt;br /&gt;
  return function (text) {&lt;br /&gt;
    return text.match(regex) [1];&lt;br /&gt;
  };&lt;br /&gt;
}&lt;br /&gt;
function prepend(prefix) {&lt;br /&gt;
  return function (text) {&lt;br /&gt;
    return prefix + text;&lt;br /&gt;
  };&lt;br /&gt;
}&lt;br /&gt;
function removeComments(html) {&lt;br /&gt;
  return html.replace(/&amp;lt;!--.*?--&amp;gt;/g, '');&lt;br /&gt;
}// Not currently used (as of June 2015), but kept just in case&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// currently unused&lt;br /&gt;
function escapePipes(html) {&lt;br /&gt;
  html = html.replace(/\|\|/g, '{{!!}n}');&lt;br /&gt;
  html = html.replace(/\|\-/g, '{{!-}}');&lt;br /&gt;
  return html.replace(/\|/g, '{{!}}');&lt;br /&gt;
}// Converts HTML &amp;lt;a href=&amp;quot;...&amp;quot;&amp;gt;...&amp;lt;/a&amp;gt; tags to wiki links, internal if possible.&lt;br /&gt;
&lt;br /&gt;
function a2wikilink(html) {&lt;br /&gt;
  // Links to wiki images, because&lt;br /&gt;
  // they need special treatment, or else they get displayed.&lt;br /&gt;
  html = html.replace(/&amp;lt;a.*?href=&amp;quot;http:\/\/wiki\.flightgear\.org\/File:(.*?)&amp;quot;.*?&amp;gt;(.*?)&amp;lt;\/a&amp;gt;/g, '[[Media:$1|$2]]');&lt;br /&gt;
  // Wiki links without custom text.&lt;br /&gt;
  html = html.replace(/&amp;lt;a.*?href=&amp;quot;http:\/\/wiki\.flightgear\.org\/(.*?)&amp;quot;.*?&amp;gt;http:\/\/wiki\.flightgear\.org\/.*?&amp;lt;\/a&amp;gt;/g, '[[$1]]');&lt;br /&gt;
  // Links to the wiki with custom text&lt;br /&gt;
  html = html.replace(/&amp;lt;a.*?href=&amp;quot;http:\/\/wiki\.flightgear\.org\/(.*?)&amp;quot;.*?&amp;gt;(.*?)&amp;lt;\/a&amp;gt;/g, '[[$1|$2]]');&lt;br /&gt;
  // Remove underscores from all wiki links&lt;br /&gt;
  var list = html.match(/\[\[.*?\]\]/g);&lt;br /&gt;
  if (list !== null) {&lt;br /&gt;
    for (var i = 0; i &amp;lt; list.length; i++) {&lt;br /&gt;
      html = html.replace(list[i], underscore2Space(list[i]));&lt;br /&gt;
    }&lt;br /&gt;
  }  // Convert non-wiki links&lt;br /&gt;
  // TODO: identify forum/devel list links, and use the AJAX/Host.download helper to get a title/subject for unnamed links (using the existing xpath/regex helpers for that)&lt;br /&gt;
&lt;br /&gt;
  html = html.replace(/&amp;lt;a.*?href=&amp;quot;(.*?)&amp;quot;.*?&amp;gt;(.*?)&amp;lt;\/a&amp;gt;/g, '[$1 $2]');&lt;br /&gt;
  // Remove triple dots from external links.&lt;br /&gt;
  // Replace with raw URL (MediaWiki converts it to a link).&lt;br /&gt;
  list = html.match(/\[.*?(\.\.\.).*?\]/g);&lt;br /&gt;
  if (list !== null) {&lt;br /&gt;
    for (var i = 0; i &amp;lt; list.length; i++) {&lt;br /&gt;
      html = html.replace(list[i], list[i].match(/\[(.*?) .*?\]/) [1]);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return html;&lt;br /&gt;
}// Converts images, including images in &amp;lt;a&amp;gt; links&lt;br /&gt;
&lt;br /&gt;
function img2link(html) {&lt;br /&gt;
  html = html.replace(/&amp;lt;a[^&amp;lt;]*?href=&amp;quot;([^&amp;lt;]*?)&amp;quot;[^&amp;lt;]*?&amp;gt;&amp;lt;img.*?src=&amp;quot;http:\/\/wiki\.flightgear\.org\/images\/.*?\/.*?\/(.*?)&amp;quot;.*?&amp;gt;&amp;lt;\/a&amp;gt;/g, '[[File:$2|250px|link=$1]]');&lt;br /&gt;
  html = html.replace(/&amp;lt;img.*?src=&amp;quot;http:\/\/wiki\.flightgear\.org\/images\/.*?\/.*?\/(.*?)&amp;quot;.*?&amp;gt;/g, '[[File:$1|250px]]');&lt;br /&gt;
  html = html.replace(/&amp;lt;a[^&amp;lt;]*?href=&amp;quot;([^&amp;lt;]*?)&amp;quot;[^&amp;lt;]*?&amp;gt;&amp;lt;img.*?src=&amp;quot;(.*?)&amp;quot;.*?&amp;gt;&amp;lt;\/a&amp;gt;/g, '(see [$2 image], links to [$1 here])');&lt;br /&gt;
  return html.replace(/&amp;lt;img.*?src=&amp;quot;(.*?)&amp;quot;.*?&amp;gt;/g, '(see the [$1 linked image])');&lt;br /&gt;
}// Converts smilies&lt;br /&gt;
&lt;br /&gt;
function forum_smilies2text(html) {&lt;br /&gt;
  html = html.replace(/&amp;lt;img src=&amp;quot;\.\/images\/smilies\/icon_.*?\.gif&amp;quot; alt=&amp;quot;(.*?)&amp;quot;.*?&amp;gt;/g, '$1');&lt;br /&gt;
  for (var i = 0; i &amp;lt; EMOTICONS.length; i++) {&lt;br /&gt;
    html = html.replace(EMOTICONS[i][0], EMOTICONS[i][1]);&lt;br /&gt;
  }&lt;br /&gt;
  return html;&lt;br /&gt;
}// Converts font formatting&lt;br /&gt;
&lt;br /&gt;
function forum_fontstyle2wikistyle(html) {&lt;br /&gt;
  html = html.replace(/&amp;lt;span style=&amp;quot;font-weight: bold&amp;quot;&amp;gt;(.*?)&amp;lt;\/span&amp;gt;/g, '\'\'\'$1\'\'\'');&lt;br /&gt;
  html = html.replace(/&amp;lt;span style=&amp;quot;text-decoration: underline&amp;quot;&amp;gt;(.*?)&amp;lt;\/span&amp;gt;/g, '&amp;lt;u&amp;gt;$1&amp;lt;/u&amp;gt;');&lt;br /&gt;
  html = html.replace(/&amp;lt;span style=&amp;quot;font-style: italic&amp;quot;&amp;gt;(.*?)&amp;lt;\/span&amp;gt;/g, '\'\'$1\'\'');&lt;br /&gt;
  return html.replace(/&amp;lt;span class=&amp;quot;posthilit&amp;quot;&amp;gt;(.*?)&amp;lt;\/span&amp;gt;/g, '$1');&lt;br /&gt;
}// Converts code blocks&lt;br /&gt;
&lt;br /&gt;
function forum_code2syntaxhighlight(html) {&lt;br /&gt;
  var list = html.match(/&amp;lt;dl class=&amp;quot;codebox&amp;quot;&amp;gt;.*?&amp;lt;code&amp;gt;(.*?)&amp;lt;\/code&amp;gt;.*?&amp;lt;\/dl&amp;gt;/g),&lt;br /&gt;
  data = [&lt;br /&gt;
  ];&lt;br /&gt;
  if (list === null) return html;&lt;br /&gt;
  for (var n = 0; n &amp;lt; list.length; n++) {&lt;br /&gt;
    data = html.match(/&amp;lt;dl class=&amp;quot;codebox&amp;quot;&amp;gt;.*?&amp;lt;code&amp;gt;(.*?)&amp;lt;\/code&amp;gt;.*?&amp;lt;\/dl&amp;gt;/);&lt;br /&gt;
    html = html.replace(data[0], processCode(data));&lt;br /&gt;
  }&lt;br /&gt;
  return html;&lt;br /&gt;
}// Strips any whitespace from the beginning and end of a string&lt;br /&gt;
&lt;br /&gt;
function stripWhitespace(html) {&lt;br /&gt;
  html = html.replace(/^\s*?(\S)/, '$1');&lt;br /&gt;
  return html.replace(/(\S)\s*?\z/, '$1');&lt;br /&gt;
}// Process code, including basic detection of language&lt;br /&gt;
&lt;br /&gt;
function processCode(data) {&lt;br /&gt;
  var lang = '',&lt;br /&gt;
  code = data[1];&lt;br /&gt;
  code = code.replace(/&amp;amp;nbsp;/g, ' ');&lt;br /&gt;
  if (code.match(/=?.*?\(?.*?\)?;/) !== null) lang = 'nasal';&lt;br /&gt;
  if (code.match(/&amp;amp;lt;.*?&amp;amp;gt;.*?&amp;amp;lt;\/.*?&amp;amp;gt;/) !== null || code.match(/&amp;amp;lt;!--.*?--&amp;amp;gt;/) !== null) lang = 'xml';&lt;br /&gt;
  code = code.replace(/&amp;lt;br\/?&amp;gt;/g, '\n');&lt;br /&gt;
  return '&amp;lt;syntaxhighlight lang=&amp;quot;' + lang + '&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;\n' + code + '\n&amp;amp;lt;/syntaxhighlight&amp;gt;';&lt;br /&gt;
}// Converts quote blocks to Cquotes&lt;br /&gt;
&lt;br /&gt;
function forum_quote2cquote(html) {&lt;br /&gt;
  html = html.replace(/&amp;lt;blockquote class=&amp;quot;uncited&amp;quot;&amp;gt;&amp;lt;div&amp;gt;(.*?)&amp;lt;\/div&amp;gt;&amp;lt;\/blockquote&amp;gt;/g, '{{cquote|$1}}');&lt;br /&gt;
  if (html.match(/&amp;lt;blockquote&amp;gt;/g) === null) return html;&lt;br /&gt;
  var numQuotes = html.match(/&amp;lt;blockquote&amp;gt;/g).length;&lt;br /&gt;
  for (var n = 0; n &amp;lt; numQuotes; n++) {&lt;br /&gt;
    html = html.replace(/&amp;lt;blockquote&amp;gt;&amp;lt;div&amp;gt;&amp;lt;cite&amp;gt;(.*?) wrote.*?:&amp;lt;\/cite&amp;gt;(.*?)&amp;lt;\/div&amp;gt;&amp;lt;\/blockquote&amp;gt;/, '{{cquote|$2|$1}}');&lt;br /&gt;
  }&lt;br /&gt;
  return html;&lt;br /&gt;
}// Converts videos to wiki style&lt;br /&gt;
&lt;br /&gt;
function vid2wiki(html) {&lt;br /&gt;
  // YouTube&lt;br /&gt;
  html = html.replace(/&amp;lt;div class=&amp;quot;video-wrapper&amp;quot;&amp;gt;\s.*?&amp;lt;div class=&amp;quot;video-container&amp;quot;&amp;gt;\s*?&amp;lt;iframe class=&amp;quot;youtube-player&amp;quot;.*?width=&amp;quot;(.*?)&amp;quot; height=&amp;quot;(.*?)&amp;quot; src=&amp;quot;http:\/\/www\.youtube\.com\/embed\/(.*?)&amp;quot;.*?&amp;gt;&amp;lt;\/iframe&amp;gt;\s*?&amp;lt;\/div&amp;gt;\s*?&amp;lt;\/div&amp;gt;/g, '{{#ev:youtube|$3|$1x$2}}');&lt;br /&gt;
  // Vimeo&lt;br /&gt;
  html = html.replace(/&amp;lt;iframe src=&amp;quot;http:\/\/player\.vimeo\.com\/video\/(.*?)\?.*?&amp;quot; width=&amp;quot;(.*?)&amp;quot; height=&amp;quot;(.*?)&amp;quot;.*?&amp;gt;.*?&amp;lt;\/iframe&amp;gt;/g, '{{#ev:vimeo|$1|$2x$3}}');&lt;br /&gt;
  return html.replace(/\[.*? Watch on Vimeo\]/g, '');&lt;br /&gt;
}// Not currently used (as of June 2015), but kept just in case&lt;br /&gt;
&lt;br /&gt;
// currently unused&lt;br /&gt;
function escapeEquals(html) {&lt;br /&gt;
  return html.replace(/=/g, '{{=}}');&lt;br /&gt;
}// &amp;lt;br&amp;gt; to newline.&lt;br /&gt;
&lt;br /&gt;
function forum_br2newline(html) {&lt;br /&gt;
  html = html.replace(/&amp;lt;br\/?&amp;gt;&amp;lt;br\/?&amp;gt;/g, '\n');&lt;br /&gt;
  return html.replace(/&amp;lt;br\/?&amp;gt;/g, '\n\n');&lt;br /&gt;
}// Forum list to wiki style&lt;br /&gt;
&lt;br /&gt;
function list2wiki(html) {&lt;br /&gt;
  var list = html.match(/&amp;lt;ul&amp;gt;(.*?)&amp;lt;\/ul&amp;gt;/g);&lt;br /&gt;
  if (list !== null) {&lt;br /&gt;
    for (var i = 0; i &amp;lt; list.length; i++) {&lt;br /&gt;
      html = html.replace(/&amp;lt;li&amp;gt;(.*?)&amp;lt;\/li&amp;gt;/g, '* $1\n');&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  list = html.match(/&amp;lt;ol.*?&amp;gt;(.*?)&amp;lt;\/ol&amp;gt;/g);&lt;br /&gt;
  if (list !== null) {&lt;br /&gt;
    for (var i = 0; i &amp;lt; list.length; i++) {&lt;br /&gt;
      html = html.replace(/&amp;lt;li&amp;gt;(.*?)&amp;lt;\/li&amp;gt;/g, '# $1\n');&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  html = html.replace(/&amp;lt;\/?[uo]l&amp;gt;/g, '');&lt;br /&gt;
  return html;&lt;br /&gt;
}&lt;br /&gt;
function nowiki(text) {&lt;br /&gt;
  return '&amp;lt;nowiki&amp;gt;' + text + '&amp;lt;/nowiki&amp;gt;';&lt;br /&gt;
}// Returns the correct ordinal adjective&lt;br /&gt;
&lt;br /&gt;
function ordAdj(date) {&lt;br /&gt;
  date = date.toString();&lt;br /&gt;
  if (date == '11' || date == '12' || date == '13') {&lt;br /&gt;
    return 'th';&lt;br /&gt;
  } else if (date.substr(1) == '1' || date == '1') {&lt;br /&gt;
    return 'st';&lt;br /&gt;
  } else if (date.substr(1) == '2' || date == '2') {&lt;br /&gt;
    return 'nd';&lt;br /&gt;
  } else if (date.substr(1) == '3' || date == '3') {&lt;br /&gt;
    return 'rd';&lt;br /&gt;
  } else {&lt;br /&gt;
    return 'th';&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Formats the date to this format: Apr 26th, 2015&lt;br /&gt;
function datef(text) {&lt;br /&gt;
  var date = new Date(text);&lt;br /&gt;
  return MONTHS[date.getMonth()] + ' ' + date.getDate() + ordAdj(date.getDate()) + ', ' + date.getFullYear();&lt;br /&gt;
}&lt;br /&gt;
function underscore2Space(str) {&lt;br /&gt;
  return str.replace(/_/g, ' ');&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// IGNORE EVERYTHING THAT FOLLOWS: &lt;br /&gt;
// This is an experiment to use GA/GP (genetic programming) to help procedurally evolve xpath and regex expressions if/when the underlying websites change&lt;br /&gt;
// so that we don't have to manually update/edit the script accordingly (this would also work for mobile themes etc)&lt;br /&gt;
// For now, this is heavily based on the genetic.js framework/examples: http://subprotocol.com/system/genetic-hello-world.html&lt;br /&gt;
// The idea is to evolve the xpath/regex expression by evaluating its return value against the expected/desired value&lt;br /&gt;
// the most important thing here is having a suitable fitness function&lt;br /&gt;
// &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function evolve_expression_test() {&lt;br /&gt;
  &lt;br /&gt;
try {  &lt;br /&gt;
var genetic = Genetic.create();&lt;br /&gt;
&lt;br /&gt;
// TODO: use minimizer: redundant_bytes + duration_msec + xpath.length&lt;br /&gt;
genetic.optimize = Genetic.Optimize.Maximize;&lt;br /&gt;
genetic.select1 = Genetic.Select1.Tournament2;&lt;br /&gt;
genetic.select2 = Genetic.Select2.Tournament2;&lt;br /&gt;
 &lt;br /&gt;
   &lt;br /&gt;
genetic.seed = function() {&lt;br /&gt;
&lt;br /&gt;
    function randomString(len) {&lt;br /&gt;
        var text = &amp;quot;&amp;quot;;&lt;br /&gt;
        var charset = &amp;quot;\\abcdefghijklmnopqrstuvwxyz0123456789[] ()&amp;lt;&amp;gt;*.,&amp;quot;;&lt;br /&gt;
        for(var i=0;i&amp;lt;len;i++)&lt;br /&gt;
            text += charset.charAt(Math.floor(Math.random() * charset.length));&lt;br /&gt;
        &lt;br /&gt;
        return text; // &amp;quot;From:&amp;amp;(.*)$&amp;lt;.*8.*&amp;gt;&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // create random strings that are equal in length to solution&lt;br /&gt;
    return randomString( this.userData[&amp;quot;solution&amp;quot;].length);&lt;br /&gt;
};&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
genetic.mutate = function(entity) {&lt;br /&gt;
    &lt;br /&gt;
    function replaceAt(str, index, character) {&lt;br /&gt;
        return str.substr(0, index) + character + str.substr(index+character.length);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // chromosomal drift&lt;br /&gt;
    var i = Math.floor(Math.random()*entity.length);&lt;br /&gt;
    return replaceAt(entity, i, String.fromCharCode(entity.charCodeAt(i) + (Math.floor(Math.random()*2) ? 1 : -1)));&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
genetic.crossover = function(mother, father) {&lt;br /&gt;
&lt;br /&gt;
    // two-point crossover&lt;br /&gt;
    var len = mother.length;&lt;br /&gt;
    var ca = Math.floor(Math.random()*len);&lt;br /&gt;
    var cb = Math.floor(Math.random()*len);     &lt;br /&gt;
    if (ca &amp;gt; cb) {&lt;br /&gt;
        var tmp = cb;&lt;br /&gt;
        cb = ca;&lt;br /&gt;
        ca = tmp;&lt;br /&gt;
    }&lt;br /&gt;
        &lt;br /&gt;
    var son = father.substr(0,ca) + mother.substr(ca, cb-ca) + father.substr(cb);&lt;br /&gt;
    var daughter = mother.substr(0,ca) + father.substr(ca, cb-ca) + mother.substr(cb);&lt;br /&gt;
    &lt;br /&gt;
    return [son, daughter];&lt;br /&gt;
};&lt;br /&gt;
    &lt;br /&gt;
genetic.determineExcessBytes = function (text, needle) {&lt;br /&gt;
    return text.length - needle.length;&lt;br /&gt;
};&lt;br /&gt;
    &lt;br /&gt;
genetic.containsText = function (text, needle) {&lt;br /&gt;
    return text.search(needle);&lt;br /&gt;
};&lt;br /&gt;
  &lt;br /&gt;
genetic.isValid = function(exp) {&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
    &lt;br /&gt;
/* myFitness:&lt;br /&gt;
 * - must be a valid xpath/regex expression (try/call)&lt;br /&gt;
 * - must containsText the needle&lt;br /&gt;
 * - low relative offset in text (begin/end)&lt;br /&gt;
 * - excessBytes&lt;br /&gt;
 * - short expression  (expression length)&lt;br /&gt;
 * - expression footprint (runtime)&lt;br /&gt;
 */ &lt;br /&gt;
&lt;br /&gt;
// TODO: the fitness function should validate each xpath/regex first&lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
genetic.fitness = function(entity) {&lt;br /&gt;
    var fitness = 0;&lt;br /&gt;
    var result;&lt;br /&gt;
    var validExp = 0.1;&lt;br /&gt;
    var hasToken = 0.1;&lt;br /&gt;
   &lt;br /&gt;
  &lt;br /&gt;
    var t = this.userData.tests[0].haystack;&lt;br /&gt;
    //var regex = new RegExp(this.userData.solution);&lt;br /&gt;
    //var output = t.match( new RegExp(&amp;quot;From: (.*) &amp;lt;.*@.*&amp;gt;&amp;quot;))[1];  &lt;br /&gt;
    // TODO: use search &amp;amp; match for improving the fitness&lt;br /&gt;
  &lt;br /&gt;
    if (0)  &lt;br /&gt;
    try {&lt;br /&gt;
    var regex = new RegExp(entity);&lt;br /&gt;
    var output = t.search( regex);&lt;br /&gt;
    validExp = 5;&lt;br /&gt;
    //if (output) validExp = 50;&lt;br /&gt;
    }&lt;br /&gt;
    catch(e) {&lt;br /&gt;
    //validExp = 2;    &lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
   &lt;br /&gt;
    &lt;br /&gt;
    var i;&lt;br /&gt;
    for (i=0;i&amp;lt;entity.length;++i) {&lt;br /&gt;
        // increase fitness for each character that matches&lt;br /&gt;
        if (entity[i] == this.userData[&amp;quot;solution&amp;quot;][i])&lt;br /&gt;
            fitness += 1;&lt;br /&gt;
        &lt;br /&gt;
        // award fractions of a point as we get warmer&lt;br /&gt;
        fitness += (127-Math.abs(entity.charCodeAt(i) - this.userData[&amp;quot;solution&amp;quot;].charCodeAt(i)))/50;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
    return fitness + (1*validExp + 1* hasToken);&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
genetic.generation = function(pop, generation, stats) {&lt;br /&gt;
    // stop running once we've reached the solution&lt;br /&gt;
    return pop[0].entity != this.userData[&amp;quot;solution&amp;quot;];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
genetic.notification = function(pop, generation, stats, isFinished) {&lt;br /&gt;
&lt;br /&gt;
    function lerp(a, b, p) {&lt;br /&gt;
        return a + (b-a)*p;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    var value = pop[0].entity;&lt;br /&gt;
    this.last = this.last||value;&lt;br /&gt;
    &lt;br /&gt;
    if (pop != 0 &amp;amp;&amp;amp; value == this.last)&lt;br /&gt;
        return;&lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
    var solution = [];&lt;br /&gt;
    var i;&lt;br /&gt;
    for (i=0;i&amp;lt;value.length;++i) {&lt;br /&gt;
        var diff = value.charCodeAt(i) - this.last.charCodeAt(i);&lt;br /&gt;
        var style = &amp;quot;background: transparent;&amp;quot;;&lt;br /&gt;
        if (diff &amp;gt; 0) {&lt;br /&gt;
            style = &amp;quot;background: rgb(0,200,50); color: #fff;&amp;quot;;&lt;br /&gt;
        } else if (diff &amp;lt; 0) {&lt;br /&gt;
            style = &amp;quot;background: rgb(0,100,50); color: #fff;&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        solution.push(&amp;quot;&amp;lt;span style=\&amp;quot;&amp;quot; + style + &amp;quot;\&amp;quot;&amp;gt;&amp;quot; + value[i] + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
    var t = this.userData.tests[0].haystack;&lt;br /&gt;
    //console.log(&amp;quot;haystack is:&amp;quot;+t);&lt;br /&gt;
    // &amp;quot;From: John Doe &amp;lt;John@do...&amp;gt; - 2020-07-02 17:36:03&amp;quot;, needle: &amp;quot;John Doe&amp;quot;}, /From: (.*) &amp;lt;.*@.*&amp;gt;/&lt;br /&gt;
    var regex = new RegExp(this.userData.solution);&lt;br /&gt;
    //var output = t.match( new RegExp(&amp;quot;From: (.*) &amp;lt;.*@.*&amp;gt;&amp;quot;))[1];  &lt;br /&gt;
    // TODO: use search &amp;amp; match for improving the fitness&lt;br /&gt;
    var output = t.search( new RegExp(value));&lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
    var buf = &amp;quot;&amp;quot;;&lt;br /&gt;
    buf += &amp;quot;&amp;lt;tr&amp;gt;&amp;quot;;&lt;br /&gt;
    buf += &amp;quot;&amp;lt;td&amp;gt;&amp;quot; + generation + &amp;quot;&amp;lt;/td&amp;gt;&amp;quot;;&lt;br /&gt;
    buf += &amp;quot;&amp;lt;td&amp;gt;&amp;quot; + pop[0].fitness.toPrecision(5) + &amp;quot;&amp;lt;/td&amp;gt;&amp;quot;;&lt;br /&gt;
    buf += &amp;quot;&amp;lt;td&amp;gt;&amp;quot; + solution.join(&amp;quot;&amp;quot;) + &amp;quot;&amp;lt;/td&amp;gt;&amp;quot;;&lt;br /&gt;
    buf += &amp;quot;&amp;lt;td&amp;gt;&amp;quot; + output + &amp;quot;&amp;lt;/td&amp;gt;&amp;quot;;&lt;br /&gt;
    buf += &amp;quot;&amp;lt;/tr&amp;gt;&amp;quot;;&lt;br /&gt;
    $(&amp;quot;#results tbody&amp;quot;).prepend(buf);&lt;br /&gt;
    &lt;br /&gt;
    this.last = value;&lt;br /&gt;
};&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  /*&lt;br /&gt;
genetic.notification2 = function(pop, generation, stats, isFinished) {&lt;br /&gt;
&lt;br /&gt;
    function lerp(a, b, p) {&lt;br /&gt;
        return a + (b-a)*p;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    var value = pop[0].entity;&lt;br /&gt;
    this.last = this.last||value;&lt;br /&gt;
    &lt;br /&gt;
    if (pop != 0 &amp;amp;&amp;amp; value == this.last)&lt;br /&gt;
        return;&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    var solution = [];&lt;br /&gt;
    var i;&lt;br /&gt;
    for (i=0;i&amp;lt;value.length;++i) {&lt;br /&gt;
    &lt;br /&gt;
    solution.push(value[i]);&lt;br /&gt;
 } &lt;br /&gt;
    console.log(&amp;quot;Generation:&amp;quot;+ generation + &amp;quot; Fitness:&amp;quot; + pop[0].fitness.toPrecision(5) + &amp;quot; Solution:&amp;quot; + solution.join(&amp;quot;&amp;quot;));&lt;br /&gt;
  &lt;br /&gt;
    this.last = value;&lt;br /&gt;
};&lt;br /&gt;
  */&lt;br /&gt;
    &lt;br /&gt;
      &lt;br /&gt;
var config = {&lt;br /&gt;
            &amp;quot;iterations&amp;quot;: 4000&lt;br /&gt;
            , &amp;quot;size&amp;quot;: 250&lt;br /&gt;
            , &amp;quot;crossover&amp;quot;: 0.3&lt;br /&gt;
            , &amp;quot;mutation&amp;quot;: 0.4&lt;br /&gt;
            , &amp;quot;skip&amp;quot;: 30 // notifications&lt;br /&gt;
            //, &amp;quot;webWorkers&amp;quot;: false&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
var profile = CONFIG['Sourceforge Mailing list'];&lt;br /&gt;
var posting = profile.tests[0];&lt;br /&gt;
var author_xpath = profile.title.xpath;&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
var regexTests = [&lt;br /&gt;
  {haystack: &amp;quot;From: John Doe &amp;lt;John@do...&amp;gt; - 2020-07-02 17:36:03&amp;quot;, needle: &amp;quot;John Doe&amp;quot;}, &lt;br /&gt;
  {haystack: &amp;quot;From: Marc Twain &amp;lt;Marc@ta...&amp;gt; - 2010-01-03 07:36:03&amp;quot;, needle: &amp;quot;Marc Twain&amp;quot;},&lt;br /&gt;
  {haystack: &amp;quot;From: George W. Bush &amp;lt;GWB@wh...&amp;gt; - 2055-11-11 17:33:13&amp;quot;, needle: &amp;quot;George W. Bush&amp;quot;}&lt;br /&gt;
];&lt;br /&gt;
  &lt;br /&gt;
// the regex we want to evolve&lt;br /&gt;
var solution = &amp;quot;From: (.*) &amp;lt;.*@.*&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// let's assume, we'd like to evolve a regex expression like this one&lt;br /&gt;
var userData = {&lt;br /&gt;
            solution: solution,&lt;br /&gt;
            tests: regexTests                         &lt;br /&gt;
};    &lt;br /&gt;
    &lt;br /&gt;
genetic.evolve(config, userData);&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
//console.log(&amp;quot;genetic.js is loaded and working, but disabled for now&amp;quot;);    &lt;br /&gt;
    &lt;br /&gt;
  &lt;br /&gt;
} // try&lt;br /&gt;
catch (e) {&lt;br /&gt;
  console.log(&amp;quot;genetic.js error:\n&amp;quot; +e.message);&lt;br /&gt;
} // catch&lt;br /&gt;
  &lt;br /&gt;
} // evolveExpression_test()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if(0) //TODO: expose via development tab&lt;br /&gt;
try {&lt;br /&gt;
  // https://github.com/cazala/synaptic&lt;br /&gt;
  var Neuron = synaptic.Neuron,&lt;br /&gt;
    Layer = synaptic.Layer,&lt;br /&gt;
    Network = synaptic.Network,&lt;br /&gt;
    Trainer = synaptic.Trainer,&lt;br /&gt;
    Architect = synaptic.Architect;&lt;br /&gt;
  &lt;br /&gt;
  function Perceptron(input, hidden, output)&lt;br /&gt;
{&lt;br /&gt;
    // create the layers&lt;br /&gt;
    var inputLayer = new Layer(input);&lt;br /&gt;
    var hiddenLayer = new Layer(hidden);&lt;br /&gt;
    var outputLayer = new Layer(output);&lt;br /&gt;
&lt;br /&gt;
    // connect the layers&lt;br /&gt;
    inputLayer.project(hiddenLayer);&lt;br /&gt;
    hiddenLayer.project(outputLayer);&lt;br /&gt;
&lt;br /&gt;
    // set the layers&lt;br /&gt;
    this.set({&lt;br /&gt;
        input: inputLayer,&lt;br /&gt;
        hidden: [hiddenLayer],&lt;br /&gt;
        output: outputLayer&lt;br /&gt;
    });&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// extend the prototype chain&lt;br /&gt;
Perceptron.prototype = new Network();&lt;br /&gt;
Perceptron.prototype.constructor = Perceptron;&lt;br /&gt;
  &lt;br /&gt;
var myPerceptron = new Perceptron(2,3,1);&lt;br /&gt;
var myTrainer = new Trainer(myPerceptron);&lt;br /&gt;
&lt;br /&gt;
myTrainer.XOR(); // { error: 0.004998819355993572, iterations: 21871, time: 356 }&lt;br /&gt;
&lt;br /&gt;
myPerceptron.activate([0,0]); // 0.0268581547421616&lt;br /&gt;
myPerceptron.activate([1,0]); // 0.9829673642853368&lt;br /&gt;
myPerceptron.activate([0,1]); // 0.9831714267395621&lt;br /&gt;
myPerceptron.activate([1,1]); // 0.02128894618097928&lt;br /&gt;
  &lt;br /&gt;
   &lt;br /&gt;
console.log(&amp;quot;Syntaptic loaded&amp;quot;);&lt;br /&gt;
} catch(e) {&lt;br /&gt;
  UI.alert(e.message);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Appendix}}&lt;/div&gt;</summary>
		<author><name>Elgaton</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=FlightGear_wiki:Instant-Refs&amp;diff=98422</id>
		<title>FlightGear wiki:Instant-Refs</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=FlightGear_wiki:Instant-Refs&amp;diff=98422"/>
		<updated>2016-05-20T12:20:56Z</updated>

		<summary type="html">&lt;p&gt;Elgaton: /* Installation */ Styling&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Quotes-logo-200x200.png|thumb]]&lt;br /&gt;
[[File:Instant-cquotes-firefox.png|thumb|Instant-Cquotes script in Firefox]]&lt;br /&gt;
&lt;br /&gt;
[[File:Ref-only-quotes.png|thumb|Instant-Cquotes screenshot prototyping runtime format selection]]&lt;br /&gt;
&lt;br /&gt;
The '''Instant-Cquotes''' script is a browser addon (user script) implemented in JavaScript in order to convert excerpts (created via copy&amp;amp;paste) from FlightGear forum or [[mailing list]] postings into MediaWiki markup/quotes to be used on the FlightGear wiki. It is supported by Firefox, Google Chrome/Chromium, Opera and Safari. It is being developed and maintained by a group of volunteers involved in maintaining the wiki and in trying to provide more up-to-date information to end-users who may not be as involved in the various FlightGear-related communication channels.&lt;br /&gt;
&lt;br /&gt;
== Background and motivation ==&lt;br /&gt;
FlightGear's development is, at best, &amp;quot;self-coordinated&amp;quot;, meaning that contributors discuss ideas and make proposals to contribute in a certain fashion and then team up to implement certain features and building blocks, often just temporarily.&lt;br /&gt;
&lt;br /&gt;
Unfortunately, due to a lack of development manpower, many ideas are not implemented immediately; it is, thus, important to know their pros and cons, as well as who originally proposed them and/or might help with their implementation, even after a long time, preferably with links to the original discussions so that new contributors can decide whether to get involved in some effort or not. The project documentation, however, is in great need of improvement&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
| url    = http://sourceforge.net/p/flightgear/mailman/message/15444440/&lt;br /&gt;
| title  = &amp;lt;nowiki&amp;gt;[Flightgear-devel] development process (was:  chaos...)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| author = &amp;lt;nowiki&amp;gt;John Denker&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| date   = Jul 16th, 2007&lt;br /&gt;
| added   = Jul 16th, 2007&lt;br /&gt;
| script_version = 0.23&lt;br /&gt;
}}&amp;lt;/ref&amp;gt; and usually significantly lacking behind:&amp;lt;ref name=&amp;quot;OlsonStateThingsFG&amp;quot;&amp;gt;{{cite web&lt;br /&gt;
| url    = http://sourceforge.net/p/flightgear/mailman/message/27861667/&lt;br /&gt;
| title  = &amp;lt;nowiki&amp;gt;Re: [Flightgear-devel] The state of things in Flight Gear&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| author = &amp;lt;nowiki&amp;gt;Curtis Olson&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| date   = Jul 27th, 2011&lt;br /&gt;
| added   = Jul 27th, 2011&lt;br /&gt;
| script_version = 0.23&lt;br /&gt;
}}&amp;lt;/ref&amp;gt; many core developers update it seldomly, if not anymore, as it takes time to write it, as well as an understanding of the inner workings of a complex system such as FlightGear. Furthermore, this task might not be attractive due to its short term impact on the project,&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
| url    = http://sourceforge.net/p/flightgear/mailman/message/27861562/&lt;br /&gt;
| title  = &amp;lt;nowiki&amp;gt;Re: [Flightgear-devel] The state of things in Flight Gear&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| author = &amp;lt;nowiki&amp;gt;Hal V. Engel&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| date   = Jul 27th, 2011&lt;br /&gt;
| added   = Jul 27th, 2011&lt;br /&gt;
| script_version = 0.23&lt;br /&gt;
}}&amp;lt;/ref&amp;gt; and it is overwhelming to think about creating documentation that would address the needs of many different kinds of contributors with different backgrounds, experience levels and goals.&amp;lt;ref name=&amp;quot;OlsonStateThingsFG&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Forum and mailing lists discussions have therefore become the only up-to-date (albeit difficult to filter)&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
| url    = http://forum.flightgear.org/viewtopic.php?p=280058#p280058&lt;br /&gt;
| title  = &amp;lt;nowiki&amp;gt;Re: quoting on the wiki&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| author = &amp;lt;nowiki&amp;gt;Thorsten&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| date   = Mar 21st, 2016&lt;br /&gt;
| added   = Mar 21st, 2016&lt;br /&gt;
| script_version = 0.25&lt;br /&gt;
}}&amp;lt;/ref&amp;gt; source of information about recent development progress; this makes it tricky to know what is going on, what needs fixing, what were the decisions taken by the developers.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
| url    = https://www.mail-archive.com/flightgear-devel%40lists.sourceforge.net/msg17198.html&lt;br /&gt;
| title  = &amp;lt;nowiki&amp;gt;[Flightgear-devel] Project tracking&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| author = &amp;lt;nowiki&amp;gt;James Turner&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| date   = Mon, 28 Jul 2008 10:06:05 -0700&lt;br /&gt;
}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The aim of the Instant-Cquotes script is to help wiki editors to copy relevant excerpts from such sources, formatting them as proper [[Template:Cquote|quotations]], and bootstrap new articles collecting them until a dedicated rewrite is made. It can also be used to reuse announcements to update the changelogs, [[Next newsletter|newsletter]] or the [[Release plan/Lessons learned]] page.&lt;br /&gt;
&lt;br /&gt;
After being away from the wiki system for some time it becomes more of an effort to re-learn how to start a new file and figure out how to format it , with what headings, etc. Sometimes it is almost too much to do the original write up of the original post and all the work of that layout and effort to have to also duplicate it in a wiki article. If I was a little more current and affluent with the wiki editor, I might not be so hesitant to create the work there instead of the forum.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=284698#p284698 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Breaking down NLCD raster image &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; wlbragg &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  May 9th, 2016 &lt;br /&gt;
  |added  =  May 9th, 2016 &lt;br /&gt;
  |script_version = 0.38 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In a few cases, such collections of quotes helped not only create bootstrap new articles, but even actual features.&lt;br /&gt;
&lt;br /&gt;
In other cases, quotes have been used to update documentation of features (e.g. [[Rembrandt]]) whose maintainers may not be actively involved in FlightGear, to help document discussions that are taking place in the meantime, and provide some background information for people interested in the corresponding feature.&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
# Install a user script manager. On Firefox, you can use [https://addons.mozilla.org/en-US/firefox/addon/greasemonkey/ Greasemonkey]; on Chrome/Chromium, Opera or Safari, you can use [https://tampermonkey.net/ Tampermonkey] (download links: [https://tampermonkey.net/index.php?ext=dhdg&amp;amp;browser=chrome Chrome/Chromium], [https://tampermonkey.net/index.php?ext=dhdg&amp;amp;browser=opera Opera], [https://tampermonkey.net/index.php?ext=dhdg&amp;amp;browser=safari Safari]).&lt;br /&gt;
# Visit [https://greasyfork.org/en/scripts/19331-instant-cquotes the Instant-Cquotes page on GreasyFork] and click on {{button|Install this script}} (green button). If Greasemonkey/Tampermonkey prompts you to confirm the installation, agree to do so.&lt;br /&gt;
&lt;br /&gt;
[[File:Howto-install-instant-cquotes.png|thumb|Click the green button to install the script]]&lt;br /&gt;
&lt;br /&gt;
=== Manual installation ===&lt;br /&gt;
{{note|This will install the most recent development version of the script, which might contain bugs. Also, GreaseMonkey/TamperMonkey will not update it automatically whenever a new version is released.}}&lt;br /&gt;
&lt;br /&gt;
* '''Firefox'''&lt;br /&gt;
# Install Greasemonkey.&lt;br /&gt;
# Save [[#The Script|the script]] below as &amp;lt;code&amp;gt;instant_cquotes.user.js&amp;lt;/code&amp;gt;, then drag-and-drop it into Firefox.&lt;br /&gt;
[[File:Greasemonkey-setup-on-firefox.png|thumb|Screenshot showing the Greasemonkey setup dialog (on Firefox)]]&lt;br /&gt;
&lt;br /&gt;
* '''Chrome/Chromium''', '''Opera''', or '''Safari'''&lt;br /&gt;
# Install Tampermonkey.&lt;br /&gt;
# Navigate to '''Add a new Script'''.&lt;br /&gt;
# Copy and paste [[#The Script|the script]] below into the editing window.&lt;br /&gt;
# Click the {{button|Save}} button (just above the {{button|Search}} button).&lt;br /&gt;
&lt;br /&gt;
=== Mobile installation ===&lt;br /&gt;
As of May 2016, there is no separate version available for mobile use. Your best chance is installing a userscript addon on Android, like one of those:&lt;br /&gt;
* [https://play.google.com/store/apps/details?id=net.biniok.tampermonkey Tampermonkey (Google Play Store)]&lt;br /&gt;
* [http://oilcan.jsharkey.org/ OilCan: Greasemonkey on steroids for Android]&lt;br /&gt;
&lt;br /&gt;
For installation instructions, refer to [https://openuserjs.org/about/Tampermonkey-for-Android Tampermonkey for Android] or [http://www.blogtechnika.com/how-to-access-greasemonkey-scripts-on-android-phones/ How To Access Greasemonkey Scripts on Android Phones].&lt;br /&gt;
&lt;br /&gt;
Testing/feedback would obviously be appreciated - if in doubt, feel free to just edit the wiki page to add your findings/questions.&lt;br /&gt;
&lt;br /&gt;
=== Configuration ===&lt;br /&gt;
[[File:User-script-menu.png|thumb|GreaseMonkey menu shown in FireFox with instanct cquotes menu items]]&lt;br /&gt;
&lt;br /&gt;
[[File:Config-dialog-instant-cquotes.png|thumb|The configuration dialog for the Instant-Cquotes script]]&lt;br /&gt;
&lt;br /&gt;
As of version 0.30, a dedicated configuration dialog is in the process of being added, so that certain script features can be dynamically configured, without having to edit the script. For now, this is merely a placeholder that provides a checkbox to easily enable/disable the debug mode. In the future, we are hoping to also expose other features this way.&lt;br /&gt;
&lt;br /&gt;
== Usage ==&lt;br /&gt;
[[File:Updated-cquotes-script-by-redleader.png|thumb|Instant-Cquotes script, with updates contributed by Red Leader]]&lt;br /&gt;
&lt;br /&gt;
[[File:New-cquotes.png|thumb|Screenshot showing Instant-Cquotes 0.30 at work]]&lt;br /&gt;
&lt;br /&gt;
# Go to some [[mailing list]] archive URL, for example [http://sourceforge.net/p/flightgear/mailman/message/32400727/] or any forum message, such as {{forumref|title=Re: Get objects to show up on Map/Radar|t=23299|label=p212558|f=71}}.&lt;br /&gt;
# Select the relevant portion of text.&lt;br /&gt;
# When you release the mouse button, a box will appear containing the converted text (for now, mainly properly-referenced quotes for the wiki).&lt;br /&gt;
# As the text will already be selected for you, press {{key press|Ctrl|C}} to copy it (no longer necessary).&lt;br /&gt;
# Paste the text into the desired wiki page.&lt;br /&gt;
&lt;br /&gt;
For example, by selecting part of the forum post in the link above you can get the following quotation:&lt;br /&gt;
&lt;br /&gt;
{{FGCquote&lt;br /&gt;
|1= The upcoming FlightGear version (3.2) will contain a canvas-based map dialog, including a modular &amp;quot;plugin&amp;quot; system for creating custom map layers and charts with roughly ~50 lines of code, most of it boilerplate. &lt;br /&gt;
This is entirely XML/Nasal based (scripted) - symbols can be pretty much anything, raster or vector images (png or svg), but even animated. Styling can be customied, too.&lt;br /&gt;
For more info, I suggest to check out:&lt;br /&gt;
[[MapStructure#Porting the map dialog]]&lt;br /&gt;
&lt;br /&gt;
[[File:MapStructureDialog.png|250px]]&lt;br /&gt;
|2= {{cite web&lt;br /&gt;
  | url    = http://forum.flightgear.org/viewtopic.php?p=212558#p212558&lt;br /&gt;
  | title  = &amp;lt;nowiki&amp;gt;Re: Get objects to show up on Map/Radar&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  | author = &amp;lt;nowiki&amp;gt;Hooray&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  | date   = Jun 14th, 2014&lt;br /&gt;
  }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== On quoting ===&lt;br /&gt;
{{Main article|FlightGear wiki:Quoting Guidelines}}&lt;br /&gt;
&lt;br /&gt;
Using the Instant-Cquotes script is a good way to bootstrap and write some preliminary notes; however, while quotes might be useful to understand how undocumented subsystems and features work and are definitely better than nothing, they are not meant to replace proper, structured and well-written wiki articles.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
| url    = http://forum.flightgear.org/viewtopic.php?p=282800#p282800&lt;br /&gt;
| title  = &amp;lt;nowiki&amp;gt;Re: What is the QT launcher?&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| author = &amp;lt;nowiki&amp;gt;bugman&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| date   = Apr 17th, 2016&lt;br /&gt;
| added   = Apr 17th, 2016&lt;br /&gt;
| script_version = 0.25&lt;br /&gt;
}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One way to convert pages bootstrapped using quotes is to extract relevant information from them and keep citations only as references; in case important details are missing, they can be asked for on the [[Mailing lists|mailing lists]] (on the forum, the chance to get a complete answer might be lower).&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
| url    = http://sourceforge.net/p/flightgear/mailman/message/34954385/&lt;br /&gt;
| title  = &amp;lt;nowiki&amp;gt;Re: [Flightgear-devel] Wiki Quotes&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| author = &amp;lt;nowiki&amp;gt;James Turner&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| date   = Mar 21st, 2016&lt;br /&gt;
| added   = Mar 21st, 2016&lt;br /&gt;
| script_version = 0.25&lt;br /&gt;
}}&amp;lt;/ref&amp;gt; Another option might be moving the quotes to the Talk page for each entry, which would preserve the sources without clogging up the articles.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
| url    = http://sourceforge.net/p/flightgear/mailman/message/34948989/&lt;br /&gt;
| title  = &amp;lt;nowiki&amp;gt;Re: [Flightgear-devel] Wiki Quotes&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| author = &amp;lt;nowiki&amp;gt;Stuart Buchanan&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| date   = Mar 19th, 2016&lt;br /&gt;
| added   = Mar 19th, 2016&lt;br /&gt;
| script_version = 0.25&lt;br /&gt;
}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As a matter of fact, the whole paragraph above was assembled using this approach; to see for yourself, look up the references at the end of this page. For another example, see [[TerraSync#News]].&lt;br /&gt;
&lt;br /&gt;
== Development ==&lt;br /&gt;
{{Note|A Chrome/Chromium-specific extension that will not need Tampermonkey installed is under development.}}&lt;br /&gt;
&lt;br /&gt;
=== Resources ===&lt;br /&gt;
* https://www.mediawiki.org/wiki/API:Changing_wiki_content&lt;br /&gt;
* https://www.mediawiki.org/wiki/API:Edit&lt;br /&gt;
&lt;br /&gt;
=== Adding sources ===&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
{{WIP}}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
Adding a new source is pretty straightforward if you understand how xpath and regexes work - basically, you only need an archive (e.g. gmane), and then determine the xpath of each relevant field, as well as the regular expression to process the extracted fields (optional).&lt;br /&gt;
&lt;br /&gt;
The basic steps are these:&lt;br /&gt;
# open the user script in an editor&lt;br /&gt;
# navigate to the meta header of the user script&lt;br /&gt;
# add a new URL to the top of the script, e.g. by copying/adapting an existing line like this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// @match       https://sourceforge.net/p/flightgear/mailman/*&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once copied, add the new URL:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// @match       http://thread.gmane.org/gmane.games.flightgear.devel/*&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next, you need to navigate to the configuration hash to add a new website to it. &lt;br /&gt;
&lt;br /&gt;
Again, it makes sense to simply take an existing configuration hash and adapt it as needed (ignore/omit the tests vector for now by keeping it empty):&lt;br /&gt;
&lt;br /&gt;
{{Caution|the following example may meanwhile be outdated, so be sure to look at the actual code instead}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  'Sourceforge Mailing list': {&lt;br /&gt;
    enabled: true,&lt;br /&gt;
    type: 'archive',&lt;br /&gt;
    event: 'document.onmouseup', // when to invoke the event handler&lt;br /&gt;
    event_handler: instantCquote, // the event handler to be invoked&lt;br /&gt;
    url_reg: '^(http|https)://sourceforge.net/p/flightgear/mailman/.*/',&lt;br /&gt;
    content: {&lt;br /&gt;
      xpath: 'tbody/tr[2]/td/pre/text()',&lt;br /&gt;
      selection: getSelectedText,&lt;br /&gt;
      idStyle: /msg[0-9]{8}/,&lt;br /&gt;
      parentTag: [&lt;br /&gt;
        'tagName',&lt;br /&gt;
        'PRE'&lt;br /&gt;
      ],&lt;br /&gt;
    transform: [] // vector with transformation callbacks&lt;br /&gt;
    }, // content recipe&lt;br /&gt;
    // vector with tests to be executed for sanity checks (unit testing)&lt;br /&gt;
    tests: [&lt;br /&gt;
    ], // end of vector with self-tests&lt;br /&gt;
    // regex/xpath and transformations for extracting various required fields&lt;br /&gt;
    author: {&lt;br /&gt;
      xpath: 'tbody/tr[1]/td/div/small/text()',&lt;br /&gt;
      transform: [extract(/From: (.*) &amp;lt;.*@.*&amp;gt;/)]&lt;br /&gt;
    },&lt;br /&gt;
    title: {&lt;br /&gt;
      xpath: 'tbody/tr[1]/td/div/div[1]/b/a/text()'&lt;br /&gt;
      transform: []&lt;br /&gt;
    },&lt;br /&gt;
    date: {&lt;br /&gt;
      xpath: 'tbody/tr[1]/td/div/small/text()',&lt;br /&gt;
      transform: [extract(/- (.*-.*-.*) /)]&lt;br /&gt;
    },&lt;br /&gt;
    url: {&lt;br /&gt;
      xpath: 'tbody/tr[1]/td/div/div[1]/b/a/@href',&lt;br /&gt;
      transform: [prepend('https://sourceforge.net')]&lt;br /&gt;
    }&lt;br /&gt;
  }, // end of mailing list profile&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, we need to review/adapt the profile according to the new archive we'd like to see supported. &lt;br /&gt;
&lt;br /&gt;
for starters, that means:&lt;br /&gt;
* changing the name of the profile, e.g. to read gmane (instead of sourceforge)&lt;br /&gt;
* change the '''url_reg''' field to the gmane URL (this can be a regular expression)&lt;br /&gt;
&lt;br /&gt;
Next, it makes sense to use an [https://addons.mozilla.org/de/firefox/addon/xpath-checker/ XPath checker], so that we can look up the xpath expression for various HTML elements, and add those to the configuration hash above.&lt;br /&gt;
&lt;br /&gt;
For testing purposes, you will probably go to the setup dialog and enable the DEBUG mode, and use your browser's console to see what is going on.&lt;br /&gt;
&lt;br /&gt;
=== Getting involved ===&lt;br /&gt;
While having some experience with JavaScript/HTML and jQuery will definitely be useful, JavaScript is close enough to FlightGear scripting ([[Nasal]]), so that people can get involved pretty easily. &lt;br /&gt;
&lt;br /&gt;
Most maintenance work will typically involve reviewing/maintaining a few configuration hashes, that contain meta information for each supported archive (mailing list/forum).&lt;br /&gt;
&lt;br /&gt;
Usually, each hash contains a combination of xpath/regex expressions to look up the relevant information, as well as vector of optional transformations that are applied (in order) to convert contents to a different format (e.g. dates).&lt;br /&gt;
&lt;br /&gt;
In addition, there is growing library of utility functions, a handful wrappers for useful stuff, for example:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;Host.dbLog(message_string)&amp;lt;/code&amp;gt; - log a message to the console if the DEBUG flag is set&lt;br /&gt;
* &amp;lt;code&amp;gt;Host.download(url, callback, method='GET')&amp;lt;/code&amp;gt; - will download the URL and pass the downloaded content to the callback specified&lt;br /&gt;
* &amp;lt;code&amp;gt;Host.downloadPosting(url, callback)&amp;lt;/code&amp;gt; - will download the posting URL and pass the extracted and transformed author/content and date fields in a hash to the callback specified, the URL must be one supported in the CONFIG hash (i.e. forum/sourceforge for now)&lt;br /&gt;
* &amp;lt;code&amp;gt;Host.make_doc(string, type=&amp;quot;text/html&amp;quot;)&amp;lt;/code&amp;gt; - will turn a string/blob into a DOM that can be queried&lt;br /&gt;
* &amp;lt;code&amp;gt;Host.eval_xpath(document, xpath_expression, type=XPathResult.STRING_TYPE)&amp;lt;/code&amp;gt; - will apply the xpath expression to the document specified, returning the requested type (defaulted to string) &lt;br /&gt;
* &amp;lt;code&amp;gt;Host.set_persistent(key,value)&amp;lt;/code&amp;gt;  - stores a key/value pair&lt;br /&gt;
* &amp;lt;code&amp;gt;Host.get_persistent(key,default_value)&amp;lt;/code&amp;gt; - retrieves a values using the key specified, falling back to the default value&lt;br /&gt;
&lt;br /&gt;
=== Porting ===&lt;br /&gt;
[[File:Instant-cquote-firefox-addon-mode.png|thumb|Prototyping a dedicated instant-cquote mode for use as a firefox addon]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Porting the script to support other browsers/script engines is greatly appreciated. Typically, this should be pretty self-contained, because all main APIs are intended to be encapsulated in a so called &amp;quot;Environment&amp;quot; hash, where APIs that are specific to a particular browser/script engine should be provided with a wrapper. As of mid 2016, most APIs are now kept inside such an Environment hash (look at the GreaseMonkey hash for reference/details), so that it is now even possible to turn the script into a standalone FireFox addon without having to change much of the underlying code.&lt;br /&gt;
&lt;br /&gt;
=== Self checks (unit testing) ===&lt;br /&gt;
For regression testing purposes, there's a dedicated &amp;quot;self check&amp;quot; dialog that will be extended over time. For now it will download a few profile/website specific postings using a vector called &amp;quot;tests&amp;quot; and then log the posting's title, author and date to the console.&lt;br /&gt;
&lt;br /&gt;
The next step will be  actually showing that information in the dialog itself - there's a separate helper function to accomplish that, so that the corresponding div layer can be updated with the results.&lt;br /&gt;
&lt;br /&gt;
[[File:Sanity-check-cquotes-dialog.png|thumb|automatically executed sanity checks]]&lt;br /&gt;
&lt;br /&gt;
=== Debug mode ===&lt;br /&gt;
[[File:Instant-cquotes-debug-mode.png|thumb|Instant-Cquotes debug mode]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== AJAX (live page editing) ===&lt;br /&gt;
{{WIP}}&lt;br /&gt;
&lt;br /&gt;
* http://wiki.flightgear.org/api.php&lt;br /&gt;
* http://wiki.flightgear.org/api.php?action=parse&amp;amp;page=Frequently%20asked%20questions&amp;amp;prop=sections&lt;br /&gt;
&lt;br /&gt;
For now, the setup dialog will try to obtain a login token for the wiki and show a message if successful.&lt;br /&gt;
&lt;br /&gt;
In addition, the profile/website hash also contains a new wiki entry for the FlightGear wiki, whose '''event_handler''' callback will be invoked once the FG wiki is visited - the console/log will show a greeting, so that is where other code can be added - e.g. to help clean up/rewrite FGCquote-based articles automatically etc.&lt;br /&gt;
&lt;br /&gt;
There is a vector of &amp;quot;modes&amp;quot;, whose members are a hash containing trigger/handler fields, linked to two callbacks - the trigger callback can be used to check some condition, while the handler will be invoked if the trigger returns true.&lt;br /&gt;
&lt;br /&gt;
This can be used to support an arbitrary number of modes, whose triggers are evaluated during page load - all triggers that return true, will have their handlers invoked, which is how the following snippet works to rewrite/augment wiki edit handles:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;gt;&lt;br /&gt;
 'FlightGear.wiki': {&lt;br /&gt;
    type: 'wiki',&lt;br /&gt;
    enabled: false,&lt;br /&gt;
    event: 'document.onmouseup', // when to invoke the event handler&lt;br /&gt;
    event_handler: function () {&lt;br /&gt;
      console.log('FlightGear wiki handler active (waiting to be populated)');&lt;br /&gt;
      // this is where the logic for a wiki mode can be added over time (for now, it's a NOP)&lt;br /&gt;
    &lt;br /&gt;
    //for each supported mode, invoke the trigger and call the corresponding handler&lt;br /&gt;
    [].forEach.call(CONFIG['FlightGear.wiki'].modes, function(mode) {&lt;br /&gt;
      //dbLog(&amp;quot;Checking trigger:&amp;quot;+mode.name);&lt;br /&gt;
      if(mode.trigger) {&lt;br /&gt;
        mode.handler();&lt;br /&gt;
      }&lt;br /&gt;
    });&lt;br /&gt;
      &lt;br /&gt;
    }, // the event handler to be invoked&lt;br /&gt;
    url_reg: '^(http|https)://wiki.flightgear.org', // ignore for now: not currently used by the wiki mode&lt;br /&gt;
    &lt;br /&gt;
    modes: [&lt;br /&gt;
      { name:'process-editSections',&lt;br /&gt;
        trigger: function() {return true;}, // match URL regex - return true for always match&lt;br /&gt;
       &lt;br /&gt;
        // the code implementing the mode&lt;br /&gt;
        handler: function() {&lt;br /&gt;
                &lt;br /&gt;
    var editSections = document.getElementsByClassName('mw-editsection');&lt;br /&gt;
    console.log('FlightGear wiki article, number of edit sections: '+editSections.length);&lt;br /&gt;
   &lt;br /&gt;
    // for now, just rewrite edit sections and add a note to them&lt;br /&gt;
   &lt;br /&gt;
     [].forEach.call(editSections, function (sec) {&lt;br /&gt;
       sec.appendChild(&lt;br /&gt;
         document.createTextNode(' (instant-cquotes is lurking) ')&lt;br /&gt;
       );&lt;br /&gt;
     }); //forEach section&lt;br /&gt;
        } // handler&lt;br /&gt;
       &lt;br /&gt;
       &lt;br /&gt;
      } // process-editSections&lt;br /&gt;
      // TODO: add other wiki modes below &lt;br /&gt;
      &lt;br /&gt;
    ] // modes&lt;br /&gt;
    &lt;br /&gt;
  }, // end of wiki profile&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See [[User:Red Leader/Sandbox/AJAX test]]&lt;br /&gt;
&lt;br /&gt;
* https://www.mediawiki.org/wiki/API:Changing_wiki_content&lt;br /&gt;
* https://www.mediawiki.org/wiki/Extension:VisualEditor&lt;br /&gt;
* https://en.wikipedia.org/wiki/Wikipedia:Creating_a_bot&lt;br /&gt;
&lt;br /&gt;
=== Mobile edition ===&lt;br /&gt;
{{Note|As of 02/2016, Hooray is contemplating to make this available as an addon for Android phones.}}&lt;br /&gt;
&lt;br /&gt;
=== Issues/limitations ===&lt;br /&gt;
==== Bugs ====&lt;br /&gt;
* It's eating characters, apparently related to regex/xpath handling - e.g. words like &amp;quot;analyzing&amp;quot; are turned into &amp;quot;analying&amp;quot; [http://forum.flightgear.org/viewtopic.php?f=6&amp;amp;t=28378&amp;amp;p=270735&amp;amp;hilit=analyzing#p270735]&lt;br /&gt;
==== Non working URLs ====&lt;br /&gt;
* image matching/extraction: http://forum.flightgear.org/viewtopic.php?p=276221#p276221&lt;br /&gt;
* http://sourceforge.net/p/flightgear/mailman/message/34754961/&lt;br /&gt;
* http://forum.flightgear.org/viewtopic.php?f=18&amp;amp;t=27054&amp;amp;start=90#p273972 → selecting from “As promised, two sample installation sessions on Linux” to “That's it.” towards the end of the message causes Iceweasel (Firefox) 44.0.2 to display a dialog box reading “A script on this page may be busy, or it may have stopped responding. You can stop the script now, open the script in the debugger, or let the script continue.” The line below reads “Script: chrome://greasemonkey-modules/...quotes/instant_cquotes.user.js:544”. Choosing ''Continue'' doesn't help: the same message reappears a few seconds afterwards.&lt;br /&gt;
&lt;br /&gt;
=== Feature requests &amp;amp; ideas ===&lt;br /&gt;
* try to recognize list items [https://sourceforge.net/p/flightgear/mailman/message/35095319/] (heuristics: look for colon/asterisk, dashes and CR/LF)&lt;br /&gt;
* should add [[Template:News]] to the article dropdown for announcements [http://wiki.flightgear.org/index.php?title=Template:News&amp;amp;oldid=98266]&lt;br /&gt;
* add a mode that will download screenshots from forum postings and automatically upload/categorize them, see [[Birds]]&lt;br /&gt;
* split the article dropdown into sections, and also populate it with the user's watchlist [https://www.mediawiki.org/wiki/API:Watchlist] {{Progressbar|60}}&lt;br /&gt;
* mailing list templates, listed at [http://wiki.flightgear.org/Template_talk:Project_infrastructure#Related_mailing_list_templates]&lt;br /&gt;
* expose the cquote/ref markup via the UI so that it can be edited/customized and treated like a template {{Done}} (0.36+)&lt;br /&gt;
* identify common/repeated links and automatically create [[Template:Project infrastructure|link/infrastructure templates]] and use those (should be straightforward using the AJAX mode) [http://wiki.flightgear.org/index.php?title=Mailing_lists&amp;amp;curid=2038&amp;amp;diff=97876&amp;amp;oldid=85252]&lt;br /&gt;
* add a devel/maintainer mode where it will return the xpath for a selection [http://stackoverflow.com/questions/361130/get-selected-text-and-selected-nodes-on-a-page] [http://stackoverflow.com/questions/12485334/get-surrounding-dom-node-of-selection]&lt;br /&gt;
* move openlink,dblog helpers to Environment hash {{Done}}&lt;br /&gt;
* identify CLI arguments like --aircraft=c172p and wrap them in between code tags &amp;lt;code&amp;gt;--aircraft=c172p&amp;lt;/code&amp;gt; [https://sourceforge.net/p/flightgear/mailman/message/35063277/] (note that we can simply download [https://sourceforge.net/p/flightgear/fgdata/ci/next/tree/options.xml options.xml] via openlink() and use that, which is kinda of neat...) {{Progressbar|60}} (see downloadOptionsXML() in the code)&lt;br /&gt;
* introduce &amp;quot;layouts&amp;quot; (templates) for different purposes: newsletter, changelog, wiki article, [[The Manual]] (LaTex)  ? {{Progressbar|40}}&lt;br /&gt;
* use wikipedia template if possible [https://sourceforge.net/p/flightgear/mailman/message/35057670/]&lt;br /&gt;
* the new '''tests''' vector could also contain vectors for tests to test the extract/transform* utilities, see Environment.APITests {{Progressbar|50}}&lt;br /&gt;
* move environment specific APIs (browser, script host etc) into some kind of Environment hash to encapsulate things (Red Leader was working on a pure Chrome-only version at some point IIRC) {{Progressbar|80}}&lt;br /&gt;
* encode script settings in created markup, for future processing/updating of quotes&lt;br /&gt;
* look up &amp;lt;code&amp;gt;[x]&amp;lt;/code&amp;gt; references and replace with the corresponding link (titled) [https://sourceforge.net/p/flightgear/mailman/message/35055331/] [https://sourceforge.net/p/flightgear/mailman/message/35062598/]&lt;br /&gt;
** convert footnotes into Abbr templates [http://article.gmane.org/gmane.games.flightgear.devel/78971]&lt;br /&gt;
* support named refs for combining identical refs [http://wiki.flightgear.org/index.php?title=FlightGear_Qt_launcher&amp;amp;curid=13693&amp;amp;diff=97562&amp;amp;oldid=97551]&lt;br /&gt;
* adopt [[Template:Forumref]]&lt;br /&gt;
* implement a less obnoxious quoting mode, without quotes, where only the ref part would be added, e.g. see the example at [[Graphics Card Profiles]] (it's still 99% quotes, but much less annoying) {{Done}}&lt;br /&gt;
* attachment support: identify attachments and link to them: [https://sourceforge.net/p/flightgear/mailman/message/11683451/] [https://sourceforge.net/p/flightgear/mailman/message/23906620/] [https://sourceforge.net/p/flightgear/mailman/message/35059842/] [https://sourceforge.net/p/flightgear/mailman/message/35067087/]&lt;br /&gt;
* bulletin points: if there is a colon (:) followed by at least two dashes (-), split up everything after the colon to turn each dash into an asterisk (wiki markup for bulletin points), followed by a newline [http://sourceforge.net/p/flightgear/mailman/message/34760165/]   &lt;br /&gt;
* generic URL/template matching, e.g. for for sourceforge commit IDs&lt;br /&gt;
* make filters/conversions configurable via checkboxes (nowiki, wrap in alert/note boxes)&lt;br /&gt;
* make syntax highlighting configurable (language, mode) ?&lt;br /&gt;
* consider using something like the Roles template to turn contributor names into tooltips where contributor roles are shown (core dev, fgdata committer etc)&lt;br /&gt;
* introduce support for tag clouds to help categorize/classify related quotes&lt;br /&gt;
* consider making transformations optional/configurable using check boxes in the jQuery dialog&lt;br /&gt;
* add new input method, for quotes that need to be updated/converted (added script version specifically for this purpose), should also add extraction/processing date&lt;br /&gt;
* investigate why not all mailing list archives/postings are supported correctly: http://sourceforge.net/p/flightgear/mailman/message/8090479/ (problem traced to &amp;lt;code&amp;gt;getPostID()&amp;lt;/code&amp;gt;)&lt;br /&gt;
* explore having a ref-only mode without using cquotes, i.e. just copy/paste quotes with proper ref tags and a references section, to rewrite the whole thing (possibly with templates for different purposes, e.g. newsletter/changelog) {{Done}}&lt;br /&gt;
* should use Template:Forumref (category:link templates)&lt;br /&gt;
* should be updated to use the new repo/flightgear file templates created by Johan &amp;amp; RedLeader {{Not done}}&lt;br /&gt;
* resolve links to forum threads to look up the title for the topic/posting, so that the posting's title can be used for those links, instead of just the URL - we can probably do that by making an AJAX call to open URLs asynchronously and extract the title for the thread/posting to come up with something like &amp;lt;code&amp;gt;[http://forum.flightgear.org/viewtopic.php?f=4&amp;amp;t=24421 A call to developers-Lockheed -L188 Electra]&amp;lt;/code&amp;gt; ([http://forum.flightgear.org/viewtopic.php?f=4&amp;amp;t=26562&amp;amp;p=247325&amp;amp;hilit=links#p247347]) {{Progressbar|50}}&lt;br /&gt;
* convert quoted bug tracker URLs to use the issue template on the wiki {{not done}}&lt;br /&gt;
* do regex/xpath validation, and display any errors (e.g. template/theme changes on the forum would currently break the script) {{Progressbar|60}}&lt;br /&gt;
* increased focus on supporting different output formats, maybe using a simple [http://www.jquery-steps.com/ jQuery based wizard] (wiki, forum, newsletter, changelog) {{Not done}}&lt;br /&gt;
* token matching for keywords/acronyms to link to the corresponding wiki articles (e.g. Nasal, Canvas, FG_ROOT, FG_HOME etc) {{Not done}}&lt;br /&gt;
* Add support for [http://sourceforge.net/p/flightgear/codetickets/ tickets], merge requests comments and [http://www.fguk.eu/index.php/forum/index FGUK forum]. (also see [[FlightGear wiki talk:Instant-Cquotes#more sources]])&lt;br /&gt;
* GET-encoded SID arguments should be stripped from forum URLs. {{Not done}}&lt;br /&gt;
* Links to repositories should be converted to use wiki templates. {{Not done}}&lt;br /&gt;
* The {{Abbr|regexes|regular expressions}} used may fail if the HTML DOM of the source changes (e.g., phpBB/theme update)&lt;br /&gt;
** Show a warning when that's the case. {{Progressbar|70}} (see the self-check dialog)&lt;br /&gt;
** Try multiple regexes in order. {{Progressbar|30}} (see the self-check dialog)&lt;br /&gt;
* Use the script to update previously created Cquotes automatically&lt;br /&gt;
** Instead of using the &amp;lt;code&amp;gt;getSelection()&amp;lt;/code&amp;gt; helper, we could register a match for &amp;lt;tt&amp;gt;wiki.flightgear.org&amp;lt;/tt&amp;gt; with &amp;lt;code&amp;gt;action=edit&amp;lt;/code&amp;gt; set, so that we can directly process all text of an edited page, using AJAX calls to open the URL in the background. {{Progressbar|40}} (see the self-check dialog, available via the greasemonkey menu)&lt;br /&gt;
** See [https://www.mediawiki.org/wiki/API:Edit#Editing_via_Ajax MW:API:Edit § Editing via Ajax]&lt;br /&gt;
&lt;br /&gt;
=== Changelog ===&lt;br /&gt;
{{Note|Contributors are invited to document their changes here, please also add your wiki handle so that others can more easily get in touch.}}&lt;br /&gt;
&lt;br /&gt;
* first stab at implementing unit tests by adding a vector with URLS to be downloaded and fields to be matched (WIP), shown in a jQuery dialog&lt;br /&gt;
* support for persistent settings and a jQuery setup dialog with persistence&lt;br /&gt;
* hosting is moved, to allow auto-updates [http://www.greasespot.net/2012/02/automatic-script-updates-come-to.html] [https://wiki.greasespot.net/Metadata_Block#.40updateURL] [http://stackoverflow.com/questions/15095055/why-isnt-my-greasemonkey-script-updating]&lt;br /&gt;
* changed to ref-only quotes for now, not using the FGCquote template anymore, due to its obnoxious appearance on quote-heavy pages (should probably become a runtime option instead)&lt;br /&gt;
* updated to use https for forum postings&lt;br /&gt;
* add version info to each created quote, i.e. for future updates&lt;br /&gt;
* add helper for opening websites asynchronously using AJAX (also via GM helper API)&lt;br /&gt;
* display version number in output dialog&lt;br /&gt;
* begin using the GreaseMonkey API for setting clipboard content&lt;br /&gt;
&lt;br /&gt;
== The script ==&lt;br /&gt;
&amp;lt;gallery mode=packed widths=230px heights=230px&amp;gt;&lt;br /&gt;
Instant-cquotes-revamped.png|Instant cquotes: Revamped user interface exposes script internals to make the script better configurable at runtime&lt;br /&gt;
Instant-cquotes-template-editor.png|Instant cquotes now features a simple built-in template editor with support for variable substitution, so that wiki templates can be more easily customized&lt;br /&gt;
Instant-cquotes-with-wikimedia-API-integration.png|Screenshot showing instant-cquotes with wikimedia API integration to fetch articles/sections and populate dropdown menus accordingly&lt;br /&gt;
Instant-cquotes-on-steroids-with-watchlist-support.png|Screenshot showing the JQuery-mode of the instant cquotes script with built-in support for fetching a user's wiki/watchlist to edit/update articles in a semi-automated fashion&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
{{PD-author|FlightGear contributors}}&lt;br /&gt;
&lt;br /&gt;
{{Note|Anybody interested in contributing to the code is invited to directly edit this wiki article. From 05/2016, the script is hosted on GreasyFork to allow automatic updates. If you'd like to see your changes applied, please bump the version number and [[User:Elgaton|Elgaton]] will upload it in the state it was when the version number was bumped. ''Make sure to perform thorough testing'' before the bump to prevent unexpected breakage; it is generally a good idea to validate your changes using an online syntax checker, e.g.:&lt;br /&gt;
* http://jshint.com/ &lt;br /&gt;
* http://esprima.org/demo/validate.html&lt;br /&gt;
* http://codebeautify.org/jsvalidate&lt;br /&gt;
&amp;lt;p/&amp;gt;Thank you!}}&lt;br /&gt;
&lt;br /&gt;
Changes that should be mentioned in the changelog, should be added below (and moved to the [[#Changelog]] section subsequently:&lt;br /&gt;
&lt;br /&gt;
* preparations for adding support to download fgdata related files like options.xml to automatically regex known CLI commands&lt;br /&gt;
* preparatory work for adding a speech-rewrite engine to assist in converting 1st person speech to 3rd person&lt;br /&gt;
* framework for encapsulating userscript specifics in an environment hash to provide better updating/porting support&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;// ==UserScript==&lt;br /&gt;
// @name        Instant-Cquotes&lt;br /&gt;
// @name:it     Instant-Cquotes&lt;br /&gt;
// @license     public domain&lt;br /&gt;
// @version     0.39&lt;br /&gt;
// @date        2016-05-05&lt;br /&gt;
// @description Automatically converts selected FlightGear mailing list and forum quotes into post-processed MediaWiki markup (i.e. cquotes).&lt;br /&gt;
// @description:it Converte automaticamente citazioni dalla mailing list e dal forum di FlightGear in marcatori MediaWiki (cquote).&lt;br /&gt;
// @author      Hooray, bigstones, Philosopher, Red Leader &amp;amp; Elgaton (2013-2016)&lt;br /&gt;
// @supportURL  http://wiki.flightgear.org/FlightGear_wiki:Instant-Cquotes&lt;br /&gt;
// @icon        http://wiki.flightgear.org/images/2/25/Quotes-logo-200x200.png&lt;br /&gt;
// @match       https://sourceforge.net/p/flightgear/mailman/*&lt;br /&gt;
// @match       http://sourceforge.net/p/flightgear/mailman/*&lt;br /&gt;
// @match       https://forum.flightgear.org/*&lt;br /&gt;
// @match       http://wiki.flightgear.org/*&lt;br /&gt;
// @namespace   http://wiki.flightgear.org/FlightGear_wiki:Instant-Cquotes&lt;br /&gt;
// @run-at      document-start&lt;br /&gt;
// @require     https://code.jquery.com/jquery-1.10.2.js&lt;br /&gt;
// @require     https://code.jquery.com/ui/1.11.4/jquery-ui.js&lt;br /&gt;
// @require     https://cdn.jsdelivr.net/genetic.js/0.1.14/dist.js&lt;br /&gt;
// @require     https://cdn.jsdelivr.net/synaptic/1.0.4/synaptic.min.js&lt;br /&gt;
// @resource    jQUI_CSS https://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css&lt;br /&gt;
// @resource    myLogo http://wiki.flightgear.org/images/2/25/Quotes-logo-200x200.png&lt;br /&gt;
// @grant       GM_registerMenuCommand&lt;br /&gt;
// @grant       GM_setValue&lt;br /&gt;
// @grant       GM_getValue&lt;br /&gt;
// @grant       GM_addStyle&lt;br /&gt;
// @grant       GM_getResourceText&lt;br /&gt;
// @grant       GM_getResourceURL&lt;br /&gt;
// @grant       GM_setClipboard&lt;br /&gt;
// @grant       GM_xmlhttpRequest&lt;br /&gt;
// @noframes&lt;br /&gt;
// ==/UserScript==&lt;br /&gt;
//&lt;br /&gt;
// This work has been released into the public domain by their authors. This&lt;br /&gt;
// applies worldwide.&lt;br /&gt;
// In some countries this may not be legally possible; if so:&lt;br /&gt;
// The authors grant anyone the right to use this work for any purpose, without&lt;br /&gt;
// any conditions, unless such conditions are required by law.&lt;br /&gt;
//&lt;br /&gt;
// This script has a number of dependencies that are implicitly satisfied when run as a user script &lt;br /&gt;
// via GreaseMonkey/TamperMonkey; however, these need to be explicitly handled when using a different mode (e.g. firefox/android):&lt;br /&gt;
// &lt;br /&gt;
// - jQuery - user interface (REQUIRED)&lt;br /&gt;
// - genetic-js - genetic programming (OPTIONAL/EXPERIMENTAL)&lt;br /&gt;
// - synaptic - neural networks (OPTIONAL/EXPERIMENTAL)&lt;br /&gt;
// &lt;br /&gt;
// &lt;br /&gt;
&lt;br /&gt;
/* Here are some TODOs&lt;br /&gt;
 * - support RSS feeds http://dir.gmane.org/gmane.games.flightgear.devel/&lt;br /&gt;
 * - move event handling/processing to the CONFIG hash&lt;br /&gt;
 * - use try/catch more widely&lt;br /&gt;
 * - wrap function calls in try/call for better debugging/diagnostics&lt;br /&gt;
 * - add helpers for [].forEach.call, map, apply and call&lt;br /&gt;
 * - replace for/in, for/of, let statements for better compatibility (dont require ES6)&lt;br /&gt;
 * - for the same reason, replace use of functions with default params &lt;br /&gt;
 * - isolate UI (e.g. JQUERY) code in UserInterface hash&lt;br /&gt;
 * - expose regex/transformations via the UI&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
'use strict';&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// TODO: move to GreaseMonkey/UI host&lt;br /&gt;
// prevent conflicts with jQuery used on webpages: https://wiki.greasespot.net/Third-Party_Libraries#jQuery&lt;br /&gt;
// http://stackoverflow.com/a/5014220&lt;br /&gt;
this.$ = this.jQuery = jQuery.noConflict(true);&lt;br /&gt;
&lt;br /&gt;
// this hash is just intended to help isolate UI specifics&lt;br /&gt;
// so that we don't need to maintain/port tons of code &lt;br /&gt;
&lt;br /&gt;
var UserInterface = {&lt;br /&gt;
  get: function() {&lt;br /&gt;
    return UserInterface.DEFAULT;&lt;br /&gt;
  },&lt;br /&gt;
  &lt;br /&gt;
 CONSOLE: {&lt;br /&gt;
   &lt;br /&gt;
 }, // CONSOLE (shell, mainly useful for testing)&lt;br /&gt;
  &lt;br /&gt;
 DEFAULT: {&lt;br /&gt;
  alert: function(msg) {return window.alert(msg);     },&lt;br /&gt;
  prompt: function(msg) {return window.prompt(msg);  }, &lt;br /&gt;
  confirm: function(msg) {return window.confirm(msg); },&lt;br /&gt;
  dialog: null,&lt;br /&gt;
  selection: null,&lt;br /&gt;
  populateWatchlist: function() {&lt;br /&gt;
    &lt;br /&gt;
  },&lt;br /&gt;
  populateEditSections: function() {&lt;br /&gt;
    &lt;br /&gt;
  }&lt;br /&gt;
 &lt;br /&gt;
 }, // default UI mapping (Browser/User script)&lt;br /&gt;
  &lt;br /&gt;
  JQUERY: {&lt;br /&gt;
    &lt;br /&gt;
  } // JQUERY &lt;br /&gt;
  &lt;br /&gt;
}; // UserInterface&lt;br /&gt;
&lt;br /&gt;
var UI = UserInterface.get(); // DEFAULT for now&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// This hash is intended to help encapsulate platform specifics (browser/scripting host)&lt;br /&gt;
// Ideally, all APIs that are platform specific should be kept here&lt;br /&gt;
// This should make it much easier to update/port and maintain the script in the future&lt;br /&gt;
var Environment = {&lt;br /&gt;
  getHost: function(xpi=false) {&lt;br /&gt;
 &lt;br /&gt;
     if(xpi) {&lt;br /&gt;
       Environment.scriptEngine = 'firefox addon';&lt;br /&gt;
       console.log('in firefox xpi/addon mode');&lt;br /&gt;
       return Environment.FirefoxAddon; // HACK for testing the xpi mode (firefox addon)&lt;br /&gt;
     }&lt;br /&gt;
    &lt;br /&gt;
    // This will determine the script engine in use: http://stackoverflow.com/questions/27487828/how-to-detect-if-a-userscript-is-installed-from-the-chrome-store&lt;br /&gt;
    if (typeof(GM_info) === 'undefined') {&lt;br /&gt;
    Environment.scriptEngine = &amp;quot;plain Chrome (Or Opera, or scriptish, or Safari, or rarer)&amp;quot;;&lt;br /&gt;
    // See http://stackoverflow.com/a/2401861/331508 for optional browser sniffing code.&lt;br /&gt;
   }&lt;br /&gt;
   else {&lt;br /&gt;
    Environment.scriptEngine = GM_info.scriptHandler  ||  &amp;quot;Greasemonkey&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
   console.log ('Instant cquotes is running on ' + Environment.scriptEngine + '.');&lt;br /&gt;
    &lt;br /&gt;
   //console.log(&amp;quot;not in firefox addon mode...&amp;quot;);&lt;br /&gt;
    // See also: https://wiki.greasespot.net/Cross-browser_userscripting&lt;br /&gt;
    return Environment.GreaseMonkey; // return the only/default host (for now)&lt;br /&gt;
  },&lt;br /&gt;
  &lt;br /&gt;
  validate: function(host) {&lt;br /&gt;
    if (host.get_persistent('startup.disable_validation',false)) return;&lt;br /&gt;
    &lt;br /&gt;
    if(Environment.scriptEngine !== &amp;quot;Greasemonkey&amp;quot;) &lt;br /&gt;
      console.log(&amp;quot;NOTE: This script has not been tested with script engines other than GreaseMonkey recently!&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    var dependencies = [&lt;br /&gt;
      {name:'jQuery', test: function() {} },&lt;br /&gt;
      {name:'genetic.js', test: function() {} },&lt;br /&gt;
      {name:'synaptic', test: function() {} },&lt;br /&gt;
    ];&lt;br /&gt;
    &lt;br /&gt;
    [].forEach.call(dependencies, function(dep) {&lt;br /&gt;
      console.log(&amp;quot;Checking for dependency:&amp;quot;+dep.name);&lt;br /&gt;
      var status=false;&lt;br /&gt;
      try {&lt;br /&gt;
      dep.test.call(undefined);&lt;br /&gt;
      status=true;&lt;br /&gt;
      }&lt;br /&gt;
      catch(e) {&lt;br /&gt;
      status=false;       &lt;br /&gt;
      }&lt;br /&gt;
      finally {&lt;br /&gt;
        var success = (status)?'==&amp;gt; success':'==&amp;gt; failed';&lt;br /&gt;
        console.log(success);&lt;br /&gt;
        return status;&lt;br /&gt;
      }&lt;br /&gt;
    });&lt;br /&gt;
  }, // validate&lt;br /&gt;
  &lt;br /&gt;
  // this contains unit tests for checking crucial APIs that must work for the script to work correctly&lt;br /&gt;
  // for the time being, most of these are stubs waiting to be filled in&lt;br /&gt;
  // for a working example, refer to the JSON test at the end&lt;br /&gt;
  // TODO: add jQuery tests&lt;br /&gt;
  APITests: [&lt;br /&gt;
     {name:'download', test: function(recipient) {recipient(true);}  },&lt;br /&gt;
     {name:'make_doc', test: function(recipient) { recipient(true);}   },&lt;br /&gt;
     {name:'eval_xpath', test: function(recipient) { recipient(true);} },&lt;br /&gt;
     {name:'JSON de/serialization', test: function(recipient) {&lt;br /&gt;
       //console.log(&amp;quot;running json test&amp;quot;);&lt;br /&gt;
       var identifier = 'unit_tests.json_serialization';&lt;br /&gt;
       var hash1 = {x:1,y:2,z:3};&lt;br /&gt;
       Host.set_persistent(identifier, hash1, true);&lt;br /&gt;
       var hash2 = Host.get_persistent(identifier,null,true);&lt;br /&gt;
       &lt;br /&gt;
       recipient(JSON.stringify(hash1) === JSON.stringify(hash2));&lt;br /&gt;
     } // callback &lt;br /&gt;
     },&lt;br /&gt;
    &lt;br /&gt;
    // downloads a posting and tries to transform it to 3rd person speech ...&lt;br /&gt;
    // TODO: add another test to check forum postings&lt;br /&gt;
    {name:'text/speech transformation', test: function(recipient) {&lt;br /&gt;
    &lt;br /&gt;
    // the posting we want to download&lt;br /&gt;
    var url='https://sourceforge.net/p/flightgear/mailman/message/35066974/';&lt;br /&gt;
    Host.downloadPosting(url, function (result) {&lt;br /&gt;
      &lt;br /&gt;
    // only process the first sentence by using comma/dot as delimiter&lt;br /&gt;
    var firstSentence = result.content.substring(result.content.indexOf(',')+1, result.content.indexOf('.'));&lt;br /&gt;
      &lt;br /&gt;
    var transformed = transformSpeech(firstSentence, result.author, null, speechTransformations );&lt;br /&gt;
    console.log(&amp;quot;3rd person speech transformation:\n&amp;quot;+transformed);   &lt;br /&gt;
    &lt;br /&gt;
    recipient(true);&lt;br /&gt;
    }); // downloadPosting() &lt;br /&gt;
        &lt;br /&gt;
  }// test()&lt;br /&gt;
    }, // end of speech transform test&lt;br /&gt;
    {&lt;br /&gt;
      name:&amp;quot;download $FG_ROOT/options.xml&amp;quot;, test: function(recipient) {&lt;br /&gt;
        downloadOptionsXML();&lt;br /&gt;
        recipient(true);&lt;br /&gt;
      } // test&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
  ], // end of APITests&lt;br /&gt;
  &lt;br /&gt;
  runAPITests: function(host, recipient) {&lt;br /&gt;
    console.log(&amp;quot;Running API tests&amp;quot;);&lt;br /&gt;
    for(let test of Environment.APITests ) {&lt;br /&gt;
      //var test = Environment.APITests[t];&lt;br /&gt;
      // invoke the callback passed, with the hash containing the test specs, so that the console/log or a div can be updated showing the test results&lt;br /&gt;
      &lt;br /&gt;
      recipient.call(undefined, test);&lt;br /&gt;
      &lt;br /&gt;
    } // foreach test&lt;br /&gt;
  }, // runAPITests&lt;br /&gt;
  &lt;br /&gt;
  /*&lt;br /&gt;
   * ===================================================================================================================================================&lt;br /&gt;
   *&lt;br /&gt;
   */&lt;br /&gt;
  &lt;br /&gt;
  // NOTE: This mode/environment is WIP and highly experimental ...&lt;br /&gt;
  // To see this working, you need to package up the whole file as a firefox xpi using &amp;quot;jpm xpi&amp;quot;&lt;br /&gt;
  // and then start the whole thing via &amp;quot;jpm run&amp;quot;, to do that, you also need a matching package.json (i.e. via jpm init) &lt;br /&gt;
  // ALSO: you will have to explicitly install any dependencies using jpm&lt;br /&gt;
  FirefoxAddon: {&lt;br /&gt;
  	init: function() {&lt;br /&gt;
		console.log(&amp;quot;Firefox addon mode ...&amp;quot;);&lt;br /&gt;
  	},&lt;br /&gt;
	getScriptVersion: function() {&lt;br /&gt;
		return '0.36'; // FIXME&lt;br /&gt;
	},&lt;br /&gt;
	dbLog: function(msg) {&lt;br /&gt;
		console.log(msg);&lt;br /&gt;
	},&lt;br /&gt;
	addEventListener: function(ev, cb) {&lt;br /&gt;
&lt;br /&gt;
	require(&amp;quot;sdk/tabs&amp;quot;).on(&amp;quot;ready&amp;quot;, logURL);&lt;br /&gt;
 	function logURL(tab) {&lt;br /&gt;
  		console.log(&amp;quot;URL loaded:&amp;quot; + tab.url);&lt;br /&gt;
	}	&lt;br /&gt;
	},&lt;br /&gt;
    &lt;br /&gt;
	registerConfigurationOption: function(name, callback, hook) {&lt;br /&gt;
	// https://developer.mozilla.org/en-US/Add-ons/SDK/Tutorials/Add_a_Context_Menu_Item&lt;br /&gt;
		console.log(&amp;quot;config menu support n/a in firefox mode&amp;quot;);&lt;br /&gt;
 // https://developer.mozilla.org/en-US/Add-ons/SDK/Tutorials/Using_third-party_modules_%28jpm%29  &lt;br /&gt;
 var menuitems = require(&amp;quot;menuitem&amp;quot;);&lt;br /&gt;
 var menuitem = menuitems.Menuitem({&lt;br /&gt;
  id: &amp;quot;clickme&amp;quot;,&lt;br /&gt;
  menuid: &amp;quot;menu_ToolsPopup&amp;quot;,&lt;br /&gt;
  label: name,&lt;br /&gt;
  onCommand: function() {&lt;br /&gt;
    console.log(&amp;quot;menuitem clicked:&amp;quot;);&lt;br /&gt;
    callback();&lt;br /&gt;
  },&lt;br /&gt;
  insertbefore: &amp;quot;menu_pageInfo&amp;quot;&lt;br /&gt;
});&lt;br /&gt;
	},&lt;br /&gt;
    &lt;br /&gt;
	registerTrigger: function() {&lt;br /&gt;
		// https://developer.mozilla.org/en-US/Add-ons/SDK/Tutorials/Add_a_Context_Menu_Item&lt;br /&gt;
		// https://developer.mozilla.org/en-US/Add-ons/SDK/High-Level_APIs/context-menu#Item%28options%29&lt;br /&gt;
		var contextMenu = require(&amp;quot;sdk/context-menu&amp;quot;);&lt;br /&gt;
		var menuItem = contextMenu.Item({&lt;br /&gt;
  		label: &amp;quot;Instant Cquote&amp;quot;,&lt;br /&gt;
  		context: contextMenu.SelectionContext(),&lt;br /&gt;
      // https://developer.mozilla.org/en/Add-ons/SDK/Guides/Two_Types_of_Scripts&lt;br /&gt;
      // https://developer.mozilla.org/en-US/Add-ons/SDK/Guides/Content_Scripts&lt;br /&gt;
  		contentScript: 'self.on(&amp;quot;click&amp;quot;, function () {' +&lt;br /&gt;
                 '  var text = window.getSelection().toString();' +&lt;br /&gt;
                 '  self.postMessage(text);' +&lt;br /&gt;
                 '});',&lt;br /&gt;
  		onMessage: function (selectionText) {&lt;br /&gt;
    		console.log(selectionText);&lt;br /&gt;
        instantCquote(selectionText);&lt;br /&gt;
  		}&lt;br /&gt;
	});&lt;br /&gt;
  &lt;br /&gt;
    // for selection handling stuff, see: https://developer.mozilla.org/en-US/Add-ons/SDK/High-Level_APIs/selection&lt;br /&gt;
    &lt;br /&gt;
    function myListener() {&lt;br /&gt;
  console.log(&amp;quot;A selection has been made.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
var selection = require(&amp;quot;sdk/selection&amp;quot;);&lt;br /&gt;
selection.on('select', myListener);&lt;br /&gt;
    &lt;br /&gt;
	}, //registerTrigger&lt;br /&gt;
    &lt;br /&gt;
	get_persistent: function(key, default_value) {&lt;br /&gt;
    // https://developer.mozilla.org/en-US/Add-ons/SDK/High-Level_APIs/simple-storage&lt;br /&gt;
    var ss = require(&amp;quot;sdk/simple-storage&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    console.log(&amp;quot;firefox mode does not yet have persistence support&amp;quot;);&lt;br /&gt;
    return default_value;},&lt;br /&gt;
	set_persistent: function(key, value) {&lt;br /&gt;
		console.log(&amp;quot;firefox persistence stubs not yet filled in !&amp;quot;);&lt;br /&gt;
	},&lt;br /&gt;
    &lt;br /&gt;
  &lt;br /&gt;
	set_clipboard: function(content) {&lt;br /&gt;
	// https://developer.mozilla.org/en-US/Add-ons/SDK/High-Level_APIs/clipboard&lt;br /&gt;
    &lt;br /&gt;
	//console.log('clipboard stub not yet filled in ...');&lt;br /&gt;
    var clipboard = require(&amp;quot;sdk/clipboard&amp;quot;);&lt;br /&gt;
    clipboard.set(content);&lt;br /&gt;
	} //set_cliipboard&lt;br /&gt;
    &lt;br /&gt;
  }, // end of FireFox addon config&lt;br /&gt;
  &lt;br /&gt;
  // placeholder for now ...&lt;br /&gt;
  Android: {&lt;br /&gt;
    // NOP&lt;br /&gt;
  }, // Android&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  ///////////////////////////////////////&lt;br /&gt;
  // supported  script engines:&lt;br /&gt;
  ///////////////////////////////////////&lt;br /&gt;
  &lt;br /&gt;
  GreaseMonkey: {&lt;br /&gt;
  // TODO: move environment specific initialization code here  &lt;br /&gt;
  init: function() {&lt;br /&gt;
  // Check if Greasemonkey/Tampermonkey is available&lt;br /&gt;
  try {&lt;br /&gt;
  // TODO: add version check for clipboard API and check for TamperMonkey/Scriptish equivalents ?&lt;br /&gt;
  GM_addStyle(GM_getResourceText('jQUI_CSS'));&lt;br /&gt;
  } // try&lt;br /&gt;
  catch (error) {&lt;br /&gt;
  console.log('Could not add style or determine script version');&lt;br /&gt;
  } // catch&lt;br /&gt;
&lt;br /&gt;
  var commands = [&lt;br /&gt;
  {name:'Setup quotes',callback:setupDialog, hook:'S' },&lt;br /&gt;
  {name:'Check quotes',callback:selfCheckDialog, hook:'C' }&lt;br /&gt;
  ];&lt;br /&gt;
      &lt;br /&gt;
  for (let c of commands ) {&lt;br /&gt;
   this.registerConfigurationOption(c.name, c.callback, c.hook);&lt;br /&gt;
  }  &lt;br /&gt;
     &lt;br /&gt;
  }, // init()&lt;br /&gt;
    &lt;br /&gt;
  getScriptVersion: function() {&lt;br /&gt;
  return GM_info.script.version;  &lt;br /&gt;
  },&lt;br /&gt;
    &lt;br /&gt;
  dbLog: function (message) {&lt;br /&gt;
  if (Boolean(DEBUG)) {&lt;br /&gt;
    console.log('Instant cquotes:' + message);&lt;br /&gt;
  }&lt;br /&gt;
  }, // dbLog()&lt;br /&gt;
    &lt;br /&gt;
  registerConfigurationOption: function(name,callback,hook) {&lt;br /&gt;
  // https://wiki.greasespot.net/GM_registerMenuCommand&lt;br /&gt;
  // https://wiki.greasespot.net/Greasemonkey_Manual:Monkey_Menu#The_Menu&lt;br /&gt;
    GM_registerMenuCommand(name, callback, hook);&lt;br /&gt;
  }, //registerMenuCommand()&lt;br /&gt;
    &lt;br /&gt;
  registerTrigger: function() {&lt;br /&gt;
    &lt;br /&gt;
    // TODO: we can use the following callback non-interactively, i.e. to trigger background tasks&lt;br /&gt;
// http://javascript.info/tutorial/onload-ondomcontentloaded&lt;br /&gt;
document.addEventListener(&amp;quot;DOMContentLoaded&amp;quot;, function(event) {&lt;br /&gt;
    console.log(&amp;quot;Instant Cquotes: DOM fully loaded and parsed&amp;quot;);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
window.addEventListener('load', init); // page fully loaded&lt;br /&gt;
Host.dbLog('Instant Cquotes: page load handler registered');&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    // Initialize (matching page loaded)&lt;br /&gt;
function init() {&lt;br /&gt;
  console.log('Instant Cquotes: page load handler invoked');&lt;br /&gt;
  var profile = getProfile();&lt;br /&gt;
  &lt;br /&gt;
  Host.dbLog(&amp;quot;Profile type is:&amp;quot;+profile.type);&lt;br /&gt;
  &lt;br /&gt;
  // Dispatch to correct event handler (depending on website/URL)&lt;br /&gt;
  // TODO: this stuff could/should be moved into the config hash itself&lt;br /&gt;
  &lt;br /&gt;
  if (profile.type=='wiki') {&lt;br /&gt;
    profile.event_handler(); // just for testing&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
   &lt;br /&gt;
    Host.dbLog('using default mode');&lt;br /&gt;
    document.onmouseup = instantCquote;&lt;br /&gt;
    // HACK: preparations for moving the the event/handler logic also into the profile hash, so that the wiki (edit mode) can be handled equally&lt;br /&gt;
    //eval(profile.event+&amp;quot;=instantCquote&amp;quot;);&lt;br /&gt;
     &lt;br /&gt;
} // init()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
  }, // registerTrigger&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
   download: function (url, callback, method='GET') {&lt;br /&gt;
  // http://wiki.greasespot.net/GM_xmlhttpRequest&lt;br /&gt;
     try {&lt;br /&gt;
  GM_xmlhttpRequest({&lt;br /&gt;
    method: method,&lt;br /&gt;
    url: url,&lt;br /&gt;
    onload: callback&lt;br /&gt;
  });&lt;br /&gt;
     }catch(e) {&lt;br /&gt;
       console.log(&amp;quot;download did not work&amp;quot;);&lt;br /&gt;
     }&lt;br /&gt;
  }, // download()&lt;br /&gt;
    &lt;br /&gt;
    // is only intended to work with archives supported by the  hash&lt;br /&gt;
    downloadPosting: function (url, EventHandler) {&lt;br /&gt;
      &lt;br /&gt;
    Host.download(url, function (response) {&lt;br /&gt;
    var profile = getProfile(url);&lt;br /&gt;
    var blob = response.responseText;&lt;br /&gt;
    var doc = Host.make_doc(blob,'text/html'); &lt;br /&gt;
    var result = {}; // hash to be returned&lt;br /&gt;
    &lt;br /&gt;
    [].forEach.call(['author','date','title','content'], function(field) {&lt;br /&gt;
      var xpath_query = '//' + profile[field].xpath;&lt;br /&gt;
      try {&lt;br /&gt;
       var value = Host.eval_xpath(doc, xpath_query).stringValue; &lt;br /&gt;
       //UI.alert(&amp;quot;extracted field value:&amp;quot;+value);&lt;br /&gt;
        &lt;br /&gt;
        // now apply all transformations, if any&lt;br /&gt;
       value = applyTransformations(value, profile[field].transform );&lt;br /&gt;
        &lt;br /&gt;
       result[field]=value; // store the extracted/transormed value in the hash that we pass on&lt;br /&gt;
      } // try&lt;br /&gt;
      catch(e) {&lt;br /&gt;
        UI.alert(&amp;quot;downloadPosting failed:\n&amp;quot;+ e.message);&lt;br /&gt;
      } // catch&lt;br /&gt;
    }); // forEach field&lt;br /&gt;
    &lt;br /&gt;
    EventHandler(result); // pass the result to the handler&lt;br /&gt;
    }); // call to Host.download() &lt;br /&gt;
      &lt;br /&gt;
    }, // downloadPosting()&lt;br /&gt;
    &lt;br /&gt;
    // TODO: add makeAJAXCall, and makeWikiCall here&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
    // turn a string/text blob into a DOM tree that can be queried (e.g. for xpath expressions)&lt;br /&gt;
    // FIXME: this is browser specific not GM specific ...&lt;br /&gt;
    make_doc: function(text, type='text/html') {&lt;br /&gt;
      // to support other browsers, see: https://developer.mozilla.org/en/docs/Web/API/DOMParser&lt;br /&gt;
      return new DOMParser().parseFromString(text,type);&lt;br /&gt;
    }, // make DOM document&lt;br /&gt;
    &lt;br /&gt;
    // xpath handling may be handled separately depending on browser/platform, so better encapsulate this&lt;br /&gt;
    // FIXME: this is browser specific not GM specific ...&lt;br /&gt;
    eval_xpath: function(doc, xpath, type=XPathResult.STRING_TYPE) {&lt;br /&gt;
      return doc.evaluate(xpath, doc, null, type, null);&lt;br /&gt;
    }, // eval_xpath&lt;br /&gt;
    &lt;br /&gt;
    set_persistent: function(key, value, json=false) &lt;br /&gt;
    {&lt;br /&gt;
      // transparently stringify to json&lt;br /&gt;
      if(json) {&lt;br /&gt;
        // http://stackoverflow.com/questions/16682150/store-a-persistent-list-between-sessions&lt;br /&gt;
        value = JSON.stringify (value);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      // https://wiki.greasespot.net/GM_setValue&lt;br /&gt;
      GM_setValue(key, value);&lt;br /&gt;
      //UI.alert('Saved value for key\n'+key+':'+value);&lt;br /&gt;
    }, // set_persistent&lt;br /&gt;
    &lt;br /&gt;
    get_persistent: function(key, default_value, json=false) {&lt;br /&gt;
     // https://wiki.greasespot.net/GM_getValue&lt;br /&gt;
    &lt;br /&gt;
      var value=GM_getValue(key, default_value);&lt;br /&gt;
      // transparently support JSON: http://stackoverflow.com/questions/16682150/store-a-persistent-list-between-sessions&lt;br /&gt;
      if(json) {&lt;br /&gt;
        value = JSON.parse (value)  ||  {};&lt;br /&gt;
      }&lt;br /&gt;
      return value;&lt;br /&gt;
    }, // get_persistent&lt;br /&gt;
&lt;br /&gt;
   setClipboard: function(msg) {&lt;br /&gt;
   // this being a greasemonkey user-script, we are not &lt;br /&gt;
   // subject to usual browser restrictions&lt;br /&gt;
   // http://wiki.greasespot.net/GM_setClipboard&lt;br /&gt;
   GM_setClipboard(msg);&lt;br /&gt;
  }, // setClipboard()&lt;br /&gt;
    &lt;br /&gt;
    getTemplate: function() {&lt;br /&gt;
    &lt;br /&gt;
    // hard-coded default template&lt;br /&gt;
    var template = '$CONTENT&amp;lt;ref&amp;gt;{{cite web\n' +&lt;br /&gt;
  '  |url    =  $URL \n' +&lt;br /&gt;
  '  |title  =  &amp;lt;nowiki&amp;gt; $TITLE &amp;lt;/nowiki&amp;gt; \n' +&lt;br /&gt;
  '  |author =  &amp;lt;nowiki&amp;gt; $AUTHOR &amp;lt;/nowiki&amp;gt; \n' +&lt;br /&gt;
  '  |date   =  $DATE \n' +&lt;br /&gt;
  '  |added  =  $ADDED \n' +&lt;br /&gt;
  '  |script_version = $SCRIPT_VERSION \n' +&lt;br /&gt;
  '  }}&amp;lt;/ref&amp;gt;\n';&lt;br /&gt;
     &lt;br /&gt;
    // return a saved template if found, fall back to hard-coded one above otherwise&lt;br /&gt;
    return Host.get_persistent('default_template', template);&lt;br /&gt;
    &lt;br /&gt;
  } // getTemplate&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
  } // end of GreaseMonkey environment, add other environments below&lt;br /&gt;
  &lt;br /&gt;
}; // Environment hash - intended to help encapsulate host specific stuff (APIs)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// the first thing we need to do is to determine what APIs are available&lt;br /&gt;
// and store everything in a Host hash, which is subsequently used for API lookups&lt;br /&gt;
// the Host hash contains all platform/browser-specific APIs&lt;br /&gt;
var Host = Environment.getHost();&lt;br /&gt;
Environment.validate(Host); // this checks the obtained host to see if all required dependencies are available&lt;br /&gt;
Host.init(); // run environment specific initialization code (e.g. logic for GreaseMonkey setup)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// move DEBUG handling to a persistent configuration flag so that we can configure this using a jQuery dialog (defaulted to false)&lt;br /&gt;
// TODO: move DEBUG variable to Environment hash / init() routine&lt;br /&gt;
var DEBUG = Host.get_persistent('debug_mode_enabled', false);&lt;br /&gt;
Host.dbLog(&amp;quot;Debug mode is:&amp;quot;+DEBUG);&lt;br /&gt;
function DEBUG_mode() {&lt;br /&gt;
  // reset script invocation counter for testing purposes&lt;br /&gt;
  Host.dbLog('Resetting script invocation counter');&lt;br /&gt;
  Host.set_persistent(GM_info.script.version, 0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if (DEBUG)&lt;br /&gt;
DEBUG_mode();&lt;br /&gt;
&lt;br /&gt;
// hash with supported websites/URLs,  includes xpath and regex expressions to extract certain fields, and a vector with optional transformations for post-processing each field&lt;br /&gt;
&lt;br /&gt;
var CONFIG = {&lt;br /&gt;
  // WIP: the first entry is special, i.e. it's not an actual list archive (source), but only added here so that the same script can be used&lt;br /&gt;
  // for editing the FlightGear wiki&lt;br /&gt;
  &lt;br /&gt;
  'FlightGear.wiki': {&lt;br /&gt;
    type: 'wiki',&lt;br /&gt;
    enabled: false,&lt;br /&gt;
    event: 'document.onmouseup', // when to invoke the event handler&lt;br /&gt;
    // TODO: move downloadWatchlist() etc here&lt;br /&gt;
    event_handler: function () {&lt;br /&gt;
      console.log('FlightGear wiki handler active (waiting to be populated)');&lt;br /&gt;
      // this is where the logic for a wiki mode can be added over time (for now, it's a NOP)&lt;br /&gt;
    &lt;br /&gt;
    //for each supported mode, invoke the trigger and call the corresponding handler&lt;br /&gt;
    [].forEach.call(CONFIG['FlightGear.wiki'].modes, function(mode) {&lt;br /&gt;
      //dbLog(&amp;quot;Checking trigger:&amp;quot;+mode.name);&lt;br /&gt;
      if(mode.trigger() ) {&lt;br /&gt;
        mode.handler();&lt;br /&gt;
      }&lt;br /&gt;
    });&lt;br /&gt;
      &lt;br /&gt;
    }, // the event handler to be invoked&lt;br /&gt;
    url_reg: '^(http|https)://wiki.flightgear.org', // ignore for now: not currently used by the wiki mode&lt;br /&gt;
    &lt;br /&gt;
    modes: [&lt;br /&gt;
      { name:'process-editSections',&lt;br /&gt;
        trigger: function() {return true;}, // match URL regex - return true for always match&lt;br /&gt;
       &lt;br /&gt;
        // the code implementing the mode&lt;br /&gt;
        handler: function() {&lt;br /&gt;
                &lt;br /&gt;
    var editSections = document.getElementsByClassName('mw-editsection');&lt;br /&gt;
    console.log('FlightGear wiki article, number of edit sections: '+editSections.length);&lt;br /&gt;
   &lt;br /&gt;
    // for now, just rewrite edit sections and add a note to them&lt;br /&gt;
   &lt;br /&gt;
     [].forEach.call(editSections, function (sec) {&lt;br /&gt;
       sec.appendChild(&lt;br /&gt;
         document.createTextNode(' (instant-cquotes is lurking) ')&lt;br /&gt;
       );&lt;br /&gt;
     }); //forEach section&lt;br /&gt;
        } // handler&lt;br /&gt;
       &lt;br /&gt;
       &lt;br /&gt;
      } // process-editSections&lt;br /&gt;
      // TODO: add other wiki modes below &lt;br /&gt;
      &lt;br /&gt;
    ] // modes&lt;br /&gt;
    &lt;br /&gt;
  }, // end of wiki profile&lt;br /&gt;
  &lt;br /&gt;
  'Sourceforge Mailing list': {&lt;br /&gt;
    enabled: true,&lt;br /&gt;
    type: 'archive',&lt;br /&gt;
    event: 'document.onmouseup', // when to invoke the event handler&lt;br /&gt;
    event_handler: instantCquote, // the event handler to be invoked&lt;br /&gt;
    url_reg: '^(http|https)://sourceforge.net/p/flightgear/mailman/.*/',&lt;br /&gt;
    content: {&lt;br /&gt;
      xpath: 'tbody/tr[2]/td/pre/text()', // NOTE this is only used by the downloadPosting  helper to retrieve the posting without having a selection (TODO:add content xpath to forum hash)&lt;br /&gt;
      selection: getSelectedText,&lt;br /&gt;
      idStyle: /msg[0-9]{8}/,&lt;br /&gt;
      parentTag: [&lt;br /&gt;
        'tagName',&lt;br /&gt;
        'PRE'&lt;br /&gt;
      ],&lt;br /&gt;
      transform: [],&lt;br /&gt;
    }, // content recipe&lt;br /&gt;
    // vector with tests to be executed for sanity checks (unit testing)&lt;br /&gt;
    tests: [&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://sourceforge.net/p/flightgear/mailman/message/35059454/',&lt;br /&gt;
        author: 'Erik Hofman',&lt;br /&gt;
        date: 'May 3rd, 2016', // NOTE: using the transformed date here &lt;br /&gt;
        title: 'Re: [Flightgear-devel] Auto altimeter setting at startup (?)'&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://sourceforge.net/p/flightgear/mailman/message/35059961/',&lt;br /&gt;
        author: 'Ludovic Brenta',&lt;br /&gt;
        date: 'May 3rd, 2016',&lt;br /&gt;
        title: 'Re: [Flightgear-devel] dual-control-tools and the limit on packet size'&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://sourceforge.net/p/flightgear/mailman/message/20014126/',&lt;br /&gt;
        author: 'Tim Moore',&lt;br /&gt;
        date: 'Aug 4th, 2008',&lt;br /&gt;
        title: 'Re: [Flightgear-devel] Cockpit displays (rendering, modelling)'&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://sourceforge.net/p/flightgear/mailman/message/23518343/',&lt;br /&gt;
        author: 'Tim Moore',&lt;br /&gt;
        date: 'Sep 10th, 2009',&lt;br /&gt;
        title: '[Flightgear-devel] Atmosphere patch from John Denker'&lt;br /&gt;
      } // add other tests below&lt;br /&gt;
&lt;br /&gt;
    ], // end of vector with self-tests&lt;br /&gt;
    // regex/xpath and transformations for extracting various required fields&lt;br /&gt;
    author: {&lt;br /&gt;
      xpath: 'tbody/tr[1]/td/div/small/text()',&lt;br /&gt;
      transform: [extract(/From: (.*) &amp;lt;.*@.*&amp;gt;/)]&lt;br /&gt;
    },&lt;br /&gt;
    title: {&lt;br /&gt;
      xpath: 'tbody/tr[1]/td/div/div[1]/b/a/text()',&lt;br /&gt;
      transform:[]&lt;br /&gt;
    },&lt;br /&gt;
    date: {&lt;br /&gt;
      xpath: 'tbody/tr[1]/td/div/small/text()',&lt;br /&gt;
      transform: [extract(/- (.*-.*-.*) /)]&lt;br /&gt;
    },&lt;br /&gt;
    url: {&lt;br /&gt;
      xpath: 'tbody/tr[1]/td/div/div[1]/b/a/@href',&lt;br /&gt;
      transform: [prepend('https://sourceforge.net')]&lt;br /&gt;
    }&lt;br /&gt;
  }, // end of mailing list profile&lt;br /&gt;
  // next website/URL (forum)&lt;br /&gt;
  'FlightGear forum': {&lt;br /&gt;
    enabled: true,&lt;br /&gt;
    type: 'archive',&lt;br /&gt;
    event: 'document.onmouseup', // when to invoke the event handler (not used atm)&lt;br /&gt;
    event_handler: null, // the event handler to be invoked (not used atm)&lt;br /&gt;
    url_reg: /https:\/\/forum\.flightgear\.org\/.*/,&lt;br /&gt;
    content: {&lt;br /&gt;
      xpath: '', //TODO: this must be added for downloadPosting() to work, or it cannot extract contents&lt;br /&gt;
      selection: getSelectedHtml,&lt;br /&gt;
      idStyle: /p[0-9]{6}/,&lt;br /&gt;
      parentTag: [&lt;br /&gt;
        'className',&lt;br /&gt;
        'content',&lt;br /&gt;
        'postbody'&lt;br /&gt;
      ],&lt;br /&gt;
      transform: [&lt;br /&gt;
        removeComments,&lt;br /&gt;
        forum_quote2cquote,&lt;br /&gt;
        forum_smilies2text,&lt;br /&gt;
        forum_fontstyle2wikistyle,&lt;br /&gt;
        forum_code2syntaxhighlight,&lt;br /&gt;
        img2link,&lt;br /&gt;
        a2wikilink,&lt;br /&gt;
        vid2wiki,&lt;br /&gt;
        list2wiki,&lt;br /&gt;
        forum_br2newline&lt;br /&gt;
      ]&lt;br /&gt;
    },&lt;br /&gt;
    // vector with tests to be executed for sanity checks (unit testing)&lt;br /&gt;
    // postings will be downloaded using the URL specified, and then the author/title &lt;br /&gt;
    // fields extracted using the outer regex and matched against what is expected&lt;br /&gt;
    // NOTE: forum postings can be edited, so that these tests would fail - thus, it makes sense to pick locked topics/postings for such tests&lt;br /&gt;
    tests: [&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://forum.flightgear.org/viewtopic.php?f=18&amp;amp;p=284108#p284108',&lt;br /&gt;
        author: 'mickybadia',&lt;br /&gt;
        date: 'May 3rd, 2016',&lt;br /&gt;
        title: 'OSM still PNG maps'&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://forum.flightgear.org/viewtopic.php?f=19&amp;amp;p=284120#p284120',&lt;br /&gt;
        author: 'Thorsten',&lt;br /&gt;
        date: 'May 3rd, 2016',&lt;br /&gt;
        title: 'Re: FlightGear\'s Screenshot Of The Month MAY 2016'&lt;br /&gt;
      },&lt;br /&gt;
       {&lt;br /&gt;
        url: 'https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;t=29279&amp;amp;p=283455#p283446',&lt;br /&gt;
        author: 'Hooray',&lt;br /&gt;
         date: 'Apr 25th, 2016',&lt;br /&gt;
        title: 'Re: Best way to learn Canvas?'&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://forum.flightgear.org/viewtopic.php?f=4&amp;amp;t=1460&amp;amp;p=283994#p283994',&lt;br /&gt;
        author: 'bugman',&lt;br /&gt;
        date: 'May 2nd, 2016',&lt;br /&gt;
        title: 'Re: eurofighter typhoon'&lt;br /&gt;
      } // add other tests below&lt;br /&gt;
&lt;br /&gt;
    ], // end of vector with self-tests&lt;br /&gt;
    author: {&lt;br /&gt;
      xpath: 'div/div[1]/p/strong/a/text()',&lt;br /&gt;
      transform: [] // no transformations applied&lt;br /&gt;
    },&lt;br /&gt;
    title: {&lt;br /&gt;
      xpath: 'div/div[1]/h3/a/text()',&lt;br /&gt;
      transform: [] // no transformations applied&lt;br /&gt;
    },&lt;br /&gt;
    date: {&lt;br /&gt;
      xpath: 'div/div[1]/p/text()[2]',&lt;br /&gt;
      transform: [extract(/» (.*?[0-9]{4})/)]&lt;br /&gt;
    },&lt;br /&gt;
    url: {&lt;br /&gt;
      xpath: 'div/div[1]/p/a/@href',&lt;br /&gt;
      transform: [&lt;br /&gt;
        extract(/\.(.*)/),&lt;br /&gt;
        prepend('https://forum.flightgear.org')&lt;br /&gt;
      ] // transform vector&lt;br /&gt;
    } // url&lt;br /&gt;
  } // forum &lt;br /&gt;
}; // CONFIG has&lt;br /&gt;
&lt;br /&gt;
// hash to map URLs (wiki article, issue tracker, sourceforge link, forum thread etc) to existing wiki templates&lt;br /&gt;
var MatchURL2Templates = [&lt;br /&gt;
  // placeholder for now&lt;br /&gt;
 {&lt;br /&gt;
   name: 'rewrite sourceforge code links',&lt;br /&gt;
   url_reg: '',&lt;br /&gt;
   handler: function() {&lt;br /&gt;
   &lt;br /&gt;
 } // handler&lt;br /&gt;
  &lt;br /&gt;
 } // add other templates below&lt;br /&gt;
  &lt;br /&gt;
]; // MatchURL2Templates&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// output methods (alert and jQuery for now)&lt;br /&gt;
var OUTPUT = {&lt;br /&gt;
  // Shows a window.prompt() message box&lt;br /&gt;
  msgbox: function (msg) {&lt;br /&gt;
    UI.prompt('Copy to clipboard ' + Host.getScriptVersion(), msg);&lt;br /&gt;
    Host.setClipboard(msg);&lt;br /&gt;
  }, // msgbox&lt;br /&gt;
  &lt;br /&gt;
  // this is currently work-in-progress, and will need to be refactored sooner or later&lt;br /&gt;
  // for now, functionality matters more than elegant design/code :)&lt;br /&gt;
  jQueryTabbed: function(msg, original) {&lt;br /&gt;
  // FIXME: using backtics here makes the whole thing require ES6  ....&lt;br /&gt;
  var markup = $(`&amp;lt;div id=&amp;quot;tabs&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;ul&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#selection&amp;quot;&amp;gt;Selection&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#articles&amp;quot;&amp;gt;Articles&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#templates&amp;quot;&amp;gt;Templates&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#development&amp;quot;&amp;gt;Development&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#settings&amp;quot;&amp;gt;Settings&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#help&amp;quot;&amp;gt;Help&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#about&amp;quot;&amp;gt;About&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;/ul&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;selection&amp;quot;&amp;gt;This tab contains your extracted and post-processed selection, converted to proper wikimedia markup, including proper attribution.&lt;br /&gt;
  &amp;lt;div id=&amp;quot;content&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;label for=&amp;quot;template_select&amp;quot;&amp;gt;Select a template&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;select name=&amp;quot;template_select&amp;quot; id=&amp;quot;template_select&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;option&amp;gt;default&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option&amp;gt;cquote&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;/select&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;options&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Note this is work-in-progress, i.e. not yet fully functional&amp;lt;/b&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
    &amp;lt;label for=&amp;quot;article_select&amp;quot;&amp;gt;Select an article to update&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;select name=&amp;quot;article_select&amp;quot; id=&amp;quot;article_select&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;news&amp;quot; label=&amp;quot;News&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;support&amp;quot; label=&amp;quot;Support&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;release&amp;quot; label=&amp;quot;Release&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;develop&amp;quot; label=&amp;quot;Development&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;watchlist&amp;quot; label=&amp;quot;Watchlist&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;/select&amp;gt;&lt;br /&gt;
    &amp;lt;p/&amp;gt;&lt;br /&gt;
    &amp;lt;label for=&amp;quot;section_select&amp;quot;&amp;gt;Select section:&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;select name=&amp;quot;section_select&amp;quot; id=&amp;quot;section_select&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;/select&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;articles&amp;quot;&amp;gt;This tab contains articles that you can directly access/edit using the mediawiki API&amp;lt;br/&amp;gt;&lt;br /&gt;
  Note: The watchlist is retrieved dynamically, so does not need to be edited here&amp;lt;br/&amp;gt;&lt;br /&gt;
    &amp;lt;label for=&amp;quot;article_select&amp;quot;&amp;gt;Select an article&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;select name=&amp;quot;article_select&amp;quot; id=&amp;quot;article_select&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;news&amp;quot; label=&amp;quot;News&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;support&amp;quot; label=&amp;quot;Support&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;develop&amp;quot; label=&amp;quot;Development&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;release&amp;quot; label=&amp;quot;Release&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;!-- the watchlist is retrieved dynamically, so omit it here &lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;watchlist&amp;quot; label=&amp;quot;Watchlist&amp;quot;/&amp;gt;&lt;br /&gt;
    --&amp;gt;&lt;br /&gt;
    &amp;lt;/select&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;button id=&amp;quot;article_new&amp;quot;&amp;gt;New&amp;lt;/button&amp;gt;&lt;br /&gt;
   &amp;lt;button id=&amp;quot;article_remove&amp;quot;&amp;gt;Remove&amp;lt;/button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div id=&amp;quot;edit_article&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;label for=&amp;quot;article_name&amp;quot;&amp;gt;Article&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;text&amp;quot; id=&amp;quot;article_name&amp;quot; name=&amp;quot;article_name&amp;quot;&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;label for=&amp;quot;article_url&amp;quot;&amp;gt;Link&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;text&amp;quot; id=&amp;quot;article_url&amp;quot; name=&amp;quot;article_url&amp;quot;&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;button id=&amp;quot;article_save&amp;quot;&amp;gt;Save&amp;lt;/button&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;templates&amp;quot;&amp;gt;This tab contains templates for different types of articles (newsletter, changelog, release plan etc)&amp;lt;p/&amp;gt;&lt;br /&gt;
  For now, this is WIP - in the future, there will be a dropdown menu added and all templates will be editable.&amp;lt;p/&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;template_header&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;label for=&amp;quot;template_select&amp;quot;&amp;gt;Select a template&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;select name=&amp;quot;template_select&amp;quot; id=&amp;quot;template_select&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;option&amp;gt;default&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option&amp;gt;cquote&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;/select&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;template_area&amp;quot;/&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;template_controls&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;button id=&amp;quot;template_save&amp;quot;&amp;gt;Save&amp;lt;/button&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;development&amp;quot;&amp;gt;This tab is a placeholder for features currently under development&amp;lt;p/&amp;gt;&lt;br /&gt;
  &amp;lt;button id=&amp;quot;evolve_regex&amp;quot;&amp;gt;Evolve regex&amp;lt;/button&amp;gt;&amp;lt;p/&amp;gt;&lt;br /&gt;
  &amp;lt;button id=&amp;quot;test_perceptron&amp;quot;&amp;gt;Test Perceptron&amp;lt;/button&amp;gt;&amp;lt;p/&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;output&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table id=&amp;quot;results&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;thead&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
     &amp;lt;th&amp;gt;Generation&amp;lt;/th&amp;gt;&lt;br /&gt;
     &amp;lt;th&amp;gt;Fitness&amp;lt;/th&amp;gt;&lt;br /&gt;
     &amp;lt;th&amp;gt;Expression&amp;lt;/th&amp;gt;&lt;br /&gt;
     &amp;lt;th&amp;gt;Result&amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
  &amp;lt;/thead&amp;gt;&lt;br /&gt;
  &amp;lt;tbody&amp;gt;&lt;br /&gt;
  &amp;lt;/tbody&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt; &lt;br /&gt;
&lt;br /&gt;
   &amp;lt;!--&lt;br /&gt;
   &amp;lt;textarea id=&amp;quot;devel_output&amp;quot; lines=&amp;quot;10&amp;quot;&amp;gt;&amp;lt;/textarea&amp;gt;&amp;lt;p/&amp;gt;&lt;br /&gt;
  --&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div id=&amp;quot;settings&amp;quot;&amp;gt;This tab will contain script specific settings&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;help&amp;quot;&amp;gt;One day, this tab may contain help....&amp;lt;p/&amp;gt;&amp;lt;button id=&amp;quot;helpButton&amp;quot;&amp;gt;Instant Cquotes&amp;lt;/button&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;about&amp;quot;&amp;gt;show some  script related information here&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;`); // tabs div&lt;br /&gt;
    &lt;br /&gt;
   var evolve_regex = $('div#development button#evolve_regex', markup);&lt;br /&gt;
   evolve_regex.click(function() {&lt;br /&gt;
     //alert(&amp;quot;Evolve regex&amp;quot;);&lt;br /&gt;
     evolve_expression_test();&lt;br /&gt;
   });&lt;br /&gt;
    &lt;br /&gt;
   var test_perceptron = $('div#development button#test_perceptron', markup);&lt;br /&gt;
   test_perceptron.click(function() {&lt;br /&gt;
     alert(&amp;quot;Test perceptron&amp;quot;);&lt;br /&gt;
   });&lt;br /&gt;
   &lt;br /&gt;
    &lt;br /&gt;
    // add dynamic elements to each tab&lt;br /&gt;
    &lt;br /&gt;
   // NOTE: this affects all template selectors, on all tabs&lt;br /&gt;
   $('select#template_select', markup).change(function() {&lt;br /&gt;
     UI.alert(&amp;quot;Sorry, templates are not yet fully implemented (WIP)&amp;quot;);&lt;br /&gt;
   });&lt;br /&gt;
    &lt;br /&gt;
   var help = $('#helpButton', markup);&lt;br /&gt;
   help.button();&lt;br /&gt;
   help.click(function() {&lt;br /&gt;
     window.open(&amp;quot;http://wiki.flightgear.org/FlightGear_wiki:Instant-Cquotes&amp;quot;);&lt;br /&gt;
   });&lt;br /&gt;
    &lt;br /&gt;
   // rows=&amp;quot;10&amp;quot;cols=&amp;quot;80&amp;quot; style=&amp;quot; width: 420px; height: 350px&amp;quot;&lt;br /&gt;
   var textarea = $('&amp;lt;textarea id=&amp;quot;quotedtext&amp;quot; rows=&amp;quot;20&amp;quot; cols=&amp;quot;70&amp;quot;/&amp;gt;');&lt;br /&gt;
   textarea.val(msg);&lt;br /&gt;
   $('#selection #content', markup).append(textarea);&lt;br /&gt;
  &lt;br /&gt;
   var templateArea = $('&amp;lt;textarea id=&amp;quot;template-edit&amp;quot; rows=&amp;quot;20&amp;quot; cols=&amp;quot;70&amp;quot;/&amp;gt;');&lt;br /&gt;
   templateArea.val( Host.getTemplate() );&lt;br /&gt;
   $('div#templates div#template_area', markup).append(templateArea);&lt;br /&gt;
   &lt;br /&gt;
   //$('#templates', markup).append($('&amp;lt;button&amp;gt;'));&lt;br /&gt;
    $('div#templates div#template_controls button#template_save',markup).button().click(function() {&lt;br /&gt;
      //UI.alert(&amp;quot;Saving template:\n&amp;quot;+templateArea.val() );&lt;br /&gt;
      &lt;br /&gt;
      Host.set_persistent('default_template',templateArea.val() );&lt;br /&gt;
    }); // save template&lt;br /&gt;
    &lt;br /&gt;
  // TODO: Currently, this is hard-coded, but should be made customizable via the &amp;quot;articles&amp;quot; tab at some point ...&lt;br /&gt;
  var articles = [&lt;br /&gt;
    // NOTE: category must match an existing &amp;lt;optgroup&amp;gt; above, title must match an existing wiki article&lt;br /&gt;
    {category:'support', name:'Frequently asked questions', url:''},&lt;br /&gt;
    {category:'support', name:'Asking for help', url:''},&lt;br /&gt;
    {category:'news', name:'Next newsletter', url:''},&lt;br /&gt;
    {category:'news', name:'Next changelog', url:''},&lt;br /&gt;
    {category:'release', name:'Release plan/Lessons learned', url:''}, // TODO: use wikimedia template&lt;br /&gt;
    {category:'develop', name:'Nasal library', url:''},&lt;br /&gt;
    {category:'develop', name:'Canvas Snippets', url:''},&lt;br /&gt;
    &lt;br /&gt;
  ];&lt;br /&gt;
    &lt;br /&gt;
    // TODO: this should be moved elsewhere&lt;br /&gt;
    function updateArticleList(selector) {&lt;br /&gt;
    $.each(articles, function (i, article) {&lt;br /&gt;
    $(selector+ ' optgroup#'+article.category, markup).append($('&amp;lt;option&amp;gt;', { &lt;br /&gt;
        value: article.name, // FIXME: just a placeholder for now&lt;br /&gt;
        text : article.name &lt;br /&gt;
    })); //append option&lt;br /&gt;
   }); // foreach&lt;br /&gt;
    } // updateArticleList&lt;br /&gt;
    &lt;br /&gt;
    // add the article list to the corresponding dropdown menus&lt;br /&gt;
    updateArticleList('select#article_select');&lt;br /&gt;
        &lt;br /&gt;
    // populate watchlist (prototype for now)&lt;br /&gt;
    // TODO: generalize &amp;amp; refactor: url, format&lt;br /&gt;
      &lt;br /&gt;
    // https://www.mediawiki.org/wiki/API:Watchlist&lt;br /&gt;
    // http://wiki.flightgear.org/api.php?action=query&amp;amp;list=watchlist&lt;br /&gt;
      var watchlist_url = 'http://wiki.flightgear.org/api.php?action=query&amp;amp;list=watchlist&amp;amp;format=json';&lt;br /&gt;
      Host.download(watchlist_url, function(response) {&lt;br /&gt;
        try {&lt;br /&gt;
       var watchlist = JSON.parse(response.responseText);&lt;br /&gt;
            &lt;br /&gt;
       //$('div#options select#section_select', markup).empty(); // delete all sections&lt;br /&gt;
      &lt;br /&gt;
      $.each(watchlist.query.watchlist, function (i, article) {&lt;br /&gt;
      $('div#options select#article_select optgroup#watchlist', markup).append($('&amp;lt;option&amp;gt;', { &lt;br /&gt;
        value: article.title, //FIXME just a placeholder for now&lt;br /&gt;
        text : article.title &lt;br /&gt;
    }));&lt;br /&gt;
   }); //foreach section&lt;br /&gt;
&lt;br /&gt;
        }&lt;br /&gt;
        catch (e) {&lt;br /&gt;
          UI.alert(&amp;quot;Could not download wiki watchlist\n&amp;quot;+watchlist.error.info);&lt;br /&gt;
        }&lt;br /&gt;
      }); // download &amp;amp; populate watchlist&lt;br /&gt;
      &lt;br /&gt;
    &lt;br /&gt;
    // register an event handler for the main tab, so that article specific sections can be retrieved&lt;br /&gt;
    $('div#options select#article_select', markup).change(function() {&lt;br /&gt;
      var article = this.value;&lt;br /&gt;
      &lt;br /&gt;
    // HACK: try to get a login token (actually not needed just for reading ...)&lt;br /&gt;
    Host.download('http://wiki.flightgear.org/api.php?action=query&amp;amp;prop=info|revisions&amp;amp;intoken=edit&amp;amp;rvprop=timestamp&amp;amp;titles=Main%20Page', function (response) {&lt;br /&gt;
    var message = 'FlightGear wiki login status (AJAX):';&lt;br /&gt;
    var status = response.statusText;&lt;br /&gt;
    &lt;br /&gt;
    // populate dropdown menu with article sections&lt;br /&gt;
    if (status === 'OK') {&lt;br /&gt;
    &lt;br /&gt;
      // Resolve redirects: https://www.mediawiki.org/wiki/API:Query#Resolving_redirects&lt;br /&gt;
      var section_url = 'http://wiki.flightgear.org/api.php?action=parse&amp;amp;page='+encodeURIComponent(article)+'&amp;amp;prop=sections&amp;amp;format=json&amp;amp;redirects';&lt;br /&gt;
      Host.download(section_url, function(response) {&lt;br /&gt;
        try {&lt;br /&gt;
       var sections = JSON.parse(response.responseText);&lt;br /&gt;
            &lt;br /&gt;
       $('div#options select#section_select', markup).empty(); // delete all sections&lt;br /&gt;
      &lt;br /&gt;
      $.each(sections.parse.sections, function (i, section) {&lt;br /&gt;
      $('div#options select#section_select', markup).append($('&amp;lt;option&amp;gt;', { &lt;br /&gt;
        value: section.line, //FIXME just a placeholder for now&lt;br /&gt;
        text : section.line &lt;br /&gt;
    }));&lt;br /&gt;
   }); //foreach section&lt;br /&gt;
&lt;br /&gt;
        }&lt;br /&gt;
        catch (e) {&lt;br /&gt;
          UI.alert(e.message);&lt;br /&gt;
        }&lt;br /&gt;
             &lt;br /&gt;
      }); //download sections&lt;br /&gt;
     &lt;br /&gt;
      &lt;br /&gt;
      &lt;br /&gt;
    } // login status is OK&lt;br /&gt;
&lt;br /&gt;
      &lt;br /&gt;
  }); // Host.download() call, i.e. we have a login token&lt;br /&gt;
      &lt;br /&gt;
    }); // on select change&lt;br /&gt;
    &lt;br /&gt;
  // init the tab stuff&lt;br /&gt;
  markup.tabs();&lt;br /&gt;
  &lt;br /&gt;
  var diagParam = {&lt;br /&gt;
      title: 'Instant Cquotes ' + Host.getScriptVersion(),&lt;br /&gt;
      modal: true,&lt;br /&gt;
      width: 700,&lt;br /&gt;
      buttons: [&lt;br /&gt;
        {&lt;br /&gt;
          text:'reported speech',&lt;br /&gt;
          click: function() {&lt;br /&gt;
            textarea.val(createCquote(original,true));&lt;br /&gt;
          }&lt;br /&gt;
        },&lt;br /&gt;
        &lt;br /&gt;
        {&lt;br /&gt;
          text: 'Copy',&lt;br /&gt;
          click: function () {&lt;br /&gt;
            Host.setClipboard(msg);&lt;br /&gt;
            $(this).dialog('close');&lt;br /&gt;
          }&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
      ]&lt;br /&gt;
  };&lt;br /&gt;
    &lt;br /&gt;
  // actually show our tabbed dialog using the params above&lt;br /&gt;
  markup.dialog(diagParam);&lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
  } // jQueryTabbed() &lt;br /&gt;
  &lt;br /&gt;
}; // output methods&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// TODO: we can use an online API to  help with some of this: http://www.eslnow.org/reported-speech-converter/&lt;br /&gt;
// See also: http://blog.mashape.com/list-of-25-natural-language-processing-apis/&lt;br /&gt;
// http://text-processing.com/docs/phrases.html&lt;br /&gt;
// http://www.alchemyapi.com/&lt;br /&gt;
// https://words.bighugelabs.com/api.php&lt;br /&gt;
// https://www.wordsapi.com/&lt;br /&gt;
// http://www.dictionaryapi.com/&lt;br /&gt;
// https://www.textrazor.com/&lt;br /&gt;
// http://www.programmableweb.com/news/how-5-natural-language-processing-apis-stack/analysis/2014/07/28&lt;br /&gt;
&lt;br /&gt;
var speechTransformations = [&lt;br /&gt;
// TODO: support aliasing using vectors: would/should &lt;br /&gt;
// ordering is crucial here (most specific first, least specific/most generic last)&lt;br /&gt;
 &lt;br /&gt;
// first, we start off  by expanding short forms: http://www.learnenglish.de/grammar/shortforms.html&lt;br /&gt;
// http://www.macmillandictionary.com/thesaurus-category/british/short-forms&lt;br /&gt;
 &lt;br /&gt;
  {query:/couldn\'t/gi, replacement:'could not'},&lt;br /&gt;
  {query:/I could not/gi, replacement:'$author could not'},&lt;br /&gt;
  &lt;br /&gt;
  {query:/I\'m/gi, replacement:'I am'},&lt;br /&gt;
  {query:/I am/gi, replacement:'$author is'},&lt;br /&gt;
  &lt;br /&gt;
  {query:/I\'ve/, replacement:'I have'},&lt;br /&gt;
  {query:/I have had/, replacement:'$author had'},&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  {query:/can(\'|\’)t/gi, replacement:'cannot'},&lt;br /&gt;
  &lt;br /&gt;
  {query:/I(\'|\’)ll/gi, replacement:'$author will'},&lt;br /&gt;
  {query:/I(\'|\’)d/gi, replacement:'$author would'},&lt;br /&gt;
  &lt;br /&gt;
  {query:/I have done/gi, replacement:'$author has done'},&lt;br /&gt;
  {query:/I\'ve done/gi, replacement:'$author has done'}, //FIXME. queries should really be vectors ...&lt;br /&gt;
  &lt;br /&gt;
  {query:/I believe/gi, replacement:'$author suggested'},&lt;br /&gt;
  {query:/I think/gi, replacement:'$author suggested'},&lt;br /&gt;
  {query:/I guess/gi, replacement:'$author believes'},&lt;br /&gt;
  &lt;br /&gt;
  {query:/I can see that/gi, replacement:'$author suggested that'},&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  {query:/I have got/gi, replacement:'$author has got'},&lt;br /&gt;
  {query:/I\'ve got/gi, replacement:'$author has got'},&lt;br /&gt;
  &lt;br /&gt;
  {query:/I\'d suggest/gi, replacement:'$author would suggest'},&lt;br /&gt;
  &lt;br /&gt;
  {query:/I\’m prototyping/gi, replacement:'$author is prototyping'},&lt;br /&gt;
  &lt;br /&gt;
  {query:/I myself/gi, replacement:'$author himself'},&lt;br /&gt;
  {query:/I am/gi, replacement:' $author is'},&lt;br /&gt;
  &lt;br /&gt;
  {query:/I can see/gi, replacement:'$author can see'},&lt;br /&gt;
  {query:/I can/gi, replacement:'$author can'},&lt;br /&gt;
  {query:/I have/gi, replacement:'$author has'},&lt;br /&gt;
  {query:/I should/g, replacement:'$author should'},&lt;br /&gt;
  {query:/I shall/gi, replacement:'$author shall'},&lt;br /&gt;
  {query:/I may/gi, replacement:'$author may'},&lt;br /&gt;
  {query:/I will/gi, replacement:'$author will'},&lt;br /&gt;
  {query:/I would/gi, replacement:'$author would'},&lt;br /&gt;
  {query:/by myself/gi, replacement:'by $author'},&lt;br /&gt;
  {query:/and I/gi, replacement:'and $author'},&lt;br /&gt;
  {query:/and me/gi, replacement:'and $author'},&lt;br /&gt;
  {query:/and myself/gi, replacement:'and $author'}&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  // least specific stuff last (broad/generic stuff is kept as is, with author clarification added in parentheses)&lt;br /&gt;
  /*&lt;br /&gt;
  {query:/I/, replacement:'I ($author)'},&lt;br /&gt;
  &lt;br /&gt;
  {query:/me/, replacement:'me ($author)'},&lt;br /&gt;
  {query:/my/, replacement:'my ($author)'},&lt;br /&gt;
  {query:/myself/, replacement:'myself ($author)'},&lt;br /&gt;
  {query:/mine/, replacement:'$author'}&lt;br /&gt;
  */&lt;br /&gt;
];&lt;br /&gt;
&lt;br /&gt;
// try to assist in transforming speech using the transformation vector passed in&lt;br /&gt;
// still needs to be exposed via the UI&lt;br /&gt;
function transformSpeech(text, author, gender, transformations) {&lt;br /&gt;
  // WIP: foreach transformation in vector, replace the search pattern with the matched string (replacing author/gender as applicable)&lt;br /&gt;
  //alert(&amp;quot;text to be transformed:\n&amp;quot;+text);&lt;br /&gt;
  for(var i=0;i&amp;lt; transformations.length; i++) {&lt;br /&gt;
    var token = transformations[i];&lt;br /&gt;
    // patch the replacement string using the correct author name &lt;br /&gt;
    var replacement = token.replacement.replace(/\$author/gi, author);&lt;br /&gt;
    text = text.replace(token.query, replacement);&lt;br /&gt;
  } // end of token transformation&lt;br /&gt;
  console.log(&amp;quot;transformed text is:&amp;quot;+text);&lt;br /&gt;
  return text;&lt;br /&gt;
} // transformSpeech&lt;br /&gt;
&lt;br /&gt;
// run a self-test&lt;br /&gt;
&lt;br /&gt;
(function() {&lt;br /&gt;
var author =&amp;quot;John Doe&amp;quot;;&lt;br /&gt;
var transformed = transformSpeech(&amp;quot;I have decided to commit a new feature&amp;quot;, author, null, speechTransformations );&lt;br /&gt;
if (transformed !== author+&amp;quot; has decided to commit a new feature&amp;quot;)&lt;br /&gt;
  Host.dbLog(&amp;quot;FIXME: Speech transformations are not working correctly&amp;quot;);&lt;br /&gt;
}) ();&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
var MONTHS = [&lt;br /&gt;
  'Jan',&lt;br /&gt;
  'Feb',&lt;br /&gt;
  'Mar',&lt;br /&gt;
  'Apr',&lt;br /&gt;
  'May',&lt;br /&gt;
  'Jun',&lt;br /&gt;
  'Jul',&lt;br /&gt;
  'Aug',&lt;br /&gt;
  'Sep',&lt;br /&gt;
  'Oct',&lt;br /&gt;
  'Nov',&lt;br /&gt;
  'Dec'&lt;br /&gt;
];&lt;br /&gt;
// Conversion for forum emoticons&lt;br /&gt;
var EMOTICONS = [&lt;br /&gt;
  [/:shock:/g,&lt;br /&gt;
  'O_O'],&lt;br /&gt;
  [&lt;br /&gt;
    /:lol:/g,&lt;br /&gt;
    '(lol)'&lt;br /&gt;
  ],&lt;br /&gt;
  [&lt;br /&gt;
    /:oops:/g,&lt;br /&gt;
    ':$'&lt;br /&gt;
  ],&lt;br /&gt;
  [&lt;br /&gt;
    /:cry:/g,&lt;br /&gt;
    ';('&lt;br /&gt;
  ],&lt;br /&gt;
  [&lt;br /&gt;
    /:evil:/g,&lt;br /&gt;
    '&amp;gt;:)'&lt;br /&gt;
  ],&lt;br /&gt;
  [&lt;br /&gt;
    /:twisted:/g,&lt;br /&gt;
    '3:)'&lt;br /&gt;
  ],&lt;br /&gt;
  [&lt;br /&gt;
    /:roll:/g,&lt;br /&gt;
    '(eye roll)'&lt;br /&gt;
  ],&lt;br /&gt;
  [&lt;br /&gt;
    /:wink:/g,&lt;br /&gt;
    ';)'&lt;br /&gt;
  ],&lt;br /&gt;
  [&lt;br /&gt;
    /:!:/g,&lt;br /&gt;
    '(!)'&lt;br /&gt;
  ],&lt;br /&gt;
  [&lt;br /&gt;
    /:\?:/g,&lt;br /&gt;
    '(?)'&lt;br /&gt;
  ],&lt;br /&gt;
  [&lt;br /&gt;
    /:idea:/g,&lt;br /&gt;
    '(idea)'&lt;br /&gt;
  ],&lt;br /&gt;
  [&lt;br /&gt;
    /:arrow:/g,&lt;br /&gt;
    '(-&amp;gt;)'&lt;br /&gt;
  ],&lt;br /&gt;
  [&lt;br /&gt;
    /:mrgreen:/g,&lt;br /&gt;
    'xD'&lt;br /&gt;
  ]&lt;br /&gt;
];&lt;br /&gt;
// ##################&lt;br /&gt;
// # Main functions #&lt;br /&gt;
// ##################&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// the required trigger is host specific (userscript vs. addon vs. android etc)&lt;br /&gt;
// for now, this merely wraps window.load mapping to the instantCquotoe callback below&lt;br /&gt;
Host.registerTrigger();&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// FIXME: function is currently referenced in CONFIG hash - event_handler, so cannot be easily moved across&lt;br /&gt;
// The main function&lt;br /&gt;
// TODO: split up, so that we can reuse the code elsewhere&lt;br /&gt;
function instantCquote(sel) {&lt;br /&gt;
  var profile = getProfile();&lt;br /&gt;
  &lt;br /&gt;
  // TODO: use config hash here&lt;br /&gt;
  var selection =  document.getSelection(),&lt;br /&gt;
  post_id=0;&lt;br /&gt;
  &lt;br /&gt;
  try {&lt;br /&gt;
    post_id = getPostId(selection, profile);&lt;br /&gt;
  } &lt;br /&gt;
  catch (error) {&lt;br /&gt;
    Host.dbLog('Failed extracting post id\nProfile:' + profile);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  if (selection.toString() === '') {&lt;br /&gt;
    Host.dbLog('No text is selected, aborting function');&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  if (!checkValid(selection, profile)) {&lt;br /&gt;
    Host.dbLog('Selection is not valid, aborting function');&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  try {&lt;br /&gt;
    transformationLoop(profile, post_id);&lt;br /&gt;
  }&lt;br /&gt;
  catch(e) {&lt;br /&gt;
    UI.alert(&amp;quot;Transformation loop:\n&amp;quot;+e.message);&lt;br /&gt;
  }&lt;br /&gt;
} // instantCquote&lt;br /&gt;
&lt;br /&gt;
  // TODO: this needs to be refactored so that it can be also reused by the async/AJAX mode&lt;br /&gt;
  // to extract fields in the background (i.e. move to a separate function)&lt;br /&gt;
function transformationLoop(profile, post_id) {&lt;br /&gt;
  var output = {}, field;&lt;br /&gt;
  Host.dbLog(&amp;quot;Starting extraction/transformation loop&amp;quot;);&lt;br /&gt;
  for (field in profile) {&lt;br /&gt;
    if (field === 'name') continue;&lt;br /&gt;
    if (field ==='type' || field === 'event' || field === 'event_handler') continue; // skip fields that don't contain xpath expressions&lt;br /&gt;
    Host.dbLog(&amp;quot;Extracting field using field id:&amp;quot;+post_id);&lt;br /&gt;
    var fieldData = extractFieldInfo(profile, post_id, field);&lt;br /&gt;
    var transform = profile[field].transform;&lt;br /&gt;
    if (transform !== undefined) {&lt;br /&gt;
      Host.dbLog('Field \'' + field + '\' before transformation:\n\'' + fieldData + '\'');&lt;br /&gt;
      fieldData = applyTransformations(fieldData, transform);&lt;br /&gt;
      Host.dbLog('Field \'' + field + '\' after transformation:\n\'' + fieldData + '\'');&lt;br /&gt;
    }&lt;br /&gt;
    output[field] = fieldData;&lt;br /&gt;
  } // extract and transform all fields for the current profile (website)&lt;br /&gt;
  Host.dbLog(&amp;quot;extraction and transformation loop finished&amp;quot;);&lt;br /&gt;
  output.content = stripWhitespace(output.content);&lt;br /&gt;
  &lt;br /&gt;
  var outputPlain = createCquote(output);&lt;br /&gt;
  outputText(outputPlain, output);&lt;br /&gt;
} // transformationLoop()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/// #############&lt;br /&gt;
&lt;br /&gt;
function runProfileTests() {&lt;br /&gt;
  &lt;br /&gt;
  for (var profile in CONFIG) {&lt;br /&gt;
    if (CONFIG[profile].type != 'archive' || !CONFIG[profile].enabled ) continue; // skip the wiki entry, because it's not an actual archive that we need to test&lt;br /&gt;
    // should be really moved to downloadPostign&lt;br /&gt;
    if (CONFIG[profile].content.xpath === '') console.log(&amp;quot;xpath for content extraction is empty, cannot procedurally extract contents&amp;quot;);&lt;br /&gt;
    for (var test in CONFIG[profile].tests) {&lt;br /&gt;
      var required_data = CONFIG[profile].tests[test];&lt;br /&gt;
      var title = required_data.title;&lt;br /&gt;
      //dbLog('Running test for posting titled:' + title);&lt;br /&gt;
      // fetch posting via getPostingDataAJAX() and compare to the fields we are looking for (author, title, date)&lt;br /&gt;
      //getPostingDataAJAX(profile, required_data.url);&lt;br /&gt;
      //alert(&amp;quot;required title:&amp;quot;+title);&lt;br /&gt;
    } // foreach test&lt;br /&gt;
&lt;br /&gt;
  } // foreach profile (website)&lt;br /&gt;
  &lt;br /&gt;
} //runProfileTests&lt;br /&gt;
&lt;br /&gt;
function selfCheckDialog() {&lt;br /&gt;
  var sections = '&amp;lt;h3&amp;gt;Important APIs:&amp;lt;/h3&amp;gt;&amp;lt;div id=&amp;quot;api_checks&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;';&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  try {&lt;br /&gt;
   runProfileTests.call(undefined); // check website profiles&lt;br /&gt;
  }&lt;br /&gt;
  catch (e) {&lt;br /&gt;
      UI.alert(e.message);&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  for (var profile in CONFIG) {&lt;br /&gt;
    // TODO: also check if enabled or not&lt;br /&gt;
    if (CONFIG[profile].type != 'archive') continue; // skip the wiki entry, because it's not an actual archive that we need to test&lt;br /&gt;
    var test_results = '';&lt;br /&gt;
    for (var test in CONFIG[profile].tests) {&lt;br /&gt;
      // var fieldData = extractFieldInfo(profile, post_id, 'author');&lt;br /&gt;
      test_results += CONFIG[profile].tests[test].title + '&amp;lt;p/&amp;gt;';&lt;br /&gt;
    }&lt;br /&gt;
    sections +='&amp;lt;h3&amp;gt;' + profile + ':&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;'+ CONFIG[profile].url_reg+'&amp;lt;/font&amp;gt;&amp;lt;/h3&amp;gt;&amp;lt;div&amp;gt;&amp;lt;p&amp;gt;' + test_results + '&amp;lt;/p&amp;gt;&amp;lt;/div&amp;gt;\n';&lt;br /&gt;
  }  // https://jqueryui.com/accordion/&lt;br /&gt;
  &lt;br /&gt;
 &lt;br /&gt;
  var checkDlg = $('&amp;lt;div id=&amp;quot;selfCheck&amp;quot; title=&amp;quot;Self Check dialog&amp;quot;&amp;gt;&amp;lt;p&amp;gt;&amp;lt;div id=&amp;quot;accordion&amp;quot;&amp;gt;' + sections + '&amp;lt;/div&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;/div&amp;gt;');&lt;br /&gt;
  &lt;br /&gt;
   // run all API tests, invoke the callback to obtain the status&lt;br /&gt;
  Environment.runAPITests(Host, function(meta) {&lt;br /&gt;
  &lt;br /&gt;
  //console.log('Running API test '+meta.name);&lt;br /&gt;
    &lt;br /&gt;
  meta.test(function(result) {&lt;br /&gt;
   var status = (result)?'success':'fail';&lt;br /&gt;
   var test = $(&amp;quot;&amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&amp;quot;).text('Running API test '+meta.name+':'+status); &lt;br /&gt;
   $('#api_checks', checkDlg).append(test);&lt;br /&gt;
  }); // update tests results&lt;br /&gt;
    &lt;br /&gt;
  }); // runAPITests&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  /*&lt;br /&gt;
  [].forEach.call(CONFIG, function(profile) {&lt;br /&gt;
    alert(&amp;quot;profile is:&amp;quot;+profile);&lt;br /&gt;
  [].forEach.call(CONFIG[profile].tests, function(test) {&lt;br /&gt;
    &lt;br /&gt;
    //UI.alert(test.url);&lt;br /&gt;
    Host.downloadPosting(test.url, function(downloaded) {&lt;br /&gt;
      alert(&amp;quot;downloaded:&amp;quot;);&lt;br /&gt;
      //if (test.title == downloaded.title) alert(&amp;quot;titles match:&amp;quot;+test.title);&lt;br /&gt;
    }); //downloadPosting&lt;br /&gt;
  }); //forEach test&lt;br /&gt;
  }); //forEach profile&lt;br /&gt;
  */&lt;br /&gt;
  &lt;br /&gt;
  //$('#accordion',checkDlg).accordion();&lt;br /&gt;
  checkDlg.dialog({&lt;br /&gt;
    width: 700,&lt;br /&gt;
    height: 500,&lt;br /&gt;
    open: function () {&lt;br /&gt;
      // http://stackoverflow.com/questions/2929487/putting-a-jquery-ui-accordion-in-a-jquery-ui-dialog&lt;br /&gt;
      $('#accordion').accordion({&lt;br /&gt;
        autoHeight: true&lt;br /&gt;
      });&lt;br /&gt;
    }&lt;br /&gt;
  }); // show dialog&lt;br /&gt;
} // selfCheckDialog&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// show a simple configuration dialog (WIP)&lt;br /&gt;
function setupDialog() {&lt;br /&gt;
  //alert(&amp;quot;configuration dialog is not yet implemented&amp;quot;);&lt;br /&gt;
  var checked = (Host.get_persistent('debug_mode_enabled', false) === true) ? 'checked' : '';&lt;br /&gt;
  //dbLog(&amp;quot;value is:&amp;quot;+get_persistent(&amp;quot;debug_mode_enabled&amp;quot;));&lt;br /&gt;
  //dbLog(&amp;quot;persistent debug flag is:&amp;quot;+checked);&lt;br /&gt;
  var setupDiv = $('&amp;lt;div id=&amp;quot;setupDialog&amp;quot; title=&amp;quot;Setup dialog&amp;quot;&amp;gt;NOTE: this configuration dialog is still work-in-progress&amp;lt;/p&amp;gt;&amp;lt;label&amp;gt;&amp;lt;input id=&amp;quot;debugcb&amp;quot; type=&amp;quot;checkbox&amp;quot;' + checked + '&amp;gt;Enable Debug mode&amp;lt;/label&amp;gt;&amp;lt;p/&amp;gt;&amp;lt;div id=&amp;quot;progressbar&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;');&lt;br /&gt;
  setupDiv.click(function () {&lt;br /&gt;
    //alert(&amp;quot;changing persistent debug state&amp;quot;);&lt;br /&gt;
    Host.set_persistent('debug_mode_enabled', $('#debugcb').is(':checked'));&lt;br /&gt;
  });&lt;br /&gt;
  //MediaWiki editing stub, based on: https://www.mediawiki.org/wiki/API:Edit#Editing_via_Ajax&lt;br /&gt;
  //only added here to show some status info in the setup dialog&lt;br /&gt;
  Host.download('http://wiki.flightgear.org/api.php?action=query&amp;amp;prop=info|revisions&amp;amp;intoken=edit&amp;amp;rvprop=timestamp&amp;amp;titles=Main%20Page', function (response) {&lt;br /&gt;
    var message = 'FlightGear wiki login status (AJAX):';&lt;br /&gt;
    var status = response.statusText;&lt;br /&gt;
    var color = (status == 'OK') ? 'green' : 'red';&lt;br /&gt;
    Host.dbLog(message + status);&lt;br /&gt;
    var statusDiv = $('&amp;lt;p&amp;gt;' + message + status + '&amp;lt;/p&amp;gt;').css('color', color);&lt;br /&gt;
    setupDiv.append(statusDiv);&lt;br /&gt;
  });&lt;br /&gt;
  setupDiv.dialog();&lt;br /&gt;
} // setupDialog&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// this  can be used to download/cache $FG_ROOT/options.xml so that fgfs CLI arguments can be recognized and post-processed automatically&lt;br /&gt;
// which can help transforming postings correctly&lt;br /&gt;
function downloadOptionsXML() {&lt;br /&gt;
&lt;br /&gt;
  // download $FG_ROOT/options.xml&lt;br /&gt;
          Host.download(&amp;quot;https://sourceforge.net/p/flightgear/fgdata/ci/next/tree/options.xml?format=raw&amp;quot;, function(response) {&lt;br /&gt;
            var xml = response.responseText;&lt;br /&gt;
            var doc = Host.make_doc(xml, 'text/xml');&lt;br /&gt;
            // https://developer.mozilla.org/en-US/docs/Web/API/XPathResult&lt;br /&gt;
            var options = Host.eval_xpath(doc, '//*/option', XPathResult.ORDERED_NODE_SNAPSHOT_TYPE);&lt;br /&gt;
            &lt;br /&gt;
            // http://help.dottoro.com/ljgnejkp.php&lt;br /&gt;
            Host.dbLog(&amp;quot;Number of options found in options.xml:&amp;quot;+options.snapshotLength);&lt;br /&gt;
            &lt;br /&gt;
            // http://help.dottoro.com/ljtfvvpx.php&lt;br /&gt;
            &lt;br /&gt;
              // https://sourceforge.net/p/flightgear/fgdata/ci/next/tree/options.xml&lt;br /&gt;
              &lt;br /&gt;
            &lt;br /&gt;
          }); // end of options.xml download&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
} // downloadOptionsXML&lt;br /&gt;
&lt;br /&gt;
function getProfile(url=undefined) {&lt;br /&gt;
  &lt;br /&gt;
  if(url === undefined) &lt;br /&gt;
    url=window.location.href;&lt;br /&gt;
  else&lt;br /&gt;
    url=url;&lt;br /&gt;
  &lt;br /&gt;
  Host.dbLog(&amp;quot;getProfile call URL is:&amp;quot;+url);&lt;br /&gt;
  &lt;br /&gt;
  for (var profile in CONFIG) {&lt;br /&gt;
    if (url.match(CONFIG[profile].url_reg) !== null) {&lt;br /&gt;
      Host.dbLog('Matching website profile found');&lt;br /&gt;
      var invocations = Host.get_persistent(Host.getScriptVersion(), 0);&lt;br /&gt;
      Host.dbLog('Number of script invocations for version ' + Host.getScriptVersion() + ' is:' + invocations);&lt;br /&gt;
&lt;br /&gt;
      // determine if we want to show a config dialog&lt;br /&gt;
      if (invocations === 0) {&lt;br /&gt;
        Host.dbLog(&amp;quot;ask for config dialog to be shown&amp;quot;);&lt;br /&gt;
        var response = UI.confirm('This is your first time running version ' + Host.getScriptVersion() + '\nConfigure now?');&lt;br /&gt;
        if (response) {&lt;br /&gt;
                  &lt;br /&gt;
          // show configuration dialog (jQuery)&lt;br /&gt;
          setupDialog();&lt;br /&gt;
        } &lt;br /&gt;
        else {&lt;br /&gt;
        } // don't configure&lt;br /&gt;
&lt;br /&gt;
      }      &lt;br /&gt;
      &lt;br /&gt;
      // increment number of invocations, use the script's version number as the key, to prevent the config dialog from showing up again (except for updated scripts)&lt;br /&gt;
      // FIXME: this is triggered/incremented by each click ...&lt;br /&gt;
      Host.dbLog(&amp;quot;increment number of script invocations&amp;quot;);&lt;br /&gt;
      Host.set_persistent(Host.getScriptVersion(), invocations + 1);&lt;br /&gt;
      return CONFIG[profile];&lt;br /&gt;
    } // matched website profile&lt;br /&gt;
    Host.dbLog('Could not find matching URL in getProfile() call!');&lt;br /&gt;
  } // for each profile&lt;br /&gt;
}// Get the HTML code that is selected&lt;br /&gt;
&lt;br /&gt;
function getSelectedHtml() {&lt;br /&gt;
  // From http://stackoverflow.com/a/6668159&lt;br /&gt;
  var html = '',&lt;br /&gt;
  selection = document.getSelection();&lt;br /&gt;
  if (selection.rangeCount) {&lt;br /&gt;
    var container = document.createElement('div');&lt;br /&gt;
    for (var i = 0; i &amp;lt; selection.rangeCount; i++) {&lt;br /&gt;
      container.appendChild(selection.getRangeAt(i).cloneContents());&lt;br /&gt;
    }&lt;br /&gt;
    html = container.innerHTML;&lt;br /&gt;
  }&lt;br /&gt;
  Host.dbLog('instantCquote(): Unprocessed HTML\n\'' + html + '\'');&lt;br /&gt;
  return html;&lt;br /&gt;
}// Gets the selected text&lt;br /&gt;
&lt;br /&gt;
function getSelectedText() {&lt;br /&gt;
  return document.getSelection().toString();&lt;br /&gt;
}// Get the ID of the post&lt;br /&gt;
// (this needs some work so that it can be used by the AJAX mode, without an actual selection)&lt;br /&gt;
&lt;br /&gt;
function getPostId(selection, profile, focus) {&lt;br /&gt;
  if (focus !== undefined) {&lt;br /&gt;
    Host.dbLog(&amp;quot;Trying to get PostId with defined focus&amp;quot;);&lt;br /&gt;
    selection = selection.focusNode.parentNode;&lt;br /&gt;
  } else {&lt;br /&gt;
    Host.dbLog(&amp;quot;Trying to get PostId with undefined focus&amp;quot;);&lt;br /&gt;
    selection = selection.anchorNode.parentNode;&lt;br /&gt;
  }&lt;br /&gt;
  while (selection.id.match(profile.content.idStyle) === null) {&lt;br /&gt;
    selection = selection.parentNode;&lt;br /&gt;
  }&lt;br /&gt;
  Host.dbLog(&amp;quot;Selection id is:&amp;quot;+selection.id);&lt;br /&gt;
  return selection.id;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Checks that the selection is valid&lt;br /&gt;
function checkValid(selection, profile) {&lt;br /&gt;
  var ret = true,&lt;br /&gt;
  selection_cp = {&lt;br /&gt;
  },&lt;br /&gt;
  tags = profile.content.parentTag;&lt;br /&gt;
  for (var n = 0; n &amp;lt; 2; n++) {&lt;br /&gt;
    if (n === 0) {&lt;br /&gt;
      selection_cp = selection.anchorNode.parentNode;&lt;br /&gt;
    } else {&lt;br /&gt;
      selection_cp = selection.focusNode.parentNode;&lt;br /&gt;
    }&lt;br /&gt;
    while (true) {&lt;br /&gt;
      if (selection_cp.tagName === 'BODY') {&lt;br /&gt;
        ret = false;&lt;br /&gt;
        break;&lt;br /&gt;
      } else {&lt;br /&gt;
        var cont = false;&lt;br /&gt;
        for (var i = 0; i &amp;lt; tags.length; i++) {&lt;br /&gt;
          if (selection_cp[tags[0]] === tags[i]) {&lt;br /&gt;
            cont = true;&lt;br /&gt;
            break;&lt;br /&gt;
          }&lt;br /&gt;
        }&lt;br /&gt;
        if (cont) {&lt;br /&gt;
          break;&lt;br /&gt;
        } else {&lt;br /&gt;
          selection_cp = selection_cp.parentNode;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  ret = ret &amp;amp;&amp;amp; (getPostId(selection, profile) === getPostId(selection, profile, 1));&lt;br /&gt;
  return ret;&lt;br /&gt;
}// Extracts the raw text from a certain place, using an XPath&lt;br /&gt;
&lt;br /&gt;
function extractFieldInfo(profile, id, field) {&lt;br /&gt;
  &lt;br /&gt;
  if (field === 'content') {&lt;br /&gt;
    Host.dbLog(&amp;quot;Returning content (selection)&amp;quot;);&lt;br /&gt;
    return profile[field].selection();&lt;br /&gt;
  } else {&lt;br /&gt;
    Host.dbLog(&amp;quot;Extracting field via xpath:&amp;quot;+field);&lt;br /&gt;
    var xpath = '//*[@id=&amp;quot;' + id + '&amp;quot;]/' + profile[field].xpath;&lt;br /&gt;
    return Host.eval_xpath(document, xpath).stringValue; // document.evaluate(xpath, document, null, XPathResult.STRING_TYPE, null).stringValue;&lt;br /&gt;
  }&lt;br /&gt;
}// Change the text using specified transformations&lt;br /&gt;
&lt;br /&gt;
function applyTransformations(fieldInfo, trans) { &lt;br /&gt;
    for (var i = 0; i &amp;lt; trans.length; i++) {&lt;br /&gt;
      fieldInfo = trans[i](fieldInfo);&lt;br /&gt;
      Host.dbLog('applyTransformations(): Multiple transformation, transformation after loop #' + (i + 1) + ':\n\'' + fieldInfo + '\'');&lt;br /&gt;
    }&lt;br /&gt;
    return fieldInfo;&lt;br /&gt;
  &lt;br /&gt;
} //applyTransformations&lt;br /&gt;
&lt;br /&gt;
// Formats the quote&lt;br /&gt;
&lt;br /&gt;
function createCquote(data, indirect_speech=false) {&lt;br /&gt;
 if(!indirect_speech)&lt;br /&gt;
   return nonQuotedRef(data); // conventional/verbatim selection&lt;br /&gt;
  else { &lt;br /&gt;
    // pattern match the content using a vector of regexes&lt;br /&gt;
    data.content = transformSpeech(data.content, data.author, null, speechTransformations );&lt;br /&gt;
    return nonQuotedRef(data);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function nonQuotedRef(data) { //TODO: rename &lt;br /&gt;
  var template = Host.getTemplate();&lt;br /&gt;
  &lt;br /&gt;
  var substituted = template&lt;br /&gt;
  .replace('$CONTENT', data.content)&lt;br /&gt;
  .replace('$URL',data.url)&lt;br /&gt;
  .replace('$TITLE',data.title)  &lt;br /&gt;
  .replace('$AUTHOR',data.author)&lt;br /&gt;
  .replace('$DATE',datef(data.date))&lt;br /&gt;
  .replace('$ADDED',datef(data.date))&lt;br /&gt;
  .replace('$SCRIPT_VERSION', Host.getScriptVersion() );&lt;br /&gt;
  &lt;br /&gt;
  return substituted; &lt;br /&gt;
}// &lt;br /&gt;
&lt;br /&gt;
// Output the text.&lt;br /&gt;
// Tries the jQuery dialog, and falls back to window.prompt()&lt;br /&gt;
&lt;br /&gt;
function outputText(msg, original) {&lt;br /&gt;
  try {&lt;br /&gt;
    OUTPUT.jQueryTabbed(msg, original); &lt;br /&gt;
  } &lt;br /&gt;
  catch (err) {&lt;br /&gt;
    msg = msg.replace(/&amp;amp;lt;\/syntaxhighligh(.)&amp;gt;/g, '&amp;lt;/syntaxhighligh$1');&lt;br /&gt;
    OUTPUT.msgbox(msg);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// #############&lt;br /&gt;
// # Utilities #&lt;br /&gt;
// #############&lt;br /&gt;
&lt;br /&gt;
function extract(regex) {&lt;br /&gt;
  return function (text) {&lt;br /&gt;
    return text.match(regex) [1];&lt;br /&gt;
  };&lt;br /&gt;
}&lt;br /&gt;
function prepend(prefix) {&lt;br /&gt;
  return function (text) {&lt;br /&gt;
    return prefix + text;&lt;br /&gt;
  };&lt;br /&gt;
}&lt;br /&gt;
function removeComments(html) {&lt;br /&gt;
  return html.replace(/&amp;lt;!--.*?--&amp;gt;/g, '');&lt;br /&gt;
}// Not currently used (as of June 2015), but kept just in case&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// currently unused&lt;br /&gt;
function escapePipes(html) {&lt;br /&gt;
  html = html.replace(/\|\|/g, '{{!!}n}');&lt;br /&gt;
  html = html.replace(/\|\-/g, '{{!-}}');&lt;br /&gt;
  return html.replace(/\|/g, '{{!}}');&lt;br /&gt;
}// Converts HTML &amp;lt;a href=&amp;quot;...&amp;quot;&amp;gt;...&amp;lt;/a&amp;gt; tags to wiki links, internal if possible.&lt;br /&gt;
&lt;br /&gt;
function a2wikilink(html) {&lt;br /&gt;
  // Links to wiki images, because&lt;br /&gt;
  // they need special treatment, or else they get displayed.&lt;br /&gt;
  html = html.replace(/&amp;lt;a.*?href=&amp;quot;http:\/\/wiki\.flightgear\.org\/File:(.*?)&amp;quot;.*?&amp;gt;(.*?)&amp;lt;\/a&amp;gt;/g, '[[Media:$1|$2]]');&lt;br /&gt;
  // Wiki links without custom text.&lt;br /&gt;
  html = html.replace(/&amp;lt;a.*?href=&amp;quot;http:\/\/wiki\.flightgear\.org\/(.*?)&amp;quot;.*?&amp;gt;http:\/\/wiki\.flightgear\.org\/.*?&amp;lt;\/a&amp;gt;/g, '[[$1]]');&lt;br /&gt;
  // Links to the wiki with custom text&lt;br /&gt;
  html = html.replace(/&amp;lt;a.*?href=&amp;quot;http:\/\/wiki\.flightgear\.org\/(.*?)&amp;quot;.*?&amp;gt;(.*?)&amp;lt;\/a&amp;gt;/g, '[[$1|$2]]');&lt;br /&gt;
  // Remove underscores from all wiki links&lt;br /&gt;
  var list = html.match(/\[\[.*?\]\]/g);&lt;br /&gt;
  if (list !== null) {&lt;br /&gt;
    for (var i = 0; i &amp;lt; list.length; i++) {&lt;br /&gt;
      html = html.replace(list[i], underscore2Space(list[i]));&lt;br /&gt;
    }&lt;br /&gt;
  }  // Convert non-wiki links&lt;br /&gt;
  // TODO: identify forum/devel list links, and use the AJAX/Host.download helper to get a title/subject for unnamed links (using the existing xpath/regex helpers for that)&lt;br /&gt;
&lt;br /&gt;
  html = html.replace(/&amp;lt;a.*?href=&amp;quot;(.*?)&amp;quot;.*?&amp;gt;(.*?)&amp;lt;\/a&amp;gt;/g, '[$1 $2]');&lt;br /&gt;
  // Remove triple dots from external links.&lt;br /&gt;
  // Replace with raw URL (MediaWiki converts it to a link).&lt;br /&gt;
  list = html.match(/\[.*?(\.\.\.).*?\]/g);&lt;br /&gt;
  if (list !== null) {&lt;br /&gt;
    for (var i = 0; i &amp;lt; list.length; i++) {&lt;br /&gt;
      html = html.replace(list[i], list[i].match(/\[(.*?) .*?\]/) [1]);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return html;&lt;br /&gt;
}// Converts images, including images in &amp;lt;a&amp;gt; links&lt;br /&gt;
&lt;br /&gt;
function img2link(html) {&lt;br /&gt;
  html = html.replace(/&amp;lt;a[^&amp;lt;]*?href=&amp;quot;([^&amp;lt;]*?)&amp;quot;[^&amp;lt;]*?&amp;gt;&amp;lt;img.*?src=&amp;quot;http:\/\/wiki\.flightgear\.org\/images\/.*?\/.*?\/(.*?)&amp;quot;.*?&amp;gt;&amp;lt;\/a&amp;gt;/g, '[[File:$2|250px|link=$1]]');&lt;br /&gt;
  html = html.replace(/&amp;lt;img.*?src=&amp;quot;http:\/\/wiki\.flightgear\.org\/images\/.*?\/.*?\/(.*?)&amp;quot;.*?&amp;gt;/g, '[[File:$1|250px]]');&lt;br /&gt;
  html = html.replace(/&amp;lt;a[^&amp;lt;]*?href=&amp;quot;([^&amp;lt;]*?)&amp;quot;[^&amp;lt;]*?&amp;gt;&amp;lt;img.*?src=&amp;quot;(.*?)&amp;quot;.*?&amp;gt;&amp;lt;\/a&amp;gt;/g, '(see [$2 image], links to [$1 here])');&lt;br /&gt;
  return html.replace(/&amp;lt;img.*?src=&amp;quot;(.*?)&amp;quot;.*?&amp;gt;/g, '(see the [$1 linked image])');&lt;br /&gt;
}// Converts smilies&lt;br /&gt;
&lt;br /&gt;
function forum_smilies2text(html) {&lt;br /&gt;
  html = html.replace(/&amp;lt;img src=&amp;quot;\.\/images\/smilies\/icon_.*?\.gif&amp;quot; alt=&amp;quot;(.*?)&amp;quot;.*?&amp;gt;/g, '$1');&lt;br /&gt;
  for (var i = 0; i &amp;lt; EMOTICONS.length; i++) {&lt;br /&gt;
    html = html.replace(EMOTICONS[i][0], EMOTICONS[i][1]);&lt;br /&gt;
  }&lt;br /&gt;
  return html;&lt;br /&gt;
}// Converts font formatting&lt;br /&gt;
&lt;br /&gt;
function forum_fontstyle2wikistyle(html) {&lt;br /&gt;
  html = html.replace(/&amp;lt;span style=&amp;quot;font-weight: bold&amp;quot;&amp;gt;(.*?)&amp;lt;\/span&amp;gt;/g, '\'\'\'$1\'\'\'');&lt;br /&gt;
  html = html.replace(/&amp;lt;span style=&amp;quot;text-decoration: underline&amp;quot;&amp;gt;(.*?)&amp;lt;\/span&amp;gt;/g, '&amp;lt;u&amp;gt;$1&amp;lt;/u&amp;gt;');&lt;br /&gt;
  html = html.replace(/&amp;lt;span style=&amp;quot;font-style: italic&amp;quot;&amp;gt;(.*?)&amp;lt;\/span&amp;gt;/g, '\'\'$1\'\'');&lt;br /&gt;
  return html.replace(/&amp;lt;span class=&amp;quot;posthilit&amp;quot;&amp;gt;(.*?)&amp;lt;\/span&amp;gt;/g, '$1');&lt;br /&gt;
}// Converts code blocks&lt;br /&gt;
&lt;br /&gt;
function forum_code2syntaxhighlight(html) {&lt;br /&gt;
  var list = html.match(/&amp;lt;dl class=&amp;quot;codebox&amp;quot;&amp;gt;.*?&amp;lt;code&amp;gt;(.*?)&amp;lt;\/code&amp;gt;.*?&amp;lt;\/dl&amp;gt;/g),&lt;br /&gt;
  data = [&lt;br /&gt;
  ];&lt;br /&gt;
  if (list === null) return html;&lt;br /&gt;
  for (var n = 0; n &amp;lt; list.length; n++) {&lt;br /&gt;
    data = html.match(/&amp;lt;dl class=&amp;quot;codebox&amp;quot;&amp;gt;.*?&amp;lt;code&amp;gt;(.*?)&amp;lt;\/code&amp;gt;.*?&amp;lt;\/dl&amp;gt;/);&lt;br /&gt;
    html = html.replace(data[0], processCode(data));&lt;br /&gt;
  }&lt;br /&gt;
  return html;&lt;br /&gt;
}// Strips any whitespace from the beginning and end of a string&lt;br /&gt;
&lt;br /&gt;
function stripWhitespace(html) {&lt;br /&gt;
  html = html.replace(/^\s*?(\S)/, '$1');&lt;br /&gt;
  return html.replace(/(\S)\s*?\z/, '$1');&lt;br /&gt;
}// Process code, including basic detection of language&lt;br /&gt;
&lt;br /&gt;
function processCode(data) {&lt;br /&gt;
  var lang = '',&lt;br /&gt;
  code = data[1];&lt;br /&gt;
  code = code.replace(/&amp;amp;nbsp;/g, ' ');&lt;br /&gt;
  if (code.match(/=?.*?\(?.*?\)?;/) !== null) lang = 'nasal';&lt;br /&gt;
  if (code.match(/&amp;amp;lt;.*?&amp;amp;gt;.*?&amp;amp;lt;\/.*?&amp;amp;gt;/) !== null || code.match(/&amp;amp;lt;!--.*?--&amp;amp;gt;/) !== null) lang = 'xml';&lt;br /&gt;
  code = code.replace(/&amp;lt;br\/?&amp;gt;/g, '\n');&lt;br /&gt;
  return '&amp;lt;syntaxhighlight lang=&amp;quot;' + lang + '&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;\n' + code + '\n&amp;amp;lt;/syntaxhighlight&amp;gt;';&lt;br /&gt;
}// Converts quote blocks to Cquotes&lt;br /&gt;
&lt;br /&gt;
function forum_quote2cquote(html) {&lt;br /&gt;
  html = html.replace(/&amp;lt;blockquote class=&amp;quot;uncited&amp;quot;&amp;gt;&amp;lt;div&amp;gt;(.*?)&amp;lt;\/div&amp;gt;&amp;lt;\/blockquote&amp;gt;/g, '{{cquote|$1}}');&lt;br /&gt;
  if (html.match(/&amp;lt;blockquote&amp;gt;/g) === null) return html;&lt;br /&gt;
  var numQuotes = html.match(/&amp;lt;blockquote&amp;gt;/g).length;&lt;br /&gt;
  for (var n = 0; n &amp;lt; numQuotes; n++) {&lt;br /&gt;
    html = html.replace(/&amp;lt;blockquote&amp;gt;&amp;lt;div&amp;gt;&amp;lt;cite&amp;gt;(.*?) wrote.*?:&amp;lt;\/cite&amp;gt;(.*?)&amp;lt;\/div&amp;gt;&amp;lt;\/blockquote&amp;gt;/, '{{cquote|$2|$1}}');&lt;br /&gt;
  }&lt;br /&gt;
  return html;&lt;br /&gt;
}// Converts videos to wiki style&lt;br /&gt;
&lt;br /&gt;
function vid2wiki(html) {&lt;br /&gt;
  // YouTube&lt;br /&gt;
  html = html.replace(/&amp;lt;div class=&amp;quot;video-wrapper&amp;quot;&amp;gt;\s.*?&amp;lt;div class=&amp;quot;video-container&amp;quot;&amp;gt;\s*?&amp;lt;iframe class=&amp;quot;youtube-player&amp;quot;.*?width=&amp;quot;(.*?)&amp;quot; height=&amp;quot;(.*?)&amp;quot; src=&amp;quot;http:\/\/www\.youtube\.com\/embed\/(.*?)&amp;quot;.*?&amp;gt;&amp;lt;\/iframe&amp;gt;\s*?&amp;lt;\/div&amp;gt;\s*?&amp;lt;\/div&amp;gt;/g, '{{#ev:youtube|$3|$1x$2}}');&lt;br /&gt;
  // Vimeo&lt;br /&gt;
  html = html.replace(/&amp;lt;iframe src=&amp;quot;http:\/\/player\.vimeo\.com\/video\/(.*?)\?.*?&amp;quot; width=&amp;quot;(.*?)&amp;quot; height=&amp;quot;(.*?)&amp;quot;.*?&amp;gt;.*?&amp;lt;\/iframe&amp;gt;/g, '{{#ev:vimeo|$1|$2x$3}}');&lt;br /&gt;
  return html.replace(/\[.*? Watch on Vimeo\]/g, '');&lt;br /&gt;
}// Not currently used (as of June 2015), but kept just in case&lt;br /&gt;
&lt;br /&gt;
// currently unused&lt;br /&gt;
function escapeEquals(html) {&lt;br /&gt;
  return html.replace(/=/g, '{{=}}');&lt;br /&gt;
}// &amp;lt;br&amp;gt; to newline.&lt;br /&gt;
&lt;br /&gt;
function forum_br2newline(html) {&lt;br /&gt;
  html = html.replace(/&amp;lt;br\/?&amp;gt;&amp;lt;br\/?&amp;gt;/g, '\n');&lt;br /&gt;
  return html.replace(/&amp;lt;br\/?&amp;gt;/g, '\n\n');&lt;br /&gt;
}// Forum list to wiki style&lt;br /&gt;
&lt;br /&gt;
function list2wiki(html) {&lt;br /&gt;
  var list = html.match(/&amp;lt;ul&amp;gt;(.*?)&amp;lt;\/ul&amp;gt;/g);&lt;br /&gt;
  if (list !== null) {&lt;br /&gt;
    for (var i = 0; i &amp;lt; list.length; i++) {&lt;br /&gt;
      html = html.replace(/&amp;lt;li&amp;gt;(.*?)&amp;lt;\/li&amp;gt;/g, '* $1\n');&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  list = html.match(/&amp;lt;ol.*?&amp;gt;(.*?)&amp;lt;\/ol&amp;gt;/g);&lt;br /&gt;
  if (list !== null) {&lt;br /&gt;
    for (var i = 0; i &amp;lt; list.length; i++) {&lt;br /&gt;
      html = html.replace(/&amp;lt;li&amp;gt;(.*?)&amp;lt;\/li&amp;gt;/g, '# $1\n');&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  html = html.replace(/&amp;lt;\/?[uo]l&amp;gt;/g, '');&lt;br /&gt;
  return html;&lt;br /&gt;
}&lt;br /&gt;
function nowiki(text) {&lt;br /&gt;
  return '&amp;lt;nowiki&amp;gt;' + text + '&amp;lt;/nowiki&amp;gt;';&lt;br /&gt;
}// Returns the correct ordinal adjective&lt;br /&gt;
&lt;br /&gt;
function ordAdj(date) {&lt;br /&gt;
  date = date.toString();&lt;br /&gt;
  if (date == '11' || date == '12' || date == '13') {&lt;br /&gt;
    return 'th';&lt;br /&gt;
  } else if (date.substr(1) == '1' || date == '1') {&lt;br /&gt;
    return 'st';&lt;br /&gt;
  } else if (date.substr(1) == '2' || date == '2') {&lt;br /&gt;
    return 'nd';&lt;br /&gt;
  } else if (date.substr(1) == '3' || date == '3') {&lt;br /&gt;
    return 'rd';&lt;br /&gt;
  } else {&lt;br /&gt;
    return 'th';&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Formats the date to this format: Apr 26th, 2015&lt;br /&gt;
function datef(text) {&lt;br /&gt;
  var date = new Date(text);&lt;br /&gt;
  return MONTHS[date.getMonth()] + ' ' + date.getDate() + ordAdj(date.getDate()) + ', ' + date.getFullYear();&lt;br /&gt;
}&lt;br /&gt;
function underscore2Space(str) {&lt;br /&gt;
  return str.replace(/_/g, ' ');&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// IGNORE EVERYTHING THAT FOLLOWS: &lt;br /&gt;
// This is an experiment to use GA/GP (genetic programming) to help procedurally evolve xpath and regex expressions if/when the underlying websites change&lt;br /&gt;
// so that we don't have to manually update/edit the script accordingly (this would also work for mobile themes etc)&lt;br /&gt;
// For now, this is heavily based on the genetic.js framework/examples: http://subprotocol.com/system/genetic-hello-world.html&lt;br /&gt;
// The idea is to evolve the xpath/regex expression by evaluating its return value against the expected/desired value&lt;br /&gt;
// the most important thing here is having a suitable fitness function&lt;br /&gt;
// &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function evolve_expression_test() {&lt;br /&gt;
  &lt;br /&gt;
try {  &lt;br /&gt;
var genetic = Genetic.create();&lt;br /&gt;
&lt;br /&gt;
// TODO: use minimizer: redundant_bytes + duration_msec + xpath.length&lt;br /&gt;
genetic.optimize = Genetic.Optimize.Maximize;&lt;br /&gt;
genetic.select1 = Genetic.Select1.Tournament2;&lt;br /&gt;
genetic.select2 = Genetic.Select2.Tournament2;&lt;br /&gt;
 &lt;br /&gt;
   &lt;br /&gt;
genetic.seed = function() {&lt;br /&gt;
&lt;br /&gt;
    function randomString(len) {&lt;br /&gt;
        var text = &amp;quot;&amp;quot;;&lt;br /&gt;
        var charset = &amp;quot;\\abcdefghijklmnopqrstuvwxyz0123456789[] ()&amp;lt;&amp;gt;*.,&amp;quot;;&lt;br /&gt;
        for(var i=0;i&amp;lt;len;i++)&lt;br /&gt;
            text += charset.charAt(Math.floor(Math.random() * charset.length));&lt;br /&gt;
        &lt;br /&gt;
        return text; // &amp;quot;From:&amp;amp;(.*)$&amp;lt;.*8.*&amp;gt;&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // create random strings that are equal in length to solution&lt;br /&gt;
    return randomString( this.userData[&amp;quot;solution&amp;quot;].length);&lt;br /&gt;
};&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
genetic.mutate = function(entity) {&lt;br /&gt;
    &lt;br /&gt;
    function replaceAt(str, index, character) {&lt;br /&gt;
        return str.substr(0, index) + character + str.substr(index+character.length);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // chromosomal drift&lt;br /&gt;
    var i = Math.floor(Math.random()*entity.length);&lt;br /&gt;
    return replaceAt(entity, i, String.fromCharCode(entity.charCodeAt(i) + (Math.floor(Math.random()*2) ? 1 : -1)));&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
genetic.crossover = function(mother, father) {&lt;br /&gt;
&lt;br /&gt;
    // two-point crossover&lt;br /&gt;
    var len = mother.length;&lt;br /&gt;
    var ca = Math.floor(Math.random()*len);&lt;br /&gt;
    var cb = Math.floor(Math.random()*len);     &lt;br /&gt;
    if (ca &amp;gt; cb) {&lt;br /&gt;
        var tmp = cb;&lt;br /&gt;
        cb = ca;&lt;br /&gt;
        ca = tmp;&lt;br /&gt;
    }&lt;br /&gt;
        &lt;br /&gt;
    var son = father.substr(0,ca) + mother.substr(ca, cb-ca) + father.substr(cb);&lt;br /&gt;
    var daughter = mother.substr(0,ca) + father.substr(ca, cb-ca) + mother.substr(cb);&lt;br /&gt;
    &lt;br /&gt;
    return [son, daughter];&lt;br /&gt;
};&lt;br /&gt;
    &lt;br /&gt;
genetic.determineExcessBytes = function (text, needle) {&lt;br /&gt;
    return text.length - needle.length;&lt;br /&gt;
};&lt;br /&gt;
    &lt;br /&gt;
genetic.containsText = function (text, needle) {&lt;br /&gt;
    return text.search(needle);&lt;br /&gt;
};&lt;br /&gt;
  &lt;br /&gt;
genetic.isValid = function(exp) {&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
    &lt;br /&gt;
/* myFitness:&lt;br /&gt;
 * - must be a valid xpath/regex expression (try/call)&lt;br /&gt;
 * - must containsText the needle&lt;br /&gt;
 * - low relative offset in text (begin/end)&lt;br /&gt;
 * - excessBytes&lt;br /&gt;
 * - short expression  (expression length)&lt;br /&gt;
 * - expression footprint (runtime)&lt;br /&gt;
 */ &lt;br /&gt;
&lt;br /&gt;
// TODO: the fitness function should validate each xpath/regex first&lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
genetic.fitness = function(entity) {&lt;br /&gt;
    var fitness = 0;&lt;br /&gt;
    var result;&lt;br /&gt;
    var validExp = 0.1;&lt;br /&gt;
    var hasToken = 0.1;&lt;br /&gt;
   &lt;br /&gt;
  &lt;br /&gt;
    var t = this.userData.tests[0].haystack;&lt;br /&gt;
    //var regex = new RegExp(this.userData.solution);&lt;br /&gt;
    //var output = t.match( new RegExp(&amp;quot;From: (.*) &amp;lt;.*@.*&amp;gt;&amp;quot;))[1];  &lt;br /&gt;
    // TODO: use search &amp;amp; match for improving the fitness&lt;br /&gt;
  &lt;br /&gt;
    if (0)  &lt;br /&gt;
    try {&lt;br /&gt;
    var regex = new RegExp(entity);&lt;br /&gt;
    var output = t.search( regex);&lt;br /&gt;
    validExp = 5;&lt;br /&gt;
    //if (output) validExp = 50;&lt;br /&gt;
    }&lt;br /&gt;
    catch(e) {&lt;br /&gt;
    //validExp = 2;    &lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
   &lt;br /&gt;
    &lt;br /&gt;
    var i;&lt;br /&gt;
    for (i=0;i&amp;lt;entity.length;++i) {&lt;br /&gt;
        // increase fitness for each character that matches&lt;br /&gt;
        if (entity[i] == this.userData[&amp;quot;solution&amp;quot;][i])&lt;br /&gt;
            fitness += 1;&lt;br /&gt;
        &lt;br /&gt;
        // award fractions of a point as we get warmer&lt;br /&gt;
        fitness += (127-Math.abs(entity.charCodeAt(i) - this.userData[&amp;quot;solution&amp;quot;].charCodeAt(i)))/50;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
    return fitness + (1*validExp + 1* hasToken);&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
genetic.generation = function(pop, generation, stats) {&lt;br /&gt;
    // stop running once we've reached the solution&lt;br /&gt;
    return pop[0].entity != this.userData[&amp;quot;solution&amp;quot;];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
genetic.notification = function(pop, generation, stats, isFinished) {&lt;br /&gt;
&lt;br /&gt;
    function lerp(a, b, p) {&lt;br /&gt;
        return a + (b-a)*p;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    var value = pop[0].entity;&lt;br /&gt;
    this.last = this.last||value;&lt;br /&gt;
    &lt;br /&gt;
    if (pop != 0 &amp;amp;&amp;amp; value == this.last)&lt;br /&gt;
        return;&lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
    var solution = [];&lt;br /&gt;
    var i;&lt;br /&gt;
    for (i=0;i&amp;lt;value.length;++i) {&lt;br /&gt;
        var diff = value.charCodeAt(i) - this.last.charCodeAt(i);&lt;br /&gt;
        var style = &amp;quot;background: transparent;&amp;quot;;&lt;br /&gt;
        if (diff &amp;gt; 0) {&lt;br /&gt;
            style = &amp;quot;background: rgb(0,200,50); color: #fff;&amp;quot;;&lt;br /&gt;
        } else if (diff &amp;lt; 0) {&lt;br /&gt;
            style = &amp;quot;background: rgb(0,100,50); color: #fff;&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        solution.push(&amp;quot;&amp;lt;span style=\&amp;quot;&amp;quot; + style + &amp;quot;\&amp;quot;&amp;gt;&amp;quot; + value[i] + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
    var t = this.userData.tests[0].haystack;&lt;br /&gt;
    //console.log(&amp;quot;haystack is:&amp;quot;+t);&lt;br /&gt;
    // &amp;quot;From: John Doe &amp;lt;John@do...&amp;gt; - 2020-07-02 17:36:03&amp;quot;, needle: &amp;quot;John Doe&amp;quot;}, /From: (.*) &amp;lt;.*@.*&amp;gt;/&lt;br /&gt;
    var regex = new RegExp(this.userData.solution);&lt;br /&gt;
    //var output = t.match( new RegExp(&amp;quot;From: (.*) &amp;lt;.*@.*&amp;gt;&amp;quot;))[1];  &lt;br /&gt;
    // TODO: use search &amp;amp; match for improving the fitness&lt;br /&gt;
    var output = t.search( new RegExp(value));&lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
    var buf = &amp;quot;&amp;quot;;&lt;br /&gt;
    buf += &amp;quot;&amp;lt;tr&amp;gt;&amp;quot;;&lt;br /&gt;
    buf += &amp;quot;&amp;lt;td&amp;gt;&amp;quot; + generation + &amp;quot;&amp;lt;/td&amp;gt;&amp;quot;;&lt;br /&gt;
    buf += &amp;quot;&amp;lt;td&amp;gt;&amp;quot; + pop[0].fitness.toPrecision(5) + &amp;quot;&amp;lt;/td&amp;gt;&amp;quot;;&lt;br /&gt;
    buf += &amp;quot;&amp;lt;td&amp;gt;&amp;quot; + solution.join(&amp;quot;&amp;quot;) + &amp;quot;&amp;lt;/td&amp;gt;&amp;quot;;&lt;br /&gt;
    buf += &amp;quot;&amp;lt;td&amp;gt;&amp;quot; + output + &amp;quot;&amp;lt;/td&amp;gt;&amp;quot;;&lt;br /&gt;
    buf += &amp;quot;&amp;lt;/tr&amp;gt;&amp;quot;;&lt;br /&gt;
    $(&amp;quot;#results tbody&amp;quot;).prepend(buf);&lt;br /&gt;
    &lt;br /&gt;
    this.last = value;&lt;br /&gt;
};&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  /*&lt;br /&gt;
genetic.notification2 = function(pop, generation, stats, isFinished) {&lt;br /&gt;
&lt;br /&gt;
    function lerp(a, b, p) {&lt;br /&gt;
        return a + (b-a)*p;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    var value = pop[0].entity;&lt;br /&gt;
    this.last = this.last||value;&lt;br /&gt;
    &lt;br /&gt;
    if (pop != 0 &amp;amp;&amp;amp; value == this.last)&lt;br /&gt;
        return;&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    var solution = [];&lt;br /&gt;
    var i;&lt;br /&gt;
    for (i=0;i&amp;lt;value.length;++i) {&lt;br /&gt;
    &lt;br /&gt;
    solution.push(value[i]);&lt;br /&gt;
 } &lt;br /&gt;
    console.log(&amp;quot;Generation:&amp;quot;+ generation + &amp;quot; Fitness:&amp;quot; + pop[0].fitness.toPrecision(5) + &amp;quot; Solution:&amp;quot; + solution.join(&amp;quot;&amp;quot;));&lt;br /&gt;
  &lt;br /&gt;
    this.last = value;&lt;br /&gt;
};&lt;br /&gt;
  */&lt;br /&gt;
    &lt;br /&gt;
      &lt;br /&gt;
var config = {&lt;br /&gt;
            &amp;quot;iterations&amp;quot;: 4000&lt;br /&gt;
            , &amp;quot;size&amp;quot;: 250&lt;br /&gt;
            , &amp;quot;crossover&amp;quot;: 0.3&lt;br /&gt;
            , &amp;quot;mutation&amp;quot;: 0.4&lt;br /&gt;
            , &amp;quot;skip&amp;quot;: 30 // notifications&lt;br /&gt;
            //, &amp;quot;webWorkers&amp;quot;: false&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
var profile = CONFIG['Sourceforge Mailing list'];&lt;br /&gt;
var posting = profile.tests[0];&lt;br /&gt;
var author_xpath = profile.title.xpath;&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
var regexTests = [&lt;br /&gt;
  {haystack: &amp;quot;From: John Doe &amp;lt;John@do...&amp;gt; - 2020-07-02 17:36:03&amp;quot;, needle: &amp;quot;John Doe&amp;quot;}, &lt;br /&gt;
  {haystack: &amp;quot;From: Marc Twain &amp;lt;Marc@ta...&amp;gt; - 2010-01-03 07:36:03&amp;quot;, needle: &amp;quot;Marc Twain&amp;quot;},&lt;br /&gt;
  {haystack: &amp;quot;From: George W. Bush &amp;lt;GWB@wh...&amp;gt; - 2055-11-11 17:33:13&amp;quot;, needle: &amp;quot;George W. Bush&amp;quot;}&lt;br /&gt;
];&lt;br /&gt;
  &lt;br /&gt;
// the regex we want to evolve&lt;br /&gt;
var solution = &amp;quot;From: (.*) &amp;lt;.*@.*&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// let's assume, we'd like to evolve a regex expression like this one&lt;br /&gt;
var userData = {&lt;br /&gt;
            solution: solution,&lt;br /&gt;
            tests: regexTests                         &lt;br /&gt;
};    &lt;br /&gt;
    &lt;br /&gt;
genetic.evolve(config, userData);&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
//console.log(&amp;quot;genetic.js is loaded and working, but disabled for now&amp;quot;);    &lt;br /&gt;
    &lt;br /&gt;
  &lt;br /&gt;
} // try&lt;br /&gt;
catch (e) {&lt;br /&gt;
  console.log(&amp;quot;genetic.js error:\n&amp;quot; +e.message);&lt;br /&gt;
} // catch&lt;br /&gt;
  &lt;br /&gt;
} // evolveExpression_test()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if(0) //TODO: expose via development tab&lt;br /&gt;
try {&lt;br /&gt;
  // https://github.com/cazala/synaptic&lt;br /&gt;
  var Neuron = synaptic.Neuron,&lt;br /&gt;
    Layer = synaptic.Layer,&lt;br /&gt;
    Network = synaptic.Network,&lt;br /&gt;
    Trainer = synaptic.Trainer,&lt;br /&gt;
    Architect = synaptic.Architect;&lt;br /&gt;
  &lt;br /&gt;
  function Perceptron(input, hidden, output)&lt;br /&gt;
{&lt;br /&gt;
    // create the layers&lt;br /&gt;
    var inputLayer = new Layer(input);&lt;br /&gt;
    var hiddenLayer = new Layer(hidden);&lt;br /&gt;
    var outputLayer = new Layer(output);&lt;br /&gt;
&lt;br /&gt;
    // connect the layers&lt;br /&gt;
    inputLayer.project(hiddenLayer);&lt;br /&gt;
    hiddenLayer.project(outputLayer);&lt;br /&gt;
&lt;br /&gt;
    // set the layers&lt;br /&gt;
    this.set({&lt;br /&gt;
        input: inputLayer,&lt;br /&gt;
        hidden: [hiddenLayer],&lt;br /&gt;
        output: outputLayer&lt;br /&gt;
    });&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// extend the prototype chain&lt;br /&gt;
Perceptron.prototype = new Network();&lt;br /&gt;
Perceptron.prototype.constructor = Perceptron;&lt;br /&gt;
  &lt;br /&gt;
var myPerceptron = new Perceptron(2,3,1);&lt;br /&gt;
var myTrainer = new Trainer(myPerceptron);&lt;br /&gt;
&lt;br /&gt;
myTrainer.XOR(); // { error: 0.004998819355993572, iterations: 21871, time: 356 }&lt;br /&gt;
&lt;br /&gt;
myPerceptron.activate([0,0]); // 0.0268581547421616&lt;br /&gt;
myPerceptron.activate([1,0]); // 0.9829673642853368&lt;br /&gt;
myPerceptron.activate([0,1]); // 0.9831714267395621&lt;br /&gt;
myPerceptron.activate([1,1]); // 0.02128894618097928&lt;br /&gt;
  &lt;br /&gt;
   &lt;br /&gt;
console.log(&amp;quot;Syntaptic loaded&amp;quot;);&lt;br /&gt;
} catch(e) {&lt;br /&gt;
  UI.alert(e.message);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Appendix}}&lt;/div&gt;</summary>
		<author><name>Elgaton</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=FlightGear_wiki:Instant-Refs&amp;diff=98421</id>
		<title>FlightGear wiki:Instant-Refs</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=FlightGear_wiki:Instant-Refs&amp;diff=98421"/>
		<updated>2016-05-20T12:19:30Z</updated>

		<summary type="html">&lt;p&gt;Elgaton: /* Background and motivation */ Remove duplicate reference&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Quotes-logo-200x200.png|thumb]]&lt;br /&gt;
[[File:Instant-cquotes-firefox.png|thumb|Instant-Cquotes script in Firefox]]&lt;br /&gt;
&lt;br /&gt;
[[File:Ref-only-quotes.png|thumb|Instant-Cquotes screenshot prototyping runtime format selection]]&lt;br /&gt;
&lt;br /&gt;
The '''Instant-Cquotes''' script is a browser addon (user script) implemented in JavaScript in order to convert excerpts (created via copy&amp;amp;paste) from FlightGear forum or [[mailing list]] postings into MediaWiki markup/quotes to be used on the FlightGear wiki. It is supported by Firefox, Google Chrome/Chromium, Opera and Safari. It is being developed and maintained by a group of volunteers involved in maintaining the wiki and in trying to provide more up-to-date information to end-users who may not be as involved in the various FlightGear-related communication channels.&lt;br /&gt;
&lt;br /&gt;
== Background and motivation ==&lt;br /&gt;
FlightGear's development is, at best, &amp;quot;self-coordinated&amp;quot;, meaning that contributors discuss ideas and make proposals to contribute in a certain fashion and then team up to implement certain features and building blocks, often just temporarily.&lt;br /&gt;
&lt;br /&gt;
Unfortunately, due to a lack of development manpower, many ideas are not implemented immediately; it is, thus, important to know their pros and cons, as well as who originally proposed them and/or might help with their implementation, even after a long time, preferably with links to the original discussions so that new contributors can decide whether to get involved in some effort or not. The project documentation, however, is in great need of improvement&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
| url    = http://sourceforge.net/p/flightgear/mailman/message/15444440/&lt;br /&gt;
| title  = &amp;lt;nowiki&amp;gt;[Flightgear-devel] development process (was:  chaos...)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| author = &amp;lt;nowiki&amp;gt;John Denker&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| date   = Jul 16th, 2007&lt;br /&gt;
| added   = Jul 16th, 2007&lt;br /&gt;
| script_version = 0.23&lt;br /&gt;
}}&amp;lt;/ref&amp;gt; and usually significantly lacking behind:&amp;lt;ref name=&amp;quot;OlsonStateThingsFG&amp;quot;&amp;gt;{{cite web&lt;br /&gt;
| url    = http://sourceforge.net/p/flightgear/mailman/message/27861667/&lt;br /&gt;
| title  = &amp;lt;nowiki&amp;gt;Re: [Flightgear-devel] The state of things in Flight Gear&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| author = &amp;lt;nowiki&amp;gt;Curtis Olson&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| date   = Jul 27th, 2011&lt;br /&gt;
| added   = Jul 27th, 2011&lt;br /&gt;
| script_version = 0.23&lt;br /&gt;
}}&amp;lt;/ref&amp;gt; many core developers update it seldomly, if not anymore, as it takes time to write it, as well as an understanding of the inner workings of a complex system such as FlightGear. Furthermore, this task might not be attractive due to its short term impact on the project,&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
| url    = http://sourceforge.net/p/flightgear/mailman/message/27861562/&lt;br /&gt;
| title  = &amp;lt;nowiki&amp;gt;Re: [Flightgear-devel] The state of things in Flight Gear&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| author = &amp;lt;nowiki&amp;gt;Hal V. Engel&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| date   = Jul 27th, 2011&lt;br /&gt;
| added   = Jul 27th, 2011&lt;br /&gt;
| script_version = 0.23&lt;br /&gt;
}}&amp;lt;/ref&amp;gt; and it is overwhelming to think about creating documentation that would address the needs of many different kinds of contributors with different backgrounds, experience levels and goals.&amp;lt;ref name=&amp;quot;OlsonStateThingsFG&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Forum and mailing lists discussions have therefore become the only up-to-date (albeit difficult to filter)&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
| url    = http://forum.flightgear.org/viewtopic.php?p=280058#p280058&lt;br /&gt;
| title  = &amp;lt;nowiki&amp;gt;Re: quoting on the wiki&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| author = &amp;lt;nowiki&amp;gt;Thorsten&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| date   = Mar 21st, 2016&lt;br /&gt;
| added   = Mar 21st, 2016&lt;br /&gt;
| script_version = 0.25&lt;br /&gt;
}}&amp;lt;/ref&amp;gt; source of information about recent development progress; this makes it tricky to know what is going on, what needs fixing, what were the decisions taken by the developers.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
| url    = https://www.mail-archive.com/flightgear-devel%40lists.sourceforge.net/msg17198.html&lt;br /&gt;
| title  = &amp;lt;nowiki&amp;gt;[Flightgear-devel] Project tracking&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| author = &amp;lt;nowiki&amp;gt;James Turner&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| date   = Mon, 28 Jul 2008 10:06:05 -0700&lt;br /&gt;
}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The aim of the Instant-Cquotes script is to help wiki editors to copy relevant excerpts from such sources, formatting them as proper [[Template:Cquote|quotations]], and bootstrap new articles collecting them until a dedicated rewrite is made. It can also be used to reuse announcements to update the changelogs, [[Next newsletter|newsletter]] or the [[Release plan/Lessons learned]] page.&lt;br /&gt;
&lt;br /&gt;
After being away from the wiki system for some time it becomes more of an effort to re-learn how to start a new file and figure out how to format it , with what headings, etc. Sometimes it is almost too much to do the original write up of the original post and all the work of that layout and effort to have to also duplicate it in a wiki article. If I was a little more current and affluent with the wiki editor, I might not be so hesitant to create the work there instead of the forum.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
  |url    =  https://forum.flightgear.org/viewtopic.php?p=284698#p284698 &lt;br /&gt;
  |title  =  &amp;lt;nowiki&amp;gt; Re: Breaking down NLCD raster image &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |author =  &amp;lt;nowiki&amp;gt; wlbragg &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
  |date   =  May 9th, 2016 &lt;br /&gt;
  |added  =  May 9th, 2016 &lt;br /&gt;
  |script_version = 0.38 &lt;br /&gt;
  }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In a few cases, such collections of quotes helped not only create bootstrap new articles, but even actual features.&lt;br /&gt;
&lt;br /&gt;
In other cases, quotes have been used to update documentation of features (e.g. [[Rembrandt]]) whose maintainers may not be actively involved in FlightGear, to help document discussions that are taking place in the meantime, and provide some background information for people interested in the corresponding feature.&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
# Install a user script manager. On Firefox, you can use [https://addons.mozilla.org/en-US/firefox/addon/greasemonkey/ Greasemonkey]; on Chrome/Chromium, Opera or Safari, you can use [https://tampermonkey.net/ Tampermonkey] (download links: [https://tampermonkey.net/index.php?ext=dhdg&amp;amp;browser=chrome Chrome/Chromium], [https://tampermonkey.net/index.php?ext=dhdg&amp;amp;browser=opera Opera], [https://tampermonkey.net/index.php?ext=dhdg&amp;amp;browser=safari Safari]).&lt;br /&gt;
# Visit [https://greasyfork.org/en/scripts/19331-instant-cquotes the Instant-Cquotes page on GreasyFork] and click on '''Install this script''' (green button). If Greasemonkey/Tampermonkey prompts you to confirm the installation, agree to do so.&lt;br /&gt;
&lt;br /&gt;
[[File:Howto-install-instant-cquotes.png|thumb|click the green button to install the script]]&lt;br /&gt;
&lt;br /&gt;
=== Manual installation ===&lt;br /&gt;
{{note|This will install the most recent development version of the script, which might contain bugs. Also, GreaseMonkey/TamperMonkey will not update it automatically whenever a new version is released.}}&lt;br /&gt;
&lt;br /&gt;
* '''Firefox'''&lt;br /&gt;
# Install Greasemonkey.&lt;br /&gt;
# Save [[#The Script|the script]] below as &amp;lt;code&amp;gt;instant_cquotes.user.js&amp;lt;/code&amp;gt;, then drag-and-drop it into Firefox.&lt;br /&gt;
[[File:Greasemonkey-setup-on-firefox.png|thumb|Screenshot showing the Greasemonkey setup dialog (on Firefox)]]&lt;br /&gt;
&lt;br /&gt;
* '''Chrome/Chromium''', '''Opera''', or '''Safari'''&lt;br /&gt;
# Install Tampermonkey.&lt;br /&gt;
# Navigate to '''Add a new Script'''.&lt;br /&gt;
# Copy and paste [[#The Script|the script]] below into the editing window.&lt;br /&gt;
# Click the '''Save''' button (just above the {{button|Search}} button).&lt;br /&gt;
&lt;br /&gt;
=== Mobile installation ===&lt;br /&gt;
As of May 2016, there is no separate version available for mobile use. Your best chance is installing a userscript addon on Android, like one of those:&lt;br /&gt;
* [https://play.google.com/store/apps/details?id=net.biniok.tampermonkey Tampermonkey (Google Play Store)]&lt;br /&gt;
* [http://oilcan.jsharkey.org/ OilCan: Greasemonkey on steroids for Android]&lt;br /&gt;
&lt;br /&gt;
For installation instructions, refer to [https://openuserjs.org/about/Tampermonkey-for-Android Tampermonkey for Android] or [http://www.blogtechnika.com/how-to-access-greasemonkey-scripts-on-android-phones/ How To Access Greasemonkey Scripts on Android Phones].&lt;br /&gt;
&lt;br /&gt;
Testing/feedback would obviously be appreciated - if in doubt, feel free to just edit the wiki page to add your findings/questions.&lt;br /&gt;
&lt;br /&gt;
=== Configuration ===&lt;br /&gt;
[[File:User-script-menu.png|thumb|GreaseMonkey menu shown in FireFox with instanct cquotes menu items]]&lt;br /&gt;
&lt;br /&gt;
[[File:Config-dialog-instant-cquotes.png|thumb|The configuration dialog for the Instant-Cquotes script]]&lt;br /&gt;
&lt;br /&gt;
As of version 0.30, a dedicated configuration dialog is in the process of being added, so that certain script features can be dynamically configured, without having to edit the script. For now, this is merely a placeholder that provides a checkbox to easily enable/disable the debug mode. In the future, we are hoping to also expose other features this way.&lt;br /&gt;
&lt;br /&gt;
== Usage ==&lt;br /&gt;
[[File:Updated-cquotes-script-by-redleader.png|thumb|Instant-Cquotes script, with updates contributed by Red Leader]]&lt;br /&gt;
&lt;br /&gt;
[[File:New-cquotes.png|thumb|Screenshot showing Instant-Cquotes 0.30 at work]]&lt;br /&gt;
&lt;br /&gt;
# Go to some [[mailing list]] archive URL, for example [http://sourceforge.net/p/flightgear/mailman/message/32400727/] or any forum message, such as {{forumref|title=Re: Get objects to show up on Map/Radar|t=23299|label=p212558|f=71}}.&lt;br /&gt;
# Select the relevant portion of text.&lt;br /&gt;
# When you release the mouse button, a box will appear containing the converted text (for now, mainly properly-referenced quotes for the wiki).&lt;br /&gt;
# As the text will already be selected for you, press {{key press|Ctrl|C}} to copy it (no longer necessary).&lt;br /&gt;
# Paste the text into the desired wiki page.&lt;br /&gt;
&lt;br /&gt;
For example, by selecting part of the forum post in the link above you can get the following quotation:&lt;br /&gt;
&lt;br /&gt;
{{FGCquote&lt;br /&gt;
|1= The upcoming FlightGear version (3.2) will contain a canvas-based map dialog, including a modular &amp;quot;plugin&amp;quot; system for creating custom map layers and charts with roughly ~50 lines of code, most of it boilerplate. &lt;br /&gt;
This is entirely XML/Nasal based (scripted) - symbols can be pretty much anything, raster or vector images (png or svg), but even animated. Styling can be customied, too.&lt;br /&gt;
For more info, I suggest to check out:&lt;br /&gt;
[[MapStructure#Porting the map dialog]]&lt;br /&gt;
&lt;br /&gt;
[[File:MapStructureDialog.png|250px]]&lt;br /&gt;
|2= {{cite web&lt;br /&gt;
  | url    = http://forum.flightgear.org/viewtopic.php?p=212558#p212558&lt;br /&gt;
  | title  = &amp;lt;nowiki&amp;gt;Re: Get objects to show up on Map/Radar&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  | author = &amp;lt;nowiki&amp;gt;Hooray&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  | date   = Jun 14th, 2014&lt;br /&gt;
  }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== On quoting ===&lt;br /&gt;
{{Main article|FlightGear wiki:Quoting Guidelines}}&lt;br /&gt;
&lt;br /&gt;
Using the Instant-Cquotes script is a good way to bootstrap and write some preliminary notes; however, while quotes might be useful to understand how undocumented subsystems and features work and are definitely better than nothing, they are not meant to replace proper, structured and well-written wiki articles.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
| url    = http://forum.flightgear.org/viewtopic.php?p=282800#p282800&lt;br /&gt;
| title  = &amp;lt;nowiki&amp;gt;Re: What is the QT launcher?&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| author = &amp;lt;nowiki&amp;gt;bugman&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| date   = Apr 17th, 2016&lt;br /&gt;
| added   = Apr 17th, 2016&lt;br /&gt;
| script_version = 0.25&lt;br /&gt;
}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One way to convert pages bootstrapped using quotes is to extract relevant information from them and keep citations only as references; in case important details are missing, they can be asked for on the [[Mailing lists|mailing lists]] (on the forum, the chance to get a complete answer might be lower).&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
| url    = http://sourceforge.net/p/flightgear/mailman/message/34954385/&lt;br /&gt;
| title  = &amp;lt;nowiki&amp;gt;Re: [Flightgear-devel] Wiki Quotes&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| author = &amp;lt;nowiki&amp;gt;James Turner&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| date   = Mar 21st, 2016&lt;br /&gt;
| added   = Mar 21st, 2016&lt;br /&gt;
| script_version = 0.25&lt;br /&gt;
}}&amp;lt;/ref&amp;gt; Another option might be moving the quotes to the Talk page for each entry, which would preserve the sources without clogging up the articles.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
| url    = http://sourceforge.net/p/flightgear/mailman/message/34948989/&lt;br /&gt;
| title  = &amp;lt;nowiki&amp;gt;Re: [Flightgear-devel] Wiki Quotes&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| author = &amp;lt;nowiki&amp;gt;Stuart Buchanan&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| date   = Mar 19th, 2016&lt;br /&gt;
| added   = Mar 19th, 2016&lt;br /&gt;
| script_version = 0.25&lt;br /&gt;
}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As a matter of fact, the whole paragraph above was assembled using this approach; to see for yourself, look up the references at the end of this page. For another example, see [[TerraSync#News]].&lt;br /&gt;
&lt;br /&gt;
== Development ==&lt;br /&gt;
{{Note|A Chrome/Chromium-specific extension that will not need Tampermonkey installed is under development.}}&lt;br /&gt;
&lt;br /&gt;
=== Resources ===&lt;br /&gt;
* https://www.mediawiki.org/wiki/API:Changing_wiki_content&lt;br /&gt;
* https://www.mediawiki.org/wiki/API:Edit&lt;br /&gt;
&lt;br /&gt;
=== Adding sources ===&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
{{WIP}}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
Adding a new source is pretty straightforward if you understand how xpath and regexes work - basically, you only need an archive (e.g. gmane), and then determine the xpath of each relevant field, as well as the regular expression to process the extracted fields (optional).&lt;br /&gt;
&lt;br /&gt;
The basic steps are these:&lt;br /&gt;
# open the user script in an editor&lt;br /&gt;
# navigate to the meta header of the user script&lt;br /&gt;
# add a new URL to the top of the script, e.g. by copying/adapting an existing line like this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// @match       https://sourceforge.net/p/flightgear/mailman/*&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once copied, add the new URL:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// @match       http://thread.gmane.org/gmane.games.flightgear.devel/*&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next, you need to navigate to the configuration hash to add a new website to it. &lt;br /&gt;
&lt;br /&gt;
Again, it makes sense to simply take an existing configuration hash and adapt it as needed (ignore/omit the tests vector for now by keeping it empty):&lt;br /&gt;
&lt;br /&gt;
{{Caution|the following example may meanwhile be outdated, so be sure to look at the actual code instead}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  'Sourceforge Mailing list': {&lt;br /&gt;
    enabled: true,&lt;br /&gt;
    type: 'archive',&lt;br /&gt;
    event: 'document.onmouseup', // when to invoke the event handler&lt;br /&gt;
    event_handler: instantCquote, // the event handler to be invoked&lt;br /&gt;
    url_reg: '^(http|https)://sourceforge.net/p/flightgear/mailman/.*/',&lt;br /&gt;
    content: {&lt;br /&gt;
      xpath: 'tbody/tr[2]/td/pre/text()',&lt;br /&gt;
      selection: getSelectedText,&lt;br /&gt;
      idStyle: /msg[0-9]{8}/,&lt;br /&gt;
      parentTag: [&lt;br /&gt;
        'tagName',&lt;br /&gt;
        'PRE'&lt;br /&gt;
      ],&lt;br /&gt;
    transform: [] // vector with transformation callbacks&lt;br /&gt;
    }, // content recipe&lt;br /&gt;
    // vector with tests to be executed for sanity checks (unit testing)&lt;br /&gt;
    tests: [&lt;br /&gt;
    ], // end of vector with self-tests&lt;br /&gt;
    // regex/xpath and transformations for extracting various required fields&lt;br /&gt;
    author: {&lt;br /&gt;
      xpath: 'tbody/tr[1]/td/div/small/text()',&lt;br /&gt;
      transform: [extract(/From: (.*) &amp;lt;.*@.*&amp;gt;/)]&lt;br /&gt;
    },&lt;br /&gt;
    title: {&lt;br /&gt;
      xpath: 'tbody/tr[1]/td/div/div[1]/b/a/text()'&lt;br /&gt;
      transform: []&lt;br /&gt;
    },&lt;br /&gt;
    date: {&lt;br /&gt;
      xpath: 'tbody/tr[1]/td/div/small/text()',&lt;br /&gt;
      transform: [extract(/- (.*-.*-.*) /)]&lt;br /&gt;
    },&lt;br /&gt;
    url: {&lt;br /&gt;
      xpath: 'tbody/tr[1]/td/div/div[1]/b/a/@href',&lt;br /&gt;
      transform: [prepend('https://sourceforge.net')]&lt;br /&gt;
    }&lt;br /&gt;
  }, // end of mailing list profile&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, we need to review/adapt the profile according to the new archive we'd like to see supported. &lt;br /&gt;
&lt;br /&gt;
for starters, that means:&lt;br /&gt;
* changing the name of the profile, e.g. to read gmane (instead of sourceforge)&lt;br /&gt;
* change the '''url_reg''' field to the gmane URL (this can be a regular expression)&lt;br /&gt;
&lt;br /&gt;
Next, it makes sense to use an [https://addons.mozilla.org/de/firefox/addon/xpath-checker/ XPath checker], so that we can look up the xpath expression for various HTML elements, and add those to the configuration hash above.&lt;br /&gt;
&lt;br /&gt;
For testing purposes, you will probably go to the setup dialog and enable the DEBUG mode, and use your browser's console to see what is going on.&lt;br /&gt;
&lt;br /&gt;
=== Getting involved ===&lt;br /&gt;
While having some experience with JavaScript/HTML and jQuery will definitely be useful, JavaScript is close enough to FlightGear scripting ([[Nasal]]), so that people can get involved pretty easily. &lt;br /&gt;
&lt;br /&gt;
Most maintenance work will typically involve reviewing/maintaining a few configuration hashes, that contain meta information for each supported archive (mailing list/forum).&lt;br /&gt;
&lt;br /&gt;
Usually, each hash contains a combination of xpath/regex expressions to look up the relevant information, as well as vector of optional transformations that are applied (in order) to convert contents to a different format (e.g. dates).&lt;br /&gt;
&lt;br /&gt;
In addition, there is growing library of utility functions, a handful wrappers for useful stuff, for example:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;Host.dbLog(message_string)&amp;lt;/code&amp;gt; - log a message to the console if the DEBUG flag is set&lt;br /&gt;
* &amp;lt;code&amp;gt;Host.download(url, callback, method='GET')&amp;lt;/code&amp;gt; - will download the URL and pass the downloaded content to the callback specified&lt;br /&gt;
* &amp;lt;code&amp;gt;Host.downloadPosting(url, callback)&amp;lt;/code&amp;gt; - will download the posting URL and pass the extracted and transformed author/content and date fields in a hash to the callback specified, the URL must be one supported in the CONFIG hash (i.e. forum/sourceforge for now)&lt;br /&gt;
* &amp;lt;code&amp;gt;Host.make_doc(string, type=&amp;quot;text/html&amp;quot;)&amp;lt;/code&amp;gt; - will turn a string/blob into a DOM that can be queried&lt;br /&gt;
* &amp;lt;code&amp;gt;Host.eval_xpath(document, xpath_expression, type=XPathResult.STRING_TYPE)&amp;lt;/code&amp;gt; - will apply the xpath expression to the document specified, returning the requested type (defaulted to string) &lt;br /&gt;
* &amp;lt;code&amp;gt;Host.set_persistent(key,value)&amp;lt;/code&amp;gt;  - stores a key/value pair&lt;br /&gt;
* &amp;lt;code&amp;gt;Host.get_persistent(key,default_value)&amp;lt;/code&amp;gt; - retrieves a values using the key specified, falling back to the default value&lt;br /&gt;
&lt;br /&gt;
=== Porting ===&lt;br /&gt;
[[File:Instant-cquote-firefox-addon-mode.png|thumb|Prototyping a dedicated instant-cquote mode for use as a firefox addon]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Porting the script to support other browsers/script engines is greatly appreciated. Typically, this should be pretty self-contained, because all main APIs are intended to be encapsulated in a so called &amp;quot;Environment&amp;quot; hash, where APIs that are specific to a particular browser/script engine should be provided with a wrapper. As of mid 2016, most APIs are now kept inside such an Environment hash (look at the GreaseMonkey hash for reference/details), so that it is now even possible to turn the script into a standalone FireFox addon without having to change much of the underlying code.&lt;br /&gt;
&lt;br /&gt;
=== Self checks (unit testing) ===&lt;br /&gt;
For regression testing purposes, there's a dedicated &amp;quot;self check&amp;quot; dialog that will be extended over time. For now it will download a few profile/website specific postings using a vector called &amp;quot;tests&amp;quot; and then log the posting's title, author and date to the console.&lt;br /&gt;
&lt;br /&gt;
The next step will be  actually showing that information in the dialog itself - there's a separate helper function to accomplish that, so that the corresponding div layer can be updated with the results.&lt;br /&gt;
&lt;br /&gt;
[[File:Sanity-check-cquotes-dialog.png|thumb|automatically executed sanity checks]]&lt;br /&gt;
&lt;br /&gt;
=== Debug mode ===&lt;br /&gt;
[[File:Instant-cquotes-debug-mode.png|thumb|Instant-Cquotes debug mode]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== AJAX (live page editing) ===&lt;br /&gt;
{{WIP}}&lt;br /&gt;
&lt;br /&gt;
* http://wiki.flightgear.org/api.php&lt;br /&gt;
* http://wiki.flightgear.org/api.php?action=parse&amp;amp;page=Frequently%20asked%20questions&amp;amp;prop=sections&lt;br /&gt;
&lt;br /&gt;
For now, the setup dialog will try to obtain a login token for the wiki and show a message if successful.&lt;br /&gt;
&lt;br /&gt;
In addition, the profile/website hash also contains a new wiki entry for the FlightGear wiki, whose '''event_handler''' callback will be invoked once the FG wiki is visited - the console/log will show a greeting, so that is where other code can be added - e.g. to help clean up/rewrite FGCquote-based articles automatically etc.&lt;br /&gt;
&lt;br /&gt;
There is a vector of &amp;quot;modes&amp;quot;, whose members are a hash containing trigger/handler fields, linked to two callbacks - the trigger callback can be used to check some condition, while the handler will be invoked if the trigger returns true.&lt;br /&gt;
&lt;br /&gt;
This can be used to support an arbitrary number of modes, whose triggers are evaluated during page load - all triggers that return true, will have their handlers invoked, which is how the following snippet works to rewrite/augment wiki edit handles:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;gt;&lt;br /&gt;
 'FlightGear.wiki': {&lt;br /&gt;
    type: 'wiki',&lt;br /&gt;
    enabled: false,&lt;br /&gt;
    event: 'document.onmouseup', // when to invoke the event handler&lt;br /&gt;
    event_handler: function () {&lt;br /&gt;
      console.log('FlightGear wiki handler active (waiting to be populated)');&lt;br /&gt;
      // this is where the logic for a wiki mode can be added over time (for now, it's a NOP)&lt;br /&gt;
    &lt;br /&gt;
    //for each supported mode, invoke the trigger and call the corresponding handler&lt;br /&gt;
    [].forEach.call(CONFIG['FlightGear.wiki'].modes, function(mode) {&lt;br /&gt;
      //dbLog(&amp;quot;Checking trigger:&amp;quot;+mode.name);&lt;br /&gt;
      if(mode.trigger) {&lt;br /&gt;
        mode.handler();&lt;br /&gt;
      }&lt;br /&gt;
    });&lt;br /&gt;
      &lt;br /&gt;
    }, // the event handler to be invoked&lt;br /&gt;
    url_reg: '^(http|https)://wiki.flightgear.org', // ignore for now: not currently used by the wiki mode&lt;br /&gt;
    &lt;br /&gt;
    modes: [&lt;br /&gt;
      { name:'process-editSections',&lt;br /&gt;
        trigger: function() {return true;}, // match URL regex - return true for always match&lt;br /&gt;
       &lt;br /&gt;
        // the code implementing the mode&lt;br /&gt;
        handler: function() {&lt;br /&gt;
                &lt;br /&gt;
    var editSections = document.getElementsByClassName('mw-editsection');&lt;br /&gt;
    console.log('FlightGear wiki article, number of edit sections: '+editSections.length);&lt;br /&gt;
   &lt;br /&gt;
    // for now, just rewrite edit sections and add a note to them&lt;br /&gt;
   &lt;br /&gt;
     [].forEach.call(editSections, function (sec) {&lt;br /&gt;
       sec.appendChild(&lt;br /&gt;
         document.createTextNode(' (instant-cquotes is lurking) ')&lt;br /&gt;
       );&lt;br /&gt;
     }); //forEach section&lt;br /&gt;
        } // handler&lt;br /&gt;
       &lt;br /&gt;
       &lt;br /&gt;
      } // process-editSections&lt;br /&gt;
      // TODO: add other wiki modes below &lt;br /&gt;
      &lt;br /&gt;
    ] // modes&lt;br /&gt;
    &lt;br /&gt;
  }, // end of wiki profile&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See [[User:Red Leader/Sandbox/AJAX test]]&lt;br /&gt;
&lt;br /&gt;
* https://www.mediawiki.org/wiki/API:Changing_wiki_content&lt;br /&gt;
* https://www.mediawiki.org/wiki/Extension:VisualEditor&lt;br /&gt;
* https://en.wikipedia.org/wiki/Wikipedia:Creating_a_bot&lt;br /&gt;
&lt;br /&gt;
=== Mobile edition ===&lt;br /&gt;
{{Note|As of 02/2016, Hooray is contemplating to make this available as an addon for Android phones.}}&lt;br /&gt;
&lt;br /&gt;
=== Issues/limitations ===&lt;br /&gt;
==== Bugs ====&lt;br /&gt;
* It's eating characters, apparently related to regex/xpath handling - e.g. words like &amp;quot;analyzing&amp;quot; are turned into &amp;quot;analying&amp;quot; [http://forum.flightgear.org/viewtopic.php?f=6&amp;amp;t=28378&amp;amp;p=270735&amp;amp;hilit=analyzing#p270735]&lt;br /&gt;
==== Non working URLs ====&lt;br /&gt;
* image matching/extraction: http://forum.flightgear.org/viewtopic.php?p=276221#p276221&lt;br /&gt;
* http://sourceforge.net/p/flightgear/mailman/message/34754961/&lt;br /&gt;
* http://forum.flightgear.org/viewtopic.php?f=18&amp;amp;t=27054&amp;amp;start=90#p273972 → selecting from “As promised, two sample installation sessions on Linux” to “That's it.” towards the end of the message causes Iceweasel (Firefox) 44.0.2 to display a dialog box reading “A script on this page may be busy, or it may have stopped responding. You can stop the script now, open the script in the debugger, or let the script continue.” The line below reads “Script: chrome://greasemonkey-modules/...quotes/instant_cquotes.user.js:544”. Choosing ''Continue'' doesn't help: the same message reappears a few seconds afterwards.&lt;br /&gt;
&lt;br /&gt;
=== Feature requests &amp;amp; ideas ===&lt;br /&gt;
* try to recognize list items [https://sourceforge.net/p/flightgear/mailman/message/35095319/] (heuristics: look for colon/asterisk, dashes and CR/LF)&lt;br /&gt;
* should add [[Template:News]] to the article dropdown for announcements [http://wiki.flightgear.org/index.php?title=Template:News&amp;amp;oldid=98266]&lt;br /&gt;
* add a mode that will download screenshots from forum postings and automatically upload/categorize them, see [[Birds]]&lt;br /&gt;
* split the article dropdown into sections, and also populate it with the user's watchlist [https://www.mediawiki.org/wiki/API:Watchlist] {{Progressbar|60}}&lt;br /&gt;
* mailing list templates, listed at [http://wiki.flightgear.org/Template_talk:Project_infrastructure#Related_mailing_list_templates]&lt;br /&gt;
* expose the cquote/ref markup via the UI so that it can be edited/customized and treated like a template {{Done}} (0.36+)&lt;br /&gt;
* identify common/repeated links and automatically create [[Template:Project infrastructure|link/infrastructure templates]] and use those (should be straightforward using the AJAX mode) [http://wiki.flightgear.org/index.php?title=Mailing_lists&amp;amp;curid=2038&amp;amp;diff=97876&amp;amp;oldid=85252]&lt;br /&gt;
* add a devel/maintainer mode where it will return the xpath for a selection [http://stackoverflow.com/questions/361130/get-selected-text-and-selected-nodes-on-a-page] [http://stackoverflow.com/questions/12485334/get-surrounding-dom-node-of-selection]&lt;br /&gt;
* move openlink,dblog helpers to Environment hash {{Done}}&lt;br /&gt;
* identify CLI arguments like --aircraft=c172p and wrap them in between code tags &amp;lt;code&amp;gt;--aircraft=c172p&amp;lt;/code&amp;gt; [https://sourceforge.net/p/flightgear/mailman/message/35063277/] (note that we can simply download [https://sourceforge.net/p/flightgear/fgdata/ci/next/tree/options.xml options.xml] via openlink() and use that, which is kinda of neat...) {{Progressbar|60}} (see downloadOptionsXML() in the code)&lt;br /&gt;
* introduce &amp;quot;layouts&amp;quot; (templates) for different purposes: newsletter, changelog, wiki article, [[The Manual]] (LaTex)  ? {{Progressbar|40}}&lt;br /&gt;
* use wikipedia template if possible [https://sourceforge.net/p/flightgear/mailman/message/35057670/]&lt;br /&gt;
* the new '''tests''' vector could also contain vectors for tests to test the extract/transform* utilities, see Environment.APITests {{Progressbar|50}}&lt;br /&gt;
* move environment specific APIs (browser, script host etc) into some kind of Environment hash to encapsulate things (Red Leader was working on a pure Chrome-only version at some point IIRC) {{Progressbar|80}}&lt;br /&gt;
* encode script settings in created markup, for future processing/updating of quotes&lt;br /&gt;
* look up &amp;lt;code&amp;gt;[x]&amp;lt;/code&amp;gt; references and replace with the corresponding link (titled) [https://sourceforge.net/p/flightgear/mailman/message/35055331/] [https://sourceforge.net/p/flightgear/mailman/message/35062598/]&lt;br /&gt;
** convert footnotes into Abbr templates [http://article.gmane.org/gmane.games.flightgear.devel/78971]&lt;br /&gt;
* support named refs for combining identical refs [http://wiki.flightgear.org/index.php?title=FlightGear_Qt_launcher&amp;amp;curid=13693&amp;amp;diff=97562&amp;amp;oldid=97551]&lt;br /&gt;
* adopt [[Template:Forumref]]&lt;br /&gt;
* implement a less obnoxious quoting mode, without quotes, where only the ref part would be added, e.g. see the example at [[Graphics Card Profiles]] (it's still 99% quotes, but much less annoying) {{Done}}&lt;br /&gt;
* attachment support: identify attachments and link to them: [https://sourceforge.net/p/flightgear/mailman/message/11683451/] [https://sourceforge.net/p/flightgear/mailman/message/23906620/] [https://sourceforge.net/p/flightgear/mailman/message/35059842/] [https://sourceforge.net/p/flightgear/mailman/message/35067087/]&lt;br /&gt;
* bulletin points: if there is a colon (:) followed by at least two dashes (-), split up everything after the colon to turn each dash into an asterisk (wiki markup for bulletin points), followed by a newline [http://sourceforge.net/p/flightgear/mailman/message/34760165/]   &lt;br /&gt;
* generic URL/template matching, e.g. for for sourceforge commit IDs&lt;br /&gt;
* make filters/conversions configurable via checkboxes (nowiki, wrap in alert/note boxes)&lt;br /&gt;
* make syntax highlighting configurable (language, mode) ?&lt;br /&gt;
* consider using something like the Roles template to turn contributor names into tooltips where contributor roles are shown (core dev, fgdata committer etc)&lt;br /&gt;
* introduce support for tag clouds to help categorize/classify related quotes&lt;br /&gt;
* consider making transformations optional/configurable using check boxes in the jQuery dialog&lt;br /&gt;
* add new input method, for quotes that need to be updated/converted (added script version specifically for this purpose), should also add extraction/processing date&lt;br /&gt;
* investigate why not all mailing list archives/postings are supported correctly: http://sourceforge.net/p/flightgear/mailman/message/8090479/ (problem traced to &amp;lt;code&amp;gt;getPostID()&amp;lt;/code&amp;gt;)&lt;br /&gt;
* explore having a ref-only mode without using cquotes, i.e. just copy/paste quotes with proper ref tags and a references section, to rewrite the whole thing (possibly with templates for different purposes, e.g. newsletter/changelog) {{Done}}&lt;br /&gt;
* should use Template:Forumref (category:link templates)&lt;br /&gt;
* should be updated to use the new repo/flightgear file templates created by Johan &amp;amp; RedLeader {{Not done}}&lt;br /&gt;
* resolve links to forum threads to look up the title for the topic/posting, so that the posting's title can be used for those links, instead of just the URL - we can probably do that by making an AJAX call to open URLs asynchronously and extract the title for the thread/posting to come up with something like &amp;lt;code&amp;gt;[http://forum.flightgear.org/viewtopic.php?f=4&amp;amp;t=24421 A call to developers-Lockheed -L188 Electra]&amp;lt;/code&amp;gt; ([http://forum.flightgear.org/viewtopic.php?f=4&amp;amp;t=26562&amp;amp;p=247325&amp;amp;hilit=links#p247347]) {{Progressbar|50}}&lt;br /&gt;
* convert quoted bug tracker URLs to use the issue template on the wiki {{not done}}&lt;br /&gt;
* do regex/xpath validation, and display any errors (e.g. template/theme changes on the forum would currently break the script) {{Progressbar|60}}&lt;br /&gt;
* increased focus on supporting different output formats, maybe using a simple [http://www.jquery-steps.com/ jQuery based wizard] (wiki, forum, newsletter, changelog) {{Not done}}&lt;br /&gt;
* token matching for keywords/acronyms to link to the corresponding wiki articles (e.g. Nasal, Canvas, FG_ROOT, FG_HOME etc) {{Not done}}&lt;br /&gt;
* Add support for [http://sourceforge.net/p/flightgear/codetickets/ tickets], merge requests comments and [http://www.fguk.eu/index.php/forum/index FGUK forum]. (also see [[FlightGear wiki talk:Instant-Cquotes#more sources]])&lt;br /&gt;
* GET-encoded SID arguments should be stripped from forum URLs. {{Not done}}&lt;br /&gt;
* Links to repositories should be converted to use wiki templates. {{Not done}}&lt;br /&gt;
* The {{Abbr|regexes|regular expressions}} used may fail if the HTML DOM of the source changes (e.g., phpBB/theme update)&lt;br /&gt;
** Show a warning when that's the case. {{Progressbar|70}} (see the self-check dialog)&lt;br /&gt;
** Try multiple regexes in order. {{Progressbar|30}} (see the self-check dialog)&lt;br /&gt;
* Use the script to update previously created Cquotes automatically&lt;br /&gt;
** Instead of using the &amp;lt;code&amp;gt;getSelection()&amp;lt;/code&amp;gt; helper, we could register a match for &amp;lt;tt&amp;gt;wiki.flightgear.org&amp;lt;/tt&amp;gt; with &amp;lt;code&amp;gt;action=edit&amp;lt;/code&amp;gt; set, so that we can directly process all text of an edited page, using AJAX calls to open the URL in the background. {{Progressbar|40}} (see the self-check dialog, available via the greasemonkey menu)&lt;br /&gt;
** See [https://www.mediawiki.org/wiki/API:Edit#Editing_via_Ajax MW:API:Edit § Editing via Ajax]&lt;br /&gt;
&lt;br /&gt;
=== Changelog ===&lt;br /&gt;
{{Note|Contributors are invited to document their changes here, please also add your wiki handle so that others can more easily get in touch.}}&lt;br /&gt;
&lt;br /&gt;
* first stab at implementing unit tests by adding a vector with URLS to be downloaded and fields to be matched (WIP), shown in a jQuery dialog&lt;br /&gt;
* support for persistent settings and a jQuery setup dialog with persistence&lt;br /&gt;
* hosting is moved, to allow auto-updates [http://www.greasespot.net/2012/02/automatic-script-updates-come-to.html] [https://wiki.greasespot.net/Metadata_Block#.40updateURL] [http://stackoverflow.com/questions/15095055/why-isnt-my-greasemonkey-script-updating]&lt;br /&gt;
* changed to ref-only quotes for now, not using the FGCquote template anymore, due to its obnoxious appearance on quote-heavy pages (should probably become a runtime option instead)&lt;br /&gt;
* updated to use https for forum postings&lt;br /&gt;
* add version info to each created quote, i.e. for future updates&lt;br /&gt;
* add helper for opening websites asynchronously using AJAX (also via GM helper API)&lt;br /&gt;
* display version number in output dialog&lt;br /&gt;
* begin using the GreaseMonkey API for setting clipboard content&lt;br /&gt;
&lt;br /&gt;
== The script ==&lt;br /&gt;
&amp;lt;gallery mode=packed widths=230px heights=230px&amp;gt;&lt;br /&gt;
Instant-cquotes-revamped.png|Instant cquotes: Revamped user interface exposes script internals to make the script better configurable at runtime&lt;br /&gt;
Instant-cquotes-template-editor.png|Instant cquotes now features a simple built-in template editor with support for variable substitution, so that wiki templates can be more easily customized&lt;br /&gt;
Instant-cquotes-with-wikimedia-API-integration.png|Screenshot showing instant-cquotes with wikimedia API integration to fetch articles/sections and populate dropdown menus accordingly&lt;br /&gt;
Instant-cquotes-on-steroids-with-watchlist-support.png|Screenshot showing the JQuery-mode of the instant cquotes script with built-in support for fetching a user's wiki/watchlist to edit/update articles in a semi-automated fashion&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
{{PD-author|FlightGear contributors}}&lt;br /&gt;
&lt;br /&gt;
{{Note|Anybody interested in contributing to the code is invited to directly edit this wiki article. From 05/2016, the script is hosted on GreasyFork to allow automatic updates. If you'd like to see your changes applied, please bump the version number and [[User:Elgaton|Elgaton]] will upload it in the state it was when the version number was bumped. ''Make sure to perform thorough testing'' before the bump to prevent unexpected breakage; it is generally a good idea to validate your changes using an online syntax checker, e.g.:&lt;br /&gt;
* http://jshint.com/ &lt;br /&gt;
* http://esprima.org/demo/validate.html&lt;br /&gt;
* http://codebeautify.org/jsvalidate&lt;br /&gt;
&amp;lt;p/&amp;gt;Thank you!}}&lt;br /&gt;
&lt;br /&gt;
Changes that should be mentioned in the changelog, should be added below (and moved to the [[#Changelog]] section subsequently:&lt;br /&gt;
&lt;br /&gt;
* preparations for adding support to download fgdata related files like options.xml to automatically regex known CLI commands&lt;br /&gt;
* preparatory work for adding a speech-rewrite engine to assist in converting 1st person speech to 3rd person&lt;br /&gt;
* framework for encapsulating userscript specifics in an environment hash to provide better updating/porting support&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;// ==UserScript==&lt;br /&gt;
// @name        Instant-Cquotes&lt;br /&gt;
// @name:it     Instant-Cquotes&lt;br /&gt;
// @license     public domain&lt;br /&gt;
// @version     0.39&lt;br /&gt;
// @date        2016-05-05&lt;br /&gt;
// @description Automatically converts selected FlightGear mailing list and forum quotes into post-processed MediaWiki markup (i.e. cquotes).&lt;br /&gt;
// @description:it Converte automaticamente citazioni dalla mailing list e dal forum di FlightGear in marcatori MediaWiki (cquote).&lt;br /&gt;
// @author      Hooray, bigstones, Philosopher, Red Leader &amp;amp; Elgaton (2013-2016)&lt;br /&gt;
// @supportURL  http://wiki.flightgear.org/FlightGear_wiki:Instant-Cquotes&lt;br /&gt;
// @icon        http://wiki.flightgear.org/images/2/25/Quotes-logo-200x200.png&lt;br /&gt;
// @match       https://sourceforge.net/p/flightgear/mailman/*&lt;br /&gt;
// @match       http://sourceforge.net/p/flightgear/mailman/*&lt;br /&gt;
// @match       https://forum.flightgear.org/*&lt;br /&gt;
// @match       http://wiki.flightgear.org/*&lt;br /&gt;
// @namespace   http://wiki.flightgear.org/FlightGear_wiki:Instant-Cquotes&lt;br /&gt;
// @run-at      document-start&lt;br /&gt;
// @require     https://code.jquery.com/jquery-1.10.2.js&lt;br /&gt;
// @require     https://code.jquery.com/ui/1.11.4/jquery-ui.js&lt;br /&gt;
// @require     https://cdn.jsdelivr.net/genetic.js/0.1.14/dist.js&lt;br /&gt;
// @require     https://cdn.jsdelivr.net/synaptic/1.0.4/synaptic.min.js&lt;br /&gt;
// @resource    jQUI_CSS https://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css&lt;br /&gt;
// @resource    myLogo http://wiki.flightgear.org/images/2/25/Quotes-logo-200x200.png&lt;br /&gt;
// @grant       GM_registerMenuCommand&lt;br /&gt;
// @grant       GM_setValue&lt;br /&gt;
// @grant       GM_getValue&lt;br /&gt;
// @grant       GM_addStyle&lt;br /&gt;
// @grant       GM_getResourceText&lt;br /&gt;
// @grant       GM_getResourceURL&lt;br /&gt;
// @grant       GM_setClipboard&lt;br /&gt;
// @grant       GM_xmlhttpRequest&lt;br /&gt;
// @noframes&lt;br /&gt;
// ==/UserScript==&lt;br /&gt;
//&lt;br /&gt;
// This work has been released into the public domain by their authors. This&lt;br /&gt;
// applies worldwide.&lt;br /&gt;
// In some countries this may not be legally possible; if so:&lt;br /&gt;
// The authors grant anyone the right to use this work for any purpose, without&lt;br /&gt;
// any conditions, unless such conditions are required by law.&lt;br /&gt;
//&lt;br /&gt;
// This script has a number of dependencies that are implicitly satisfied when run as a user script &lt;br /&gt;
// via GreaseMonkey/TamperMonkey; however, these need to be explicitly handled when using a different mode (e.g. firefox/android):&lt;br /&gt;
// &lt;br /&gt;
// - jQuery - user interface (REQUIRED)&lt;br /&gt;
// - genetic-js - genetic programming (OPTIONAL/EXPERIMENTAL)&lt;br /&gt;
// - synaptic - neural networks (OPTIONAL/EXPERIMENTAL)&lt;br /&gt;
// &lt;br /&gt;
// &lt;br /&gt;
&lt;br /&gt;
/* Here are some TODOs&lt;br /&gt;
 * - support RSS feeds http://dir.gmane.org/gmane.games.flightgear.devel/&lt;br /&gt;
 * - move event handling/processing to the CONFIG hash&lt;br /&gt;
 * - use try/catch more widely&lt;br /&gt;
 * - wrap function calls in try/call for better debugging/diagnostics&lt;br /&gt;
 * - add helpers for [].forEach.call, map, apply and call&lt;br /&gt;
 * - replace for/in, for/of, let statements for better compatibility (dont require ES6)&lt;br /&gt;
 * - for the same reason, replace use of functions with default params &lt;br /&gt;
 * - isolate UI (e.g. JQUERY) code in UserInterface hash&lt;br /&gt;
 * - expose regex/transformations via the UI&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
'use strict';&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// TODO: move to GreaseMonkey/UI host&lt;br /&gt;
// prevent conflicts with jQuery used on webpages: https://wiki.greasespot.net/Third-Party_Libraries#jQuery&lt;br /&gt;
// http://stackoverflow.com/a/5014220&lt;br /&gt;
this.$ = this.jQuery = jQuery.noConflict(true);&lt;br /&gt;
&lt;br /&gt;
// this hash is just intended to help isolate UI specifics&lt;br /&gt;
// so that we don't need to maintain/port tons of code &lt;br /&gt;
&lt;br /&gt;
var UserInterface = {&lt;br /&gt;
  get: function() {&lt;br /&gt;
    return UserInterface.DEFAULT;&lt;br /&gt;
  },&lt;br /&gt;
  &lt;br /&gt;
 CONSOLE: {&lt;br /&gt;
   &lt;br /&gt;
 }, // CONSOLE (shell, mainly useful for testing)&lt;br /&gt;
  &lt;br /&gt;
 DEFAULT: {&lt;br /&gt;
  alert: function(msg) {return window.alert(msg);     },&lt;br /&gt;
  prompt: function(msg) {return window.prompt(msg);  }, &lt;br /&gt;
  confirm: function(msg) {return window.confirm(msg); },&lt;br /&gt;
  dialog: null,&lt;br /&gt;
  selection: null,&lt;br /&gt;
  populateWatchlist: function() {&lt;br /&gt;
    &lt;br /&gt;
  },&lt;br /&gt;
  populateEditSections: function() {&lt;br /&gt;
    &lt;br /&gt;
  }&lt;br /&gt;
 &lt;br /&gt;
 }, // default UI mapping (Browser/User script)&lt;br /&gt;
  &lt;br /&gt;
  JQUERY: {&lt;br /&gt;
    &lt;br /&gt;
  } // JQUERY &lt;br /&gt;
  &lt;br /&gt;
}; // UserInterface&lt;br /&gt;
&lt;br /&gt;
var UI = UserInterface.get(); // DEFAULT for now&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// This hash is intended to help encapsulate platform specifics (browser/scripting host)&lt;br /&gt;
// Ideally, all APIs that are platform specific should be kept here&lt;br /&gt;
// This should make it much easier to update/port and maintain the script in the future&lt;br /&gt;
var Environment = {&lt;br /&gt;
  getHost: function(xpi=false) {&lt;br /&gt;
 &lt;br /&gt;
     if(xpi) {&lt;br /&gt;
       Environment.scriptEngine = 'firefox addon';&lt;br /&gt;
       console.log('in firefox xpi/addon mode');&lt;br /&gt;
       return Environment.FirefoxAddon; // HACK for testing the xpi mode (firefox addon)&lt;br /&gt;
     }&lt;br /&gt;
    &lt;br /&gt;
    // This will determine the script engine in use: http://stackoverflow.com/questions/27487828/how-to-detect-if-a-userscript-is-installed-from-the-chrome-store&lt;br /&gt;
    if (typeof(GM_info) === 'undefined') {&lt;br /&gt;
    Environment.scriptEngine = &amp;quot;plain Chrome (Or Opera, or scriptish, or Safari, or rarer)&amp;quot;;&lt;br /&gt;
    // See http://stackoverflow.com/a/2401861/331508 for optional browser sniffing code.&lt;br /&gt;
   }&lt;br /&gt;
   else {&lt;br /&gt;
    Environment.scriptEngine = GM_info.scriptHandler  ||  &amp;quot;Greasemonkey&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
   console.log ('Instant cquotes is running on ' + Environment.scriptEngine + '.');&lt;br /&gt;
    &lt;br /&gt;
   //console.log(&amp;quot;not in firefox addon mode...&amp;quot;);&lt;br /&gt;
    // See also: https://wiki.greasespot.net/Cross-browser_userscripting&lt;br /&gt;
    return Environment.GreaseMonkey; // return the only/default host (for now)&lt;br /&gt;
  },&lt;br /&gt;
  &lt;br /&gt;
  validate: function(host) {&lt;br /&gt;
    if (host.get_persistent('startup.disable_validation',false)) return;&lt;br /&gt;
    &lt;br /&gt;
    if(Environment.scriptEngine !== &amp;quot;Greasemonkey&amp;quot;) &lt;br /&gt;
      console.log(&amp;quot;NOTE: This script has not been tested with script engines other than GreaseMonkey recently!&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    var dependencies = [&lt;br /&gt;
      {name:'jQuery', test: function() {} },&lt;br /&gt;
      {name:'genetic.js', test: function() {} },&lt;br /&gt;
      {name:'synaptic', test: function() {} },&lt;br /&gt;
    ];&lt;br /&gt;
    &lt;br /&gt;
    [].forEach.call(dependencies, function(dep) {&lt;br /&gt;
      console.log(&amp;quot;Checking for dependency:&amp;quot;+dep.name);&lt;br /&gt;
      var status=false;&lt;br /&gt;
      try {&lt;br /&gt;
      dep.test.call(undefined);&lt;br /&gt;
      status=true;&lt;br /&gt;
      }&lt;br /&gt;
      catch(e) {&lt;br /&gt;
      status=false;       &lt;br /&gt;
      }&lt;br /&gt;
      finally {&lt;br /&gt;
        var success = (status)?'==&amp;gt; success':'==&amp;gt; failed';&lt;br /&gt;
        console.log(success);&lt;br /&gt;
        return status;&lt;br /&gt;
      }&lt;br /&gt;
    });&lt;br /&gt;
  }, // validate&lt;br /&gt;
  &lt;br /&gt;
  // this contains unit tests for checking crucial APIs that must work for the script to work correctly&lt;br /&gt;
  // for the time being, most of these are stubs waiting to be filled in&lt;br /&gt;
  // for a working example, refer to the JSON test at the end&lt;br /&gt;
  // TODO: add jQuery tests&lt;br /&gt;
  APITests: [&lt;br /&gt;
     {name:'download', test: function(recipient) {recipient(true);}  },&lt;br /&gt;
     {name:'make_doc', test: function(recipient) { recipient(true);}   },&lt;br /&gt;
     {name:'eval_xpath', test: function(recipient) { recipient(true);} },&lt;br /&gt;
     {name:'JSON de/serialization', test: function(recipient) {&lt;br /&gt;
       //console.log(&amp;quot;running json test&amp;quot;);&lt;br /&gt;
       var identifier = 'unit_tests.json_serialization';&lt;br /&gt;
       var hash1 = {x:1,y:2,z:3};&lt;br /&gt;
       Host.set_persistent(identifier, hash1, true);&lt;br /&gt;
       var hash2 = Host.get_persistent(identifier,null,true);&lt;br /&gt;
       &lt;br /&gt;
       recipient(JSON.stringify(hash1) === JSON.stringify(hash2));&lt;br /&gt;
     } // callback &lt;br /&gt;
     },&lt;br /&gt;
    &lt;br /&gt;
    // downloads a posting and tries to transform it to 3rd person speech ...&lt;br /&gt;
    // TODO: add another test to check forum postings&lt;br /&gt;
    {name:'text/speech transformation', test: function(recipient) {&lt;br /&gt;
    &lt;br /&gt;
    // the posting we want to download&lt;br /&gt;
    var url='https://sourceforge.net/p/flightgear/mailman/message/35066974/';&lt;br /&gt;
    Host.downloadPosting(url, function (result) {&lt;br /&gt;
      &lt;br /&gt;
    // only process the first sentence by using comma/dot as delimiter&lt;br /&gt;
    var firstSentence = result.content.substring(result.content.indexOf(',')+1, result.content.indexOf('.'));&lt;br /&gt;
      &lt;br /&gt;
    var transformed = transformSpeech(firstSentence, result.author, null, speechTransformations );&lt;br /&gt;
    console.log(&amp;quot;3rd person speech transformation:\n&amp;quot;+transformed);   &lt;br /&gt;
    &lt;br /&gt;
    recipient(true);&lt;br /&gt;
    }); // downloadPosting() &lt;br /&gt;
        &lt;br /&gt;
  }// test()&lt;br /&gt;
    }, // end of speech transform test&lt;br /&gt;
    {&lt;br /&gt;
      name:&amp;quot;download $FG_ROOT/options.xml&amp;quot;, test: function(recipient) {&lt;br /&gt;
        downloadOptionsXML();&lt;br /&gt;
        recipient(true);&lt;br /&gt;
      } // test&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
  ], // end of APITests&lt;br /&gt;
  &lt;br /&gt;
  runAPITests: function(host, recipient) {&lt;br /&gt;
    console.log(&amp;quot;Running API tests&amp;quot;);&lt;br /&gt;
    for(let test of Environment.APITests ) {&lt;br /&gt;
      //var test = Environment.APITests[t];&lt;br /&gt;
      // invoke the callback passed, with the hash containing the test specs, so that the console/log or a div can be updated showing the test results&lt;br /&gt;
      &lt;br /&gt;
      recipient.call(undefined, test);&lt;br /&gt;
      &lt;br /&gt;
    } // foreach test&lt;br /&gt;
  }, // runAPITests&lt;br /&gt;
  &lt;br /&gt;
  /*&lt;br /&gt;
   * ===================================================================================================================================================&lt;br /&gt;
   *&lt;br /&gt;
   */&lt;br /&gt;
  &lt;br /&gt;
  // NOTE: This mode/environment is WIP and highly experimental ...&lt;br /&gt;
  // To see this working, you need to package up the whole file as a firefox xpi using &amp;quot;jpm xpi&amp;quot;&lt;br /&gt;
  // and then start the whole thing via &amp;quot;jpm run&amp;quot;, to do that, you also need a matching package.json (i.e. via jpm init) &lt;br /&gt;
  // ALSO: you will have to explicitly install any dependencies using jpm&lt;br /&gt;
  FirefoxAddon: {&lt;br /&gt;
  	init: function() {&lt;br /&gt;
		console.log(&amp;quot;Firefox addon mode ...&amp;quot;);&lt;br /&gt;
  	},&lt;br /&gt;
	getScriptVersion: function() {&lt;br /&gt;
		return '0.36'; // FIXME&lt;br /&gt;
	},&lt;br /&gt;
	dbLog: function(msg) {&lt;br /&gt;
		console.log(msg);&lt;br /&gt;
	},&lt;br /&gt;
	addEventListener: function(ev, cb) {&lt;br /&gt;
&lt;br /&gt;
	require(&amp;quot;sdk/tabs&amp;quot;).on(&amp;quot;ready&amp;quot;, logURL);&lt;br /&gt;
 	function logURL(tab) {&lt;br /&gt;
  		console.log(&amp;quot;URL loaded:&amp;quot; + tab.url);&lt;br /&gt;
	}	&lt;br /&gt;
	},&lt;br /&gt;
    &lt;br /&gt;
	registerConfigurationOption: function(name, callback, hook) {&lt;br /&gt;
	// https://developer.mozilla.org/en-US/Add-ons/SDK/Tutorials/Add_a_Context_Menu_Item&lt;br /&gt;
		console.log(&amp;quot;config menu support n/a in firefox mode&amp;quot;);&lt;br /&gt;
 // https://developer.mozilla.org/en-US/Add-ons/SDK/Tutorials/Using_third-party_modules_%28jpm%29  &lt;br /&gt;
 var menuitems = require(&amp;quot;menuitem&amp;quot;);&lt;br /&gt;
 var menuitem = menuitems.Menuitem({&lt;br /&gt;
  id: &amp;quot;clickme&amp;quot;,&lt;br /&gt;
  menuid: &amp;quot;menu_ToolsPopup&amp;quot;,&lt;br /&gt;
  label: name,&lt;br /&gt;
  onCommand: function() {&lt;br /&gt;
    console.log(&amp;quot;menuitem clicked:&amp;quot;);&lt;br /&gt;
    callback();&lt;br /&gt;
  },&lt;br /&gt;
  insertbefore: &amp;quot;menu_pageInfo&amp;quot;&lt;br /&gt;
});&lt;br /&gt;
	},&lt;br /&gt;
    &lt;br /&gt;
	registerTrigger: function() {&lt;br /&gt;
		// https://developer.mozilla.org/en-US/Add-ons/SDK/Tutorials/Add_a_Context_Menu_Item&lt;br /&gt;
		// https://developer.mozilla.org/en-US/Add-ons/SDK/High-Level_APIs/context-menu#Item%28options%29&lt;br /&gt;
		var contextMenu = require(&amp;quot;sdk/context-menu&amp;quot;);&lt;br /&gt;
		var menuItem = contextMenu.Item({&lt;br /&gt;
  		label: &amp;quot;Instant Cquote&amp;quot;,&lt;br /&gt;
  		context: contextMenu.SelectionContext(),&lt;br /&gt;
      // https://developer.mozilla.org/en/Add-ons/SDK/Guides/Two_Types_of_Scripts&lt;br /&gt;
      // https://developer.mozilla.org/en-US/Add-ons/SDK/Guides/Content_Scripts&lt;br /&gt;
  		contentScript: 'self.on(&amp;quot;click&amp;quot;, function () {' +&lt;br /&gt;
                 '  var text = window.getSelection().toString();' +&lt;br /&gt;
                 '  self.postMessage(text);' +&lt;br /&gt;
                 '});',&lt;br /&gt;
  		onMessage: function (selectionText) {&lt;br /&gt;
    		console.log(selectionText);&lt;br /&gt;
        instantCquote(selectionText);&lt;br /&gt;
  		}&lt;br /&gt;
	});&lt;br /&gt;
  &lt;br /&gt;
    // for selection handling stuff, see: https://developer.mozilla.org/en-US/Add-ons/SDK/High-Level_APIs/selection&lt;br /&gt;
    &lt;br /&gt;
    function myListener() {&lt;br /&gt;
  console.log(&amp;quot;A selection has been made.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
var selection = require(&amp;quot;sdk/selection&amp;quot;);&lt;br /&gt;
selection.on('select', myListener);&lt;br /&gt;
    &lt;br /&gt;
	}, //registerTrigger&lt;br /&gt;
    &lt;br /&gt;
	get_persistent: function(key, default_value) {&lt;br /&gt;
    // https://developer.mozilla.org/en-US/Add-ons/SDK/High-Level_APIs/simple-storage&lt;br /&gt;
    var ss = require(&amp;quot;sdk/simple-storage&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    console.log(&amp;quot;firefox mode does not yet have persistence support&amp;quot;);&lt;br /&gt;
    return default_value;},&lt;br /&gt;
	set_persistent: function(key, value) {&lt;br /&gt;
		console.log(&amp;quot;firefox persistence stubs not yet filled in !&amp;quot;);&lt;br /&gt;
	},&lt;br /&gt;
    &lt;br /&gt;
  &lt;br /&gt;
	set_clipboard: function(content) {&lt;br /&gt;
	// https://developer.mozilla.org/en-US/Add-ons/SDK/High-Level_APIs/clipboard&lt;br /&gt;
    &lt;br /&gt;
	//console.log('clipboard stub not yet filled in ...');&lt;br /&gt;
    var clipboard = require(&amp;quot;sdk/clipboard&amp;quot;);&lt;br /&gt;
    clipboard.set(content);&lt;br /&gt;
	} //set_cliipboard&lt;br /&gt;
    &lt;br /&gt;
  }, // end of FireFox addon config&lt;br /&gt;
  &lt;br /&gt;
  // placeholder for now ...&lt;br /&gt;
  Android: {&lt;br /&gt;
    // NOP&lt;br /&gt;
  }, // Android&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  ///////////////////////////////////////&lt;br /&gt;
  // supported  script engines:&lt;br /&gt;
  ///////////////////////////////////////&lt;br /&gt;
  &lt;br /&gt;
  GreaseMonkey: {&lt;br /&gt;
  // TODO: move environment specific initialization code here  &lt;br /&gt;
  init: function() {&lt;br /&gt;
  // Check if Greasemonkey/Tampermonkey is available&lt;br /&gt;
  try {&lt;br /&gt;
  // TODO: add version check for clipboard API and check for TamperMonkey/Scriptish equivalents ?&lt;br /&gt;
  GM_addStyle(GM_getResourceText('jQUI_CSS'));&lt;br /&gt;
  } // try&lt;br /&gt;
  catch (error) {&lt;br /&gt;
  console.log('Could not add style or determine script version');&lt;br /&gt;
  } // catch&lt;br /&gt;
&lt;br /&gt;
  var commands = [&lt;br /&gt;
  {name:'Setup quotes',callback:setupDialog, hook:'S' },&lt;br /&gt;
  {name:'Check quotes',callback:selfCheckDialog, hook:'C' }&lt;br /&gt;
  ];&lt;br /&gt;
      &lt;br /&gt;
  for (let c of commands ) {&lt;br /&gt;
   this.registerConfigurationOption(c.name, c.callback, c.hook);&lt;br /&gt;
  }  &lt;br /&gt;
     &lt;br /&gt;
  }, // init()&lt;br /&gt;
    &lt;br /&gt;
  getScriptVersion: function() {&lt;br /&gt;
  return GM_info.script.version;  &lt;br /&gt;
  },&lt;br /&gt;
    &lt;br /&gt;
  dbLog: function (message) {&lt;br /&gt;
  if (Boolean(DEBUG)) {&lt;br /&gt;
    console.log('Instant cquotes:' + message);&lt;br /&gt;
  }&lt;br /&gt;
  }, // dbLog()&lt;br /&gt;
    &lt;br /&gt;
  registerConfigurationOption: function(name,callback,hook) {&lt;br /&gt;
  // https://wiki.greasespot.net/GM_registerMenuCommand&lt;br /&gt;
  // https://wiki.greasespot.net/Greasemonkey_Manual:Monkey_Menu#The_Menu&lt;br /&gt;
    GM_registerMenuCommand(name, callback, hook);&lt;br /&gt;
  }, //registerMenuCommand()&lt;br /&gt;
    &lt;br /&gt;
  registerTrigger: function() {&lt;br /&gt;
    &lt;br /&gt;
    // TODO: we can use the following callback non-interactively, i.e. to trigger background tasks&lt;br /&gt;
// http://javascript.info/tutorial/onload-ondomcontentloaded&lt;br /&gt;
document.addEventListener(&amp;quot;DOMContentLoaded&amp;quot;, function(event) {&lt;br /&gt;
    console.log(&amp;quot;Instant Cquotes: DOM fully loaded and parsed&amp;quot;);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
window.addEventListener('load', init); // page fully loaded&lt;br /&gt;
Host.dbLog('Instant Cquotes: page load handler registered');&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    // Initialize (matching page loaded)&lt;br /&gt;
function init() {&lt;br /&gt;
  console.log('Instant Cquotes: page load handler invoked');&lt;br /&gt;
  var profile = getProfile();&lt;br /&gt;
  &lt;br /&gt;
  Host.dbLog(&amp;quot;Profile type is:&amp;quot;+profile.type);&lt;br /&gt;
  &lt;br /&gt;
  // Dispatch to correct event handler (depending on website/URL)&lt;br /&gt;
  // TODO: this stuff could/should be moved into the config hash itself&lt;br /&gt;
  &lt;br /&gt;
  if (profile.type=='wiki') {&lt;br /&gt;
    profile.event_handler(); // just for testing&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
   &lt;br /&gt;
    Host.dbLog('using default mode');&lt;br /&gt;
    document.onmouseup = instantCquote;&lt;br /&gt;
    // HACK: preparations for moving the the event/handler logic also into the profile hash, so that the wiki (edit mode) can be handled equally&lt;br /&gt;
    //eval(profile.event+&amp;quot;=instantCquote&amp;quot;);&lt;br /&gt;
     &lt;br /&gt;
} // init()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
  }, // registerTrigger&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
   download: function (url, callback, method='GET') {&lt;br /&gt;
  // http://wiki.greasespot.net/GM_xmlhttpRequest&lt;br /&gt;
     try {&lt;br /&gt;
  GM_xmlhttpRequest({&lt;br /&gt;
    method: method,&lt;br /&gt;
    url: url,&lt;br /&gt;
    onload: callback&lt;br /&gt;
  });&lt;br /&gt;
     }catch(e) {&lt;br /&gt;
       console.log(&amp;quot;download did not work&amp;quot;);&lt;br /&gt;
     }&lt;br /&gt;
  }, // download()&lt;br /&gt;
    &lt;br /&gt;
    // is only intended to work with archives supported by the  hash&lt;br /&gt;
    downloadPosting: function (url, EventHandler) {&lt;br /&gt;
      &lt;br /&gt;
    Host.download(url, function (response) {&lt;br /&gt;
    var profile = getProfile(url);&lt;br /&gt;
    var blob = response.responseText;&lt;br /&gt;
    var doc = Host.make_doc(blob,'text/html'); &lt;br /&gt;
    var result = {}; // hash to be returned&lt;br /&gt;
    &lt;br /&gt;
    [].forEach.call(['author','date','title','content'], function(field) {&lt;br /&gt;
      var xpath_query = '//' + profile[field].xpath;&lt;br /&gt;
      try {&lt;br /&gt;
       var value = Host.eval_xpath(doc, xpath_query).stringValue; &lt;br /&gt;
       //UI.alert(&amp;quot;extracted field value:&amp;quot;+value);&lt;br /&gt;
        &lt;br /&gt;
        // now apply all transformations, if any&lt;br /&gt;
       value = applyTransformations(value, profile[field].transform );&lt;br /&gt;
        &lt;br /&gt;
       result[field]=value; // store the extracted/transormed value in the hash that we pass on&lt;br /&gt;
      } // try&lt;br /&gt;
      catch(e) {&lt;br /&gt;
        UI.alert(&amp;quot;downloadPosting failed:\n&amp;quot;+ e.message);&lt;br /&gt;
      } // catch&lt;br /&gt;
    }); // forEach field&lt;br /&gt;
    &lt;br /&gt;
    EventHandler(result); // pass the result to the handler&lt;br /&gt;
    }); // call to Host.download() &lt;br /&gt;
      &lt;br /&gt;
    }, // downloadPosting()&lt;br /&gt;
    &lt;br /&gt;
    // TODO: add makeAJAXCall, and makeWikiCall here&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
    // turn a string/text blob into a DOM tree that can be queried (e.g. for xpath expressions)&lt;br /&gt;
    // FIXME: this is browser specific not GM specific ...&lt;br /&gt;
    make_doc: function(text, type='text/html') {&lt;br /&gt;
      // to support other browsers, see: https://developer.mozilla.org/en/docs/Web/API/DOMParser&lt;br /&gt;
      return new DOMParser().parseFromString(text,type);&lt;br /&gt;
    }, // make DOM document&lt;br /&gt;
    &lt;br /&gt;
    // xpath handling may be handled separately depending on browser/platform, so better encapsulate this&lt;br /&gt;
    // FIXME: this is browser specific not GM specific ...&lt;br /&gt;
    eval_xpath: function(doc, xpath, type=XPathResult.STRING_TYPE) {&lt;br /&gt;
      return doc.evaluate(xpath, doc, null, type, null);&lt;br /&gt;
    }, // eval_xpath&lt;br /&gt;
    &lt;br /&gt;
    set_persistent: function(key, value, json=false) &lt;br /&gt;
    {&lt;br /&gt;
      // transparently stringify to json&lt;br /&gt;
      if(json) {&lt;br /&gt;
        // http://stackoverflow.com/questions/16682150/store-a-persistent-list-between-sessions&lt;br /&gt;
        value = JSON.stringify (value);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      // https://wiki.greasespot.net/GM_setValue&lt;br /&gt;
      GM_setValue(key, value);&lt;br /&gt;
      //UI.alert('Saved value for key\n'+key+':'+value);&lt;br /&gt;
    }, // set_persistent&lt;br /&gt;
    &lt;br /&gt;
    get_persistent: function(key, default_value, json=false) {&lt;br /&gt;
     // https://wiki.greasespot.net/GM_getValue&lt;br /&gt;
    &lt;br /&gt;
      var value=GM_getValue(key, default_value);&lt;br /&gt;
      // transparently support JSON: http://stackoverflow.com/questions/16682150/store-a-persistent-list-between-sessions&lt;br /&gt;
      if(json) {&lt;br /&gt;
        value = JSON.parse (value)  ||  {};&lt;br /&gt;
      }&lt;br /&gt;
      return value;&lt;br /&gt;
    }, // get_persistent&lt;br /&gt;
&lt;br /&gt;
   setClipboard: function(msg) {&lt;br /&gt;
   // this being a greasemonkey user-script, we are not &lt;br /&gt;
   // subject to usual browser restrictions&lt;br /&gt;
   // http://wiki.greasespot.net/GM_setClipboard&lt;br /&gt;
   GM_setClipboard(msg);&lt;br /&gt;
  }, // setClipboard()&lt;br /&gt;
    &lt;br /&gt;
    getTemplate: function() {&lt;br /&gt;
    &lt;br /&gt;
    // hard-coded default template&lt;br /&gt;
    var template = '$CONTENT&amp;lt;ref&amp;gt;{{cite web\n' +&lt;br /&gt;
  '  |url    =  $URL \n' +&lt;br /&gt;
  '  |title  =  &amp;lt;nowiki&amp;gt; $TITLE &amp;lt;/nowiki&amp;gt; \n' +&lt;br /&gt;
  '  |author =  &amp;lt;nowiki&amp;gt; $AUTHOR &amp;lt;/nowiki&amp;gt; \n' +&lt;br /&gt;
  '  |date   =  $DATE \n' +&lt;br /&gt;
  '  |added  =  $ADDED \n' +&lt;br /&gt;
  '  |script_version = $SCRIPT_VERSION \n' +&lt;br /&gt;
  '  }}&amp;lt;/ref&amp;gt;\n';&lt;br /&gt;
     &lt;br /&gt;
    // return a saved template if found, fall back to hard-coded one above otherwise&lt;br /&gt;
    return Host.get_persistent('default_template', template);&lt;br /&gt;
    &lt;br /&gt;
  } // getTemplate&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
  } // end of GreaseMonkey environment, add other environments below&lt;br /&gt;
  &lt;br /&gt;
}; // Environment hash - intended to help encapsulate host specific stuff (APIs)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// the first thing we need to do is to determine what APIs are available&lt;br /&gt;
// and store everything in a Host hash, which is subsequently used for API lookups&lt;br /&gt;
// the Host hash contains all platform/browser-specific APIs&lt;br /&gt;
var Host = Environment.getHost();&lt;br /&gt;
Environment.validate(Host); // this checks the obtained host to see if all required dependencies are available&lt;br /&gt;
Host.init(); // run environment specific initialization code (e.g. logic for GreaseMonkey setup)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// move DEBUG handling to a persistent configuration flag so that we can configure this using a jQuery dialog (defaulted to false)&lt;br /&gt;
// TODO: move DEBUG variable to Environment hash / init() routine&lt;br /&gt;
var DEBUG = Host.get_persistent('debug_mode_enabled', false);&lt;br /&gt;
Host.dbLog(&amp;quot;Debug mode is:&amp;quot;+DEBUG);&lt;br /&gt;
function DEBUG_mode() {&lt;br /&gt;
  // reset script invocation counter for testing purposes&lt;br /&gt;
  Host.dbLog('Resetting script invocation counter');&lt;br /&gt;
  Host.set_persistent(GM_info.script.version, 0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if (DEBUG)&lt;br /&gt;
DEBUG_mode();&lt;br /&gt;
&lt;br /&gt;
// hash with supported websites/URLs,  includes xpath and regex expressions to extract certain fields, and a vector with optional transformations for post-processing each field&lt;br /&gt;
&lt;br /&gt;
var CONFIG = {&lt;br /&gt;
  // WIP: the first entry is special, i.e. it's not an actual list archive (source), but only added here so that the same script can be used&lt;br /&gt;
  // for editing the FlightGear wiki&lt;br /&gt;
  &lt;br /&gt;
  'FlightGear.wiki': {&lt;br /&gt;
    type: 'wiki',&lt;br /&gt;
    enabled: false,&lt;br /&gt;
    event: 'document.onmouseup', // when to invoke the event handler&lt;br /&gt;
    // TODO: move downloadWatchlist() etc here&lt;br /&gt;
    event_handler: function () {&lt;br /&gt;
      console.log('FlightGear wiki handler active (waiting to be populated)');&lt;br /&gt;
      // this is where the logic for a wiki mode can be added over time (for now, it's a NOP)&lt;br /&gt;
    &lt;br /&gt;
    //for each supported mode, invoke the trigger and call the corresponding handler&lt;br /&gt;
    [].forEach.call(CONFIG['FlightGear.wiki'].modes, function(mode) {&lt;br /&gt;
      //dbLog(&amp;quot;Checking trigger:&amp;quot;+mode.name);&lt;br /&gt;
      if(mode.trigger() ) {&lt;br /&gt;
        mode.handler();&lt;br /&gt;
      }&lt;br /&gt;
    });&lt;br /&gt;
      &lt;br /&gt;
    }, // the event handler to be invoked&lt;br /&gt;
    url_reg: '^(http|https)://wiki.flightgear.org', // ignore for now: not currently used by the wiki mode&lt;br /&gt;
    &lt;br /&gt;
    modes: [&lt;br /&gt;
      { name:'process-editSections',&lt;br /&gt;
        trigger: function() {return true;}, // match URL regex - return true for always match&lt;br /&gt;
       &lt;br /&gt;
        // the code implementing the mode&lt;br /&gt;
        handler: function() {&lt;br /&gt;
                &lt;br /&gt;
    var editSections = document.getElementsByClassName('mw-editsection');&lt;br /&gt;
    console.log('FlightGear wiki article, number of edit sections: '+editSections.length);&lt;br /&gt;
   &lt;br /&gt;
    // for now, just rewrite edit sections and add a note to them&lt;br /&gt;
   &lt;br /&gt;
     [].forEach.call(editSections, function (sec) {&lt;br /&gt;
       sec.appendChild(&lt;br /&gt;
         document.createTextNode(' (instant-cquotes is lurking) ')&lt;br /&gt;
       );&lt;br /&gt;
     }); //forEach section&lt;br /&gt;
        } // handler&lt;br /&gt;
       &lt;br /&gt;
       &lt;br /&gt;
      } // process-editSections&lt;br /&gt;
      // TODO: add other wiki modes below &lt;br /&gt;
      &lt;br /&gt;
    ] // modes&lt;br /&gt;
    &lt;br /&gt;
  }, // end of wiki profile&lt;br /&gt;
  &lt;br /&gt;
  'Sourceforge Mailing list': {&lt;br /&gt;
    enabled: true,&lt;br /&gt;
    type: 'archive',&lt;br /&gt;
    event: 'document.onmouseup', // when to invoke the event handler&lt;br /&gt;
    event_handler: instantCquote, // the event handler to be invoked&lt;br /&gt;
    url_reg: '^(http|https)://sourceforge.net/p/flightgear/mailman/.*/',&lt;br /&gt;
    content: {&lt;br /&gt;
      xpath: 'tbody/tr[2]/td/pre/text()', // NOTE this is only used by the downloadPosting  helper to retrieve the posting without having a selection (TODO:add content xpath to forum hash)&lt;br /&gt;
      selection: getSelectedText,&lt;br /&gt;
      idStyle: /msg[0-9]{8}/,&lt;br /&gt;
      parentTag: [&lt;br /&gt;
        'tagName',&lt;br /&gt;
        'PRE'&lt;br /&gt;
      ],&lt;br /&gt;
      transform: [],&lt;br /&gt;
    }, // content recipe&lt;br /&gt;
    // vector with tests to be executed for sanity checks (unit testing)&lt;br /&gt;
    tests: [&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://sourceforge.net/p/flightgear/mailman/message/35059454/',&lt;br /&gt;
        author: 'Erik Hofman',&lt;br /&gt;
        date: 'May 3rd, 2016', // NOTE: using the transformed date here &lt;br /&gt;
        title: 'Re: [Flightgear-devel] Auto altimeter setting at startup (?)'&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://sourceforge.net/p/flightgear/mailman/message/35059961/',&lt;br /&gt;
        author: 'Ludovic Brenta',&lt;br /&gt;
        date: 'May 3rd, 2016',&lt;br /&gt;
        title: 'Re: [Flightgear-devel] dual-control-tools and the limit on packet size'&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://sourceforge.net/p/flightgear/mailman/message/20014126/',&lt;br /&gt;
        author: 'Tim Moore',&lt;br /&gt;
        date: 'Aug 4th, 2008',&lt;br /&gt;
        title: 'Re: [Flightgear-devel] Cockpit displays (rendering, modelling)'&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://sourceforge.net/p/flightgear/mailman/message/23518343/',&lt;br /&gt;
        author: 'Tim Moore',&lt;br /&gt;
        date: 'Sep 10th, 2009',&lt;br /&gt;
        title: '[Flightgear-devel] Atmosphere patch from John Denker'&lt;br /&gt;
      } // add other tests below&lt;br /&gt;
&lt;br /&gt;
    ], // end of vector with self-tests&lt;br /&gt;
    // regex/xpath and transformations for extracting various required fields&lt;br /&gt;
    author: {&lt;br /&gt;
      xpath: 'tbody/tr[1]/td/div/small/text()',&lt;br /&gt;
      transform: [extract(/From: (.*) &amp;lt;.*@.*&amp;gt;/)]&lt;br /&gt;
    },&lt;br /&gt;
    title: {&lt;br /&gt;
      xpath: 'tbody/tr[1]/td/div/div[1]/b/a/text()',&lt;br /&gt;
      transform:[]&lt;br /&gt;
    },&lt;br /&gt;
    date: {&lt;br /&gt;
      xpath: 'tbody/tr[1]/td/div/small/text()',&lt;br /&gt;
      transform: [extract(/- (.*-.*-.*) /)]&lt;br /&gt;
    },&lt;br /&gt;
    url: {&lt;br /&gt;
      xpath: 'tbody/tr[1]/td/div/div[1]/b/a/@href',&lt;br /&gt;
      transform: [prepend('https://sourceforge.net')]&lt;br /&gt;
    }&lt;br /&gt;
  }, // end of mailing list profile&lt;br /&gt;
  // next website/URL (forum)&lt;br /&gt;
  'FlightGear forum': {&lt;br /&gt;
    enabled: true,&lt;br /&gt;
    type: 'archive',&lt;br /&gt;
    event: 'document.onmouseup', // when to invoke the event handler (not used atm)&lt;br /&gt;
    event_handler: null, // the event handler to be invoked (not used atm)&lt;br /&gt;
    url_reg: /https:\/\/forum\.flightgear\.org\/.*/,&lt;br /&gt;
    content: {&lt;br /&gt;
      xpath: '', //TODO: this must be added for downloadPosting() to work, or it cannot extract contents&lt;br /&gt;
      selection: getSelectedHtml,&lt;br /&gt;
      idStyle: /p[0-9]{6}/,&lt;br /&gt;
      parentTag: [&lt;br /&gt;
        'className',&lt;br /&gt;
        'content',&lt;br /&gt;
        'postbody'&lt;br /&gt;
      ],&lt;br /&gt;
      transform: [&lt;br /&gt;
        removeComments,&lt;br /&gt;
        forum_quote2cquote,&lt;br /&gt;
        forum_smilies2text,&lt;br /&gt;
        forum_fontstyle2wikistyle,&lt;br /&gt;
        forum_code2syntaxhighlight,&lt;br /&gt;
        img2link,&lt;br /&gt;
        a2wikilink,&lt;br /&gt;
        vid2wiki,&lt;br /&gt;
        list2wiki,&lt;br /&gt;
        forum_br2newline&lt;br /&gt;
      ]&lt;br /&gt;
    },&lt;br /&gt;
    // vector with tests to be executed for sanity checks (unit testing)&lt;br /&gt;
    // postings will be downloaded using the URL specified, and then the author/title &lt;br /&gt;
    // fields extracted using the outer regex and matched against what is expected&lt;br /&gt;
    // NOTE: forum postings can be edited, so that these tests would fail - thus, it makes sense to pick locked topics/postings for such tests&lt;br /&gt;
    tests: [&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://forum.flightgear.org/viewtopic.php?f=18&amp;amp;p=284108#p284108',&lt;br /&gt;
        author: 'mickybadia',&lt;br /&gt;
        date: 'May 3rd, 2016',&lt;br /&gt;
        title: 'OSM still PNG maps'&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://forum.flightgear.org/viewtopic.php?f=19&amp;amp;p=284120#p284120',&lt;br /&gt;
        author: 'Thorsten',&lt;br /&gt;
        date: 'May 3rd, 2016',&lt;br /&gt;
        title: 'Re: FlightGear\'s Screenshot Of The Month MAY 2016'&lt;br /&gt;
      },&lt;br /&gt;
       {&lt;br /&gt;
        url: 'https://forum.flightgear.org/viewtopic.php?f=71&amp;amp;t=29279&amp;amp;p=283455#p283446',&lt;br /&gt;
        author: 'Hooray',&lt;br /&gt;
         date: 'Apr 25th, 2016',&lt;br /&gt;
        title: 'Re: Best way to learn Canvas?'&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://forum.flightgear.org/viewtopic.php?f=4&amp;amp;t=1460&amp;amp;p=283994#p283994',&lt;br /&gt;
        author: 'bugman',&lt;br /&gt;
        date: 'May 2nd, 2016',&lt;br /&gt;
        title: 'Re: eurofighter typhoon'&lt;br /&gt;
      } // add other tests below&lt;br /&gt;
&lt;br /&gt;
    ], // end of vector with self-tests&lt;br /&gt;
    author: {&lt;br /&gt;
      xpath: 'div/div[1]/p/strong/a/text()',&lt;br /&gt;
      transform: [] // no transformations applied&lt;br /&gt;
    },&lt;br /&gt;
    title: {&lt;br /&gt;
      xpath: 'div/div[1]/h3/a/text()',&lt;br /&gt;
      transform: [] // no transformations applied&lt;br /&gt;
    },&lt;br /&gt;
    date: {&lt;br /&gt;
      xpath: 'div/div[1]/p/text()[2]',&lt;br /&gt;
      transform: [extract(/» (.*?[0-9]{4})/)]&lt;br /&gt;
    },&lt;br /&gt;
    url: {&lt;br /&gt;
      xpath: 'div/div[1]/p/a/@href',&lt;br /&gt;
      transform: [&lt;br /&gt;
        extract(/\.(.*)/),&lt;br /&gt;
        prepend('https://forum.flightgear.org')&lt;br /&gt;
      ] // transform vector&lt;br /&gt;
    } // url&lt;br /&gt;
  } // forum &lt;br /&gt;
}; // CONFIG has&lt;br /&gt;
&lt;br /&gt;
// hash to map URLs (wiki article, issue tracker, sourceforge link, forum thread etc) to existing wiki templates&lt;br /&gt;
var MatchURL2Templates = [&lt;br /&gt;
  // placeholder for now&lt;br /&gt;
 {&lt;br /&gt;
   name: 'rewrite sourceforge code links',&lt;br /&gt;
   url_reg: '',&lt;br /&gt;
   handler: function() {&lt;br /&gt;
   &lt;br /&gt;
 } // handler&lt;br /&gt;
  &lt;br /&gt;
 } // add other templates below&lt;br /&gt;
  &lt;br /&gt;
]; // MatchURL2Templates&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// output methods (alert and jQuery for now)&lt;br /&gt;
var OUTPUT = {&lt;br /&gt;
  // Shows a window.prompt() message box&lt;br /&gt;
  msgbox: function (msg) {&lt;br /&gt;
    UI.prompt('Copy to clipboard ' + Host.getScriptVersion(), msg);&lt;br /&gt;
    Host.setClipboard(msg);&lt;br /&gt;
  }, // msgbox&lt;br /&gt;
  &lt;br /&gt;
  // this is currently work-in-progress, and will need to be refactored sooner or later&lt;br /&gt;
  // for now, functionality matters more than elegant design/code :)&lt;br /&gt;
  jQueryTabbed: function(msg, original) {&lt;br /&gt;
  // FIXME: using backtics here makes the whole thing require ES6  ....&lt;br /&gt;
  var markup = $(`&amp;lt;div id=&amp;quot;tabs&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;ul&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#selection&amp;quot;&amp;gt;Selection&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#articles&amp;quot;&amp;gt;Articles&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#templates&amp;quot;&amp;gt;Templates&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#development&amp;quot;&amp;gt;Development&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#settings&amp;quot;&amp;gt;Settings&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#help&amp;quot;&amp;gt;Help&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#about&amp;quot;&amp;gt;About&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;/ul&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;selection&amp;quot;&amp;gt;This tab contains your extracted and post-processed selection, converted to proper wikimedia markup, including proper attribution.&lt;br /&gt;
  &amp;lt;div id=&amp;quot;content&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;label for=&amp;quot;template_select&amp;quot;&amp;gt;Select a template&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;select name=&amp;quot;template_select&amp;quot; id=&amp;quot;template_select&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;option&amp;gt;default&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option&amp;gt;cquote&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;/select&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;options&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;b&amp;gt;Note this is work-in-progress, i.e. not yet fully functional&amp;lt;/b&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
    &amp;lt;label for=&amp;quot;article_select&amp;quot;&amp;gt;Select an article to update&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;select name=&amp;quot;article_select&amp;quot; id=&amp;quot;article_select&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;news&amp;quot; label=&amp;quot;News&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;support&amp;quot; label=&amp;quot;Support&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;release&amp;quot; label=&amp;quot;Release&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;develop&amp;quot; label=&amp;quot;Development&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;watchlist&amp;quot; label=&amp;quot;Watchlist&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;/select&amp;gt;&lt;br /&gt;
    &amp;lt;p/&amp;gt;&lt;br /&gt;
    &amp;lt;label for=&amp;quot;section_select&amp;quot;&amp;gt;Select section:&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;select name=&amp;quot;section_select&amp;quot; id=&amp;quot;section_select&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;/select&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;articles&amp;quot;&amp;gt;This tab contains articles that you can directly access/edit using the mediawiki API&amp;lt;br/&amp;gt;&lt;br /&gt;
  Note: The watchlist is retrieved dynamically, so does not need to be edited here&amp;lt;br/&amp;gt;&lt;br /&gt;
    &amp;lt;label for=&amp;quot;article_select&amp;quot;&amp;gt;Select an article&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;select name=&amp;quot;article_select&amp;quot; id=&amp;quot;article_select&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;news&amp;quot; label=&amp;quot;News&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;support&amp;quot; label=&amp;quot;Support&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;develop&amp;quot; label=&amp;quot;Development&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;release&amp;quot; label=&amp;quot;Release&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;!-- the watchlist is retrieved dynamically, so omit it here &lt;br /&gt;
     &amp;lt;optgroup id=&amp;quot;watchlist&amp;quot; label=&amp;quot;Watchlist&amp;quot;/&amp;gt;&lt;br /&gt;
    --&amp;gt;&lt;br /&gt;
    &amp;lt;/select&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;button id=&amp;quot;article_new&amp;quot;&amp;gt;New&amp;lt;/button&amp;gt;&lt;br /&gt;
   &amp;lt;button id=&amp;quot;article_remove&amp;quot;&amp;gt;Remove&amp;lt;/button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div id=&amp;quot;edit_article&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;label for=&amp;quot;article_name&amp;quot;&amp;gt;Article&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;text&amp;quot; id=&amp;quot;article_name&amp;quot; name=&amp;quot;article_name&amp;quot;&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;label for=&amp;quot;article_url&amp;quot;&amp;gt;Link&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;text&amp;quot; id=&amp;quot;article_url&amp;quot; name=&amp;quot;article_url&amp;quot;&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;button id=&amp;quot;article_save&amp;quot;&amp;gt;Save&amp;lt;/button&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;templates&amp;quot;&amp;gt;This tab contains templates for different types of articles (newsletter, changelog, release plan etc)&amp;lt;p/&amp;gt;&lt;br /&gt;
  For now, this is WIP - in the future, there will be a dropdown menu added and all templates will be editable.&amp;lt;p/&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;template_header&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;label for=&amp;quot;template_select&amp;quot;&amp;gt;Select a template&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;select name=&amp;quot;template_select&amp;quot; id=&amp;quot;template_select&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;option&amp;gt;default&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option&amp;gt;cquote&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;/select&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;template_area&amp;quot;/&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;template_controls&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;button id=&amp;quot;template_save&amp;quot;&amp;gt;Save&amp;lt;/button&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;development&amp;quot;&amp;gt;This tab is a placeholder for features currently under development&amp;lt;p/&amp;gt;&lt;br /&gt;
  &amp;lt;button id=&amp;quot;evolve_regex&amp;quot;&amp;gt;Evolve regex&amp;lt;/button&amp;gt;&amp;lt;p/&amp;gt;&lt;br /&gt;
  &amp;lt;button id=&amp;quot;test_perceptron&amp;quot;&amp;gt;Test Perceptron&amp;lt;/button&amp;gt;&amp;lt;p/&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;output&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table id=&amp;quot;results&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;thead&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
     &amp;lt;th&amp;gt;Generation&amp;lt;/th&amp;gt;&lt;br /&gt;
     &amp;lt;th&amp;gt;Fitness&amp;lt;/th&amp;gt;&lt;br /&gt;
     &amp;lt;th&amp;gt;Expression&amp;lt;/th&amp;gt;&lt;br /&gt;
     &amp;lt;th&amp;gt;Result&amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
  &amp;lt;/thead&amp;gt;&lt;br /&gt;
  &amp;lt;tbody&amp;gt;&lt;br /&gt;
  &amp;lt;/tbody&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt; &lt;br /&gt;
&lt;br /&gt;
   &amp;lt;!--&lt;br /&gt;
   &amp;lt;textarea id=&amp;quot;devel_output&amp;quot; lines=&amp;quot;10&amp;quot;&amp;gt;&amp;lt;/textarea&amp;gt;&amp;lt;p/&amp;gt;&lt;br /&gt;
  --&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div id=&amp;quot;settings&amp;quot;&amp;gt;This tab will contain script specific settings&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;help&amp;quot;&amp;gt;One day, this tab may contain help....&amp;lt;p/&amp;gt;&amp;lt;button id=&amp;quot;helpButton&amp;quot;&amp;gt;Instant Cquotes&amp;lt;/button&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;about&amp;quot;&amp;gt;show some  script related information here&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;`); // tabs div&lt;br /&gt;
    &lt;br /&gt;
   var evolve_regex = $('div#development button#evolve_regex', markup);&lt;br /&gt;
   evolve_regex.click(function() {&lt;br /&gt;
     //alert(&amp;quot;Evolve regex&amp;quot;);&lt;br /&gt;
     evolve_expression_test();&lt;br /&gt;
   });&lt;br /&gt;
    &lt;br /&gt;
   var test_perceptron = $('div#development button#test_perceptron', markup);&lt;br /&gt;
   test_perceptron.click(function() {&lt;br /&gt;
     alert(&amp;quot;Test perceptron&amp;quot;);&lt;br /&gt;
   });&lt;br /&gt;
   &lt;br /&gt;
    &lt;br /&gt;
    // add dynamic elements to each tab&lt;br /&gt;
    &lt;br /&gt;
   // NOTE: this affects all template selectors, on all tabs&lt;br /&gt;
   $('select#template_select', markup).change(function() {&lt;br /&gt;
     UI.alert(&amp;quot;Sorry, templates are not yet fully implemented (WIP)&amp;quot;);&lt;br /&gt;
   });&lt;br /&gt;
    &lt;br /&gt;
   var help = $('#helpButton', markup);&lt;br /&gt;
   help.button();&lt;br /&gt;
   help.click(function() {&lt;br /&gt;
     window.open(&amp;quot;http://wiki.flightgear.org/FlightGear_wiki:Instant-Cquotes&amp;quot;);&lt;br /&gt;
   });&lt;br /&gt;
    &lt;br /&gt;
   // rows=&amp;quot;10&amp;quot;cols=&amp;quot;80&amp;quot; style=&amp;quot; width: 420px; height: 350px&amp;quot;&lt;br /&gt;
   var textarea = $('&amp;lt;textarea id=&amp;quot;quotedtext&amp;quot; rows=&amp;quot;20&amp;quot; cols=&amp;quot;70&amp;quot;/&amp;gt;');&lt;br /&gt;
   textarea.val(msg);&lt;br /&gt;
   $('#selection #content', markup).append(textarea);&lt;br /&gt;
  &lt;br /&gt;
   var templateArea = $('&amp;lt;textarea id=&amp;quot;template-edit&amp;quot; rows=&amp;quot;20&amp;quot; cols=&amp;quot;70&amp;quot;/&amp;gt;');&lt;br /&gt;
   templateArea.val( Host.getTemplate() );&lt;br /&gt;
   $('div#templates div#template_area', markup).append(templateArea);&lt;br /&gt;
   &lt;br /&gt;
   //$('#templates', markup).append($('&amp;lt;button&amp;gt;'));&lt;br /&gt;
    $('div#templates div#template_controls button#template_save',markup).button().click(function() {&lt;br /&gt;
      //UI.alert(&amp;quot;Saving template:\n&amp;quot;+templateArea.val() );&lt;br /&gt;
      &lt;br /&gt;
      Host.set_persistent('default_template',templateArea.val() );&lt;br /&gt;
    }); // save template&lt;br /&gt;
    &lt;br /&gt;
  // TODO: Currently, this is hard-coded, but should be made customizable via the &amp;quot;articles&amp;quot; tab at some point ...&lt;br /&gt;
  var articles = [&lt;br /&gt;
    // NOTE: category must match an existing &amp;lt;optgroup&amp;gt; above, title must match an existing wiki article&lt;br /&gt;
    {category:'support', name:'Frequently asked questions', url:''},&lt;br /&gt;
    {category:'support', name:'Asking for help', url:''},&lt;br /&gt;
    {category:'news', name:'Next newsletter', url:''},&lt;br /&gt;
    {category:'news', name:'Next changelog', url:''},&lt;br /&gt;
    {category:'release', name:'Release plan/Lessons learned', url:''}, // TODO: use wikimedia template&lt;br /&gt;
    {category:'develop', name:'Nasal library', url:''},&lt;br /&gt;
    {category:'develop', name:'Canvas Snippets', url:''},&lt;br /&gt;
    &lt;br /&gt;
  ];&lt;br /&gt;
    &lt;br /&gt;
    // TODO: this should be moved elsewhere&lt;br /&gt;
    function updateArticleList(selector) {&lt;br /&gt;
    $.each(articles, function (i, article) {&lt;br /&gt;
    $(selector+ ' optgroup#'+article.category, markup).append($('&amp;lt;option&amp;gt;', { &lt;br /&gt;
        value: article.name, // FIXME: just a placeholder for now&lt;br /&gt;
        text : article.name &lt;br /&gt;
    })); //append option&lt;br /&gt;
   }); // foreach&lt;br /&gt;
    } // updateArticleList&lt;br /&gt;
    &lt;br /&gt;
    // add the article list to the corresponding dropdown menus&lt;br /&gt;
    updateArticleList('select#article_select');&lt;br /&gt;
        &lt;br /&gt;
    // populate watchlist (prototype for now)&lt;br /&gt;
    // TODO: generalize &amp;amp; refactor: url, format&lt;br /&gt;
      &lt;br /&gt;
    // https://www.mediawiki.org/wiki/API:Watchlist&lt;br /&gt;
    // http://wiki.flightgear.org/api.php?action=query&amp;amp;list=watchlist&lt;br /&gt;
      var watchlist_url = 'http://wiki.flightgear.org/api.php?action=query&amp;amp;list=watchlist&amp;amp;format=json';&lt;br /&gt;
      Host.download(watchlist_url, function(response) {&lt;br /&gt;
        try {&lt;br /&gt;
       var watchlist = JSON.parse(response.responseText);&lt;br /&gt;
            &lt;br /&gt;
       //$('div#options select#section_select', markup).empty(); // delete all sections&lt;br /&gt;
      &lt;br /&gt;
      $.each(watchlist.query.watchlist, function (i, article) {&lt;br /&gt;
      $('div#options select#article_select optgroup#watchlist', markup).append($('&amp;lt;option&amp;gt;', { &lt;br /&gt;
        value: article.title, //FIXME just a placeholder for now&lt;br /&gt;
        text : article.title &lt;br /&gt;
    }));&lt;br /&gt;
   }); //foreach section&lt;br /&gt;
&lt;br /&gt;
        }&lt;br /&gt;
        catch (e) {&lt;br /&gt;
          UI.alert(&amp;quot;Could not download wiki watchlist\n&amp;quot;+watchlist.error.info);&lt;br /&gt;
        }&lt;br /&gt;
      }); // download &amp;amp; populate watchlist&lt;br /&gt;
      &lt;br /&gt;
    &lt;br /&gt;
    // register an event handler for the main tab, so that article specific sections can be retrieved&lt;br /&gt;
    $('div#options select#article_select', markup).change(function() {&lt;br /&gt;
      var article = this.value;&lt;br /&gt;
      &lt;br /&gt;
    // HACK: try to get a login token (actually not needed just for reading ...)&lt;br /&gt;
    Host.download('http://wiki.flightgear.org/api.php?action=query&amp;amp;prop=info|revisions&amp;amp;intoken=edit&amp;amp;rvprop=timestamp&amp;amp;titles=Main%20Page', function (response) {&lt;br /&gt;
    var message = 'FlightGear wiki login status (AJAX):';&lt;br /&gt;
    var status = response.statusText;&lt;br /&gt;
    &lt;br /&gt;
    // populate dropdown menu with article sections&lt;br /&gt;
    if (status === 'OK') {&lt;br /&gt;
    &lt;br /&gt;
      // Resolve redirects: https://www.mediawiki.org/wiki/API:Query#Resolving_redirects&lt;br /&gt;
      var section_url = 'http://wiki.flightgear.org/api.php?action=parse&amp;amp;page='+encodeURIComponent(article)+'&amp;amp;prop=sections&amp;amp;format=json&amp;amp;redirects';&lt;br /&gt;
      Host.download(section_url, function(response) {&lt;br /&gt;
        try {&lt;br /&gt;
       var sections = JSON.parse(response.responseText);&lt;br /&gt;
            &lt;br /&gt;
       $('div#options select#section_select', markup).empty(); // delete all sections&lt;br /&gt;
      &lt;br /&gt;
      $.each(sections.parse.sections, function (i, section) {&lt;br /&gt;
      $('div#options select#section_select', markup).append($('&amp;lt;option&amp;gt;', { &lt;br /&gt;
        value: section.line, //FIXME just a placeholder for now&lt;br /&gt;
        text : section.line &lt;br /&gt;
    }));&lt;br /&gt;
   }); //foreach section&lt;br /&gt;
&lt;br /&gt;
        }&lt;br /&gt;
        catch (e) {&lt;br /&gt;
          UI.alert(e.message);&lt;br /&gt;
        }&lt;br /&gt;
             &lt;br /&gt;
      }); //download sections&lt;br /&gt;
     &lt;br /&gt;
      &lt;br /&gt;
      &lt;br /&gt;
    } // login status is OK&lt;br /&gt;
&lt;br /&gt;
      &lt;br /&gt;
  }); // Host.download() call, i.e. we have a login token&lt;br /&gt;
      &lt;br /&gt;
    }); // on select change&lt;br /&gt;
    &lt;br /&gt;
  // init the tab stuff&lt;br /&gt;
  markup.tabs();&lt;br /&gt;
  &lt;br /&gt;
  var diagParam = {&lt;br /&gt;
      title: 'Instant Cquotes ' + Host.getScriptVersion(),&lt;br /&gt;
      modal: true,&lt;br /&gt;
      width: 700,&lt;br /&gt;
      buttons: [&lt;br /&gt;
        {&lt;br /&gt;
          text:'reported speech',&lt;br /&gt;
          click: function() {&lt;br /&gt;
            textarea.val(createCquote(original,true));&lt;br /&gt;
          }&lt;br /&gt;
        },&lt;br /&gt;
        &lt;br /&gt;
        {&lt;br /&gt;
          text: 'Copy',&lt;br /&gt;
          click: function () {&lt;br /&gt;
            Host.setClipboard(msg);&lt;br /&gt;
            $(this).dialog('close');&lt;br /&gt;
          }&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
      ]&lt;br /&gt;
  };&lt;br /&gt;
    &lt;br /&gt;
  // actually show our tabbed dialog using the params above&lt;br /&gt;
  markup.dialog(diagParam);&lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
  } // jQueryTabbed() &lt;br /&gt;
  &lt;br /&gt;
}; // output methods&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// TODO: we can use an online API to  help with some of this: http://www.eslnow.org/reported-speech-converter/&lt;br /&gt;
// See also: http://blog.mashape.com/list-of-25-natural-language-processing-apis/&lt;br /&gt;
// http://text-processing.com/docs/phrases.html&lt;br /&gt;
// http://www.alchemyapi.com/&lt;br /&gt;
// https://words.bighugelabs.com/api.php&lt;br /&gt;
// https://www.wordsapi.com/&lt;br /&gt;
// http://www.dictionaryapi.com/&lt;br /&gt;
// https://www.textrazor.com/&lt;br /&gt;
// http://www.programmableweb.com/news/how-5-natural-language-processing-apis-stack/analysis/2014/07/28&lt;br /&gt;
&lt;br /&gt;
var speechTransformations = [&lt;br /&gt;
// TODO: support aliasing using vectors: would/should &lt;br /&gt;
// ordering is crucial here (most specific first, least specific/most generic last)&lt;br /&gt;
 &lt;br /&gt;
// first, we start off  by expanding short forms: http://www.learnenglish.de/grammar/shortforms.html&lt;br /&gt;
// http://www.macmillandictionary.com/thesaurus-category/british/short-forms&lt;br /&gt;
 &lt;br /&gt;
  {query:/couldn\'t/gi, replacement:'could not'},&lt;br /&gt;
  {query:/I could not/gi, replacement:'$author could not'},&lt;br /&gt;
  &lt;br /&gt;
  {query:/I\'m/gi, replacement:'I am'},&lt;br /&gt;
  {query:/I am/gi, replacement:'$author is'},&lt;br /&gt;
  &lt;br /&gt;
  {query:/I\'ve/, replacement:'I have'},&lt;br /&gt;
  {query:/I have had/, replacement:'$author had'},&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  {query:/can(\'|\’)t/gi, replacement:'cannot'},&lt;br /&gt;
  &lt;br /&gt;
  {query:/I(\'|\’)ll/gi, replacement:'$author will'},&lt;br /&gt;
  {query:/I(\'|\’)d/gi, replacement:'$author would'},&lt;br /&gt;
  &lt;br /&gt;
  {query:/I have done/gi, replacement:'$author has done'},&lt;br /&gt;
  {query:/I\'ve done/gi, replacement:'$author has done'}, //FIXME. queries should really be vectors ...&lt;br /&gt;
  &lt;br /&gt;
  {query:/I believe/gi, replacement:'$author suggested'},&lt;br /&gt;
  {query:/I think/gi, replacement:'$author suggested'},&lt;br /&gt;
  {query:/I guess/gi, replacement:'$author believes'},&lt;br /&gt;
  &lt;br /&gt;
  {query:/I can see that/gi, replacement:'$author suggested that'},&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  {query:/I have got/gi, replacement:'$author has got'},&lt;br /&gt;
  {query:/I\'ve got/gi, replacement:'$author has got'},&lt;br /&gt;
  &lt;br /&gt;
  {query:/I\'d suggest/gi, replacement:'$author would suggest'},&lt;br /&gt;
  &lt;br /&gt;
  {query:/I\’m prototyping/gi, replacement:'$author is prototyping'},&lt;br /&gt;
  &lt;br /&gt;
  {query:/I myself/gi, replacement:'$author himself'},&lt;br /&gt;
  {query:/I am/gi, replacement:' $author is'},&lt;br /&gt;
  &lt;br /&gt;
  {query:/I can see/gi, replacement:'$author can see'},&lt;br /&gt;
  {query:/I can/gi, replacement:'$author can'},&lt;br /&gt;
  {query:/I have/gi, replacement:'$author has'},&lt;br /&gt;
  {query:/I should/g, replacement:'$author should'},&lt;br /&gt;
  {query:/I shall/gi, replacement:'$author shall'},&lt;br /&gt;
  {query:/I may/gi, replacement:'$author may'},&lt;br /&gt;
  {query:/I will/gi, replacement:'$author will'},&lt;br /&gt;
  {query:/I would/gi, replacement:'$author would'},&lt;br /&gt;
  {query:/by myself/gi, replacement:'by $author'},&lt;br /&gt;
  {query:/and I/gi, replacement:'and $author'},&lt;br /&gt;
  {query:/and me/gi, replacement:'and $author'},&lt;br /&gt;
  {query:/and myself/gi, replacement:'and $author'}&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  // least specific stuff last (broad/generic stuff is kept as is, with author clarification added in parentheses)&lt;br /&gt;
  /*&lt;br /&gt;
  {query:/I/, replacement:'I ($author)'},&lt;br /&gt;
  &lt;br /&gt;
  {query:/me/, replacement:'me ($author)'},&lt;br /&gt;
  {query:/my/, replacement:'my ($author)'},&lt;br /&gt;
  {query:/myself/, replacement:'myself ($author)'},&lt;br /&gt;
  {query:/mine/, replacement:'$author'}&lt;br /&gt;
  */&lt;br /&gt;
];&lt;br /&gt;
&lt;br /&gt;
// try to assist in transforming speech using the transformation vector passed in&lt;br /&gt;
// still needs to be exposed via the UI&lt;br /&gt;
function transformSpeech(text, author, gender, transformations) {&lt;br /&gt;
  // WIP: foreach transformation in vector, replace the search pattern with the matched string (replacing author/gender as applicable)&lt;br /&gt;
  //alert(&amp;quot;text to be transformed:\n&amp;quot;+text);&lt;br /&gt;
  for(var i=0;i&amp;lt; transformations.length; i++) {&lt;br /&gt;
    var token = transformations[i];&lt;br /&gt;
    // patch the replacement string using the correct author name &lt;br /&gt;
    var replacement = token.replacement.replace(/\$author/gi, author);&lt;br /&gt;
    text = text.replace(token.query, replacement);&lt;br /&gt;
  } // end of token transformation&lt;br /&gt;
  console.log(&amp;quot;transformed text is:&amp;quot;+text);&lt;br /&gt;
  return text;&lt;br /&gt;
} // transformSpeech&lt;br /&gt;
&lt;br /&gt;
// run a self-test&lt;br /&gt;
&lt;br /&gt;
(function() {&lt;br /&gt;
var author =&amp;quot;John Doe&amp;quot;;&lt;br /&gt;
var transformed = transformSpeech(&amp;quot;I have decided to commit a new feature&amp;quot;, author, null, speechTransformations );&lt;br /&gt;
if (transformed !== author+&amp;quot; has decided to commit a new feature&amp;quot;)&lt;br /&gt;
  Host.dbLog(&amp;quot;FIXME: Speech transformations are not working correctly&amp;quot;);&lt;br /&gt;
}) ();&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
var MONTHS = [&lt;br /&gt;
  'Jan',&lt;br /&gt;
  'Feb',&lt;br /&gt;
  'Mar',&lt;br /&gt;
  'Apr',&lt;br /&gt;
  'May',&lt;br /&gt;
  'Jun',&lt;br /&gt;
  'Jul',&lt;br /&gt;
  'Aug',&lt;br /&gt;
  'Sep',&lt;br /&gt;
  'Oct',&lt;br /&gt;
  'Nov',&lt;br /&gt;
  'Dec'&lt;br /&gt;
];&lt;br /&gt;
// Conversion for forum emoticons&lt;br /&gt;
var EMOTICONS = [&lt;br /&gt;
  [/:shock:/g,&lt;br /&gt;
  'O_O'],&lt;br /&gt;
  [&lt;br /&gt;
    /:lol:/g,&lt;br /&gt;
    '(lol)'&lt;br /&gt;
  ],&lt;br /&gt;
  [&lt;br /&gt;
    /:oops:/g,&lt;br /&gt;
    ':$'&lt;br /&gt;
  ],&lt;br /&gt;
  [&lt;br /&gt;
    /:cry:/g,&lt;br /&gt;
    ';('&lt;br /&gt;
  ],&lt;br /&gt;
  [&lt;br /&gt;
    /:evil:/g,&lt;br /&gt;
    '&amp;gt;:)'&lt;br /&gt;
  ],&lt;br /&gt;
  [&lt;br /&gt;
    /:twisted:/g,&lt;br /&gt;
    '3:)'&lt;br /&gt;
  ],&lt;br /&gt;
  [&lt;br /&gt;
    /:roll:/g,&lt;br /&gt;
    '(eye roll)'&lt;br /&gt;
  ],&lt;br /&gt;
  [&lt;br /&gt;
    /:wink:/g,&lt;br /&gt;
    ';)'&lt;br /&gt;
  ],&lt;br /&gt;
  [&lt;br /&gt;
    /:!:/g,&lt;br /&gt;
    '(!)'&lt;br /&gt;
  ],&lt;br /&gt;
  [&lt;br /&gt;
    /:\?:/g,&lt;br /&gt;
    '(?)'&lt;br /&gt;
  ],&lt;br /&gt;
  [&lt;br /&gt;
    /:idea:/g,&lt;br /&gt;
    '(idea)'&lt;br /&gt;
  ],&lt;br /&gt;
  [&lt;br /&gt;
    /:arrow:/g,&lt;br /&gt;
    '(-&amp;gt;)'&lt;br /&gt;
  ],&lt;br /&gt;
  [&lt;br /&gt;
    /:mrgreen:/g,&lt;br /&gt;
    'xD'&lt;br /&gt;
  ]&lt;br /&gt;
];&lt;br /&gt;
// ##################&lt;br /&gt;
// # Main functions #&lt;br /&gt;
// ##################&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// the required trigger is host specific (userscript vs. addon vs. android etc)&lt;br /&gt;
// for now, this merely wraps window.load mapping to the instantCquotoe callback below&lt;br /&gt;
Host.registerTrigger();&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// FIXME: function is currently referenced in CONFIG hash - event_handler, so cannot be easily moved across&lt;br /&gt;
// The main function&lt;br /&gt;
// TODO: split up, so that we can reuse the code elsewhere&lt;br /&gt;
function instantCquote(sel) {&lt;br /&gt;
  var profile = getProfile();&lt;br /&gt;
  &lt;br /&gt;
  // TODO: use config hash here&lt;br /&gt;
  var selection =  document.getSelection(),&lt;br /&gt;
  post_id=0;&lt;br /&gt;
  &lt;br /&gt;
  try {&lt;br /&gt;
    post_id = getPostId(selection, profile);&lt;br /&gt;
  } &lt;br /&gt;
  catch (error) {&lt;br /&gt;
    Host.dbLog('Failed extracting post id\nProfile:' + profile);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  if (selection.toString() === '') {&lt;br /&gt;
    Host.dbLog('No text is selected, aborting function');&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  if (!checkValid(selection, profile)) {&lt;br /&gt;
    Host.dbLog('Selection is not valid, aborting function');&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  try {&lt;br /&gt;
    transformationLoop(profile, post_id);&lt;br /&gt;
  }&lt;br /&gt;
  catch(e) {&lt;br /&gt;
    UI.alert(&amp;quot;Transformation loop:\n&amp;quot;+e.message);&lt;br /&gt;
  }&lt;br /&gt;
} // instantCquote&lt;br /&gt;
&lt;br /&gt;
  // TODO: this needs to be refactored so that it can be also reused by the async/AJAX mode&lt;br /&gt;
  // to extract fields in the background (i.e. move to a separate function)&lt;br /&gt;
function transformationLoop(profile, post_id) {&lt;br /&gt;
  var output = {}, field;&lt;br /&gt;
  Host.dbLog(&amp;quot;Starting extraction/transformation loop&amp;quot;);&lt;br /&gt;
  for (field in profile) {&lt;br /&gt;
    if (field === 'name') continue;&lt;br /&gt;
    if (field ==='type' || field === 'event' || field === 'event_handler') continue; // skip fields that don't contain xpath expressions&lt;br /&gt;
    Host.dbLog(&amp;quot;Extracting field using field id:&amp;quot;+post_id);&lt;br /&gt;
    var fieldData = extractFieldInfo(profile, post_id, field);&lt;br /&gt;
    var transform = profile[field].transform;&lt;br /&gt;
    if (transform !== undefined) {&lt;br /&gt;
      Host.dbLog('Field \'' + field + '\' before transformation:\n\'' + fieldData + '\'');&lt;br /&gt;
      fieldData = applyTransformations(fieldData, transform);&lt;br /&gt;
      Host.dbLog('Field \'' + field + '\' after transformation:\n\'' + fieldData + '\'');&lt;br /&gt;
    }&lt;br /&gt;
    output[field] = fieldData;&lt;br /&gt;
  } // extract and transform all fields for the current profile (website)&lt;br /&gt;
  Host.dbLog(&amp;quot;extraction and transformation loop finished&amp;quot;);&lt;br /&gt;
  output.content = stripWhitespace(output.content);&lt;br /&gt;
  &lt;br /&gt;
  var outputPlain = createCquote(output);&lt;br /&gt;
  outputText(outputPlain, output);&lt;br /&gt;
} // transformationLoop()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/// #############&lt;br /&gt;
&lt;br /&gt;
function runProfileTests() {&lt;br /&gt;
  &lt;br /&gt;
  for (var profile in CONFIG) {&lt;br /&gt;
    if (CONFIG[profile].type != 'archive' || !CONFIG[profile].enabled ) continue; // skip the wiki entry, because it's not an actual archive that we need to test&lt;br /&gt;
    // should be really moved to downloadPostign&lt;br /&gt;
    if (CONFIG[profile].content.xpath === '') console.log(&amp;quot;xpath for content extraction is empty, cannot procedurally extract contents&amp;quot;);&lt;br /&gt;
    for (var test in CONFIG[profile].tests) {&lt;br /&gt;
      var required_data = CONFIG[profile].tests[test];&lt;br /&gt;
      var title = required_data.title;&lt;br /&gt;
      //dbLog('Running test for posting titled:' + title);&lt;br /&gt;
      // fetch posting via getPostingDataAJAX() and compare to the fields we are looking for (author, title, date)&lt;br /&gt;
      //getPostingDataAJAX(profile, required_data.url);&lt;br /&gt;
      //alert(&amp;quot;required title:&amp;quot;+title);&lt;br /&gt;
    } // foreach test&lt;br /&gt;
&lt;br /&gt;
  } // foreach profile (website)&lt;br /&gt;
  &lt;br /&gt;
} //runProfileTests&lt;br /&gt;
&lt;br /&gt;
function selfCheckDialog() {&lt;br /&gt;
  var sections = '&amp;lt;h3&amp;gt;Important APIs:&amp;lt;/h3&amp;gt;&amp;lt;div id=&amp;quot;api_checks&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;';&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  try {&lt;br /&gt;
   runProfileTests.call(undefined); // check website profiles&lt;br /&gt;
  }&lt;br /&gt;
  catch (e) {&lt;br /&gt;
      UI.alert(e.message);&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  for (var profile in CONFIG) {&lt;br /&gt;
    // TODO: also check if enabled or not&lt;br /&gt;
    if (CONFIG[profile].type != 'archive') continue; // skip the wiki entry, because it's not an actual archive that we need to test&lt;br /&gt;
    var test_results = '';&lt;br /&gt;
    for (var test in CONFIG[profile].tests) {&lt;br /&gt;
      // var fieldData = extractFieldInfo(profile, post_id, 'author');&lt;br /&gt;
      test_results += CONFIG[profile].tests[test].title + '&amp;lt;p/&amp;gt;';&lt;br /&gt;
    }&lt;br /&gt;
    sections +='&amp;lt;h3&amp;gt;' + profile + ':&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;'+ CONFIG[profile].url_reg+'&amp;lt;/font&amp;gt;&amp;lt;/h3&amp;gt;&amp;lt;div&amp;gt;&amp;lt;p&amp;gt;' + test_results + '&amp;lt;/p&amp;gt;&amp;lt;/div&amp;gt;\n';&lt;br /&gt;
  }  // https://jqueryui.com/accordion/&lt;br /&gt;
  &lt;br /&gt;
 &lt;br /&gt;
  var checkDlg = $('&amp;lt;div id=&amp;quot;selfCheck&amp;quot; title=&amp;quot;Self Check dialog&amp;quot;&amp;gt;&amp;lt;p&amp;gt;&amp;lt;div id=&amp;quot;accordion&amp;quot;&amp;gt;' + sections + '&amp;lt;/div&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;/div&amp;gt;');&lt;br /&gt;
  &lt;br /&gt;
   // run all API tests, invoke the callback to obtain the status&lt;br /&gt;
  Environment.runAPITests(Host, function(meta) {&lt;br /&gt;
  &lt;br /&gt;
  //console.log('Running API test '+meta.name);&lt;br /&gt;
    &lt;br /&gt;
  meta.test(function(result) {&lt;br /&gt;
   var status = (result)?'success':'fail';&lt;br /&gt;
   var test = $(&amp;quot;&amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&amp;quot;).text('Running API test '+meta.name+':'+status); &lt;br /&gt;
   $('#api_checks', checkDlg).append(test);&lt;br /&gt;
  }); // update tests results&lt;br /&gt;
    &lt;br /&gt;
  }); // runAPITests&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  /*&lt;br /&gt;
  [].forEach.call(CONFIG, function(profile) {&lt;br /&gt;
    alert(&amp;quot;profile is:&amp;quot;+profile);&lt;br /&gt;
  [].forEach.call(CONFIG[profile].tests, function(test) {&lt;br /&gt;
    &lt;br /&gt;
    //UI.alert(test.url);&lt;br /&gt;
    Host.downloadPosting(test.url, function(downloaded) {&lt;br /&gt;
      alert(&amp;quot;downloaded:&amp;quot;);&lt;br /&gt;
      //if (test.title == downloaded.title) alert(&amp;quot;titles match:&amp;quot;+test.title);&lt;br /&gt;
    }); //downloadPosting&lt;br /&gt;
  }); //forEach test&lt;br /&gt;
  }); //forEach profile&lt;br /&gt;
  */&lt;br /&gt;
  &lt;br /&gt;
  //$('#accordion',checkDlg).accordion();&lt;br /&gt;
  checkDlg.dialog({&lt;br /&gt;
    width: 700,&lt;br /&gt;
    height: 500,&lt;br /&gt;
    open: function () {&lt;br /&gt;
      // http://stackoverflow.com/questions/2929487/putting-a-jquery-ui-accordion-in-a-jquery-ui-dialog&lt;br /&gt;
      $('#accordion').accordion({&lt;br /&gt;
        autoHeight: true&lt;br /&gt;
      });&lt;br /&gt;
    }&lt;br /&gt;
  }); // show dialog&lt;br /&gt;
} // selfCheckDialog&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// show a simple configuration dialog (WIP)&lt;br /&gt;
function setupDialog() {&lt;br /&gt;
  //alert(&amp;quot;configuration dialog is not yet implemented&amp;quot;);&lt;br /&gt;
  var checked = (Host.get_persistent('debug_mode_enabled', false) === true) ? 'checked' : '';&lt;br /&gt;
  //dbLog(&amp;quot;value is:&amp;quot;+get_persistent(&amp;quot;debug_mode_enabled&amp;quot;));&lt;br /&gt;
  //dbLog(&amp;quot;persistent debug flag is:&amp;quot;+checked);&lt;br /&gt;
  var setupDiv = $('&amp;lt;div id=&amp;quot;setupDialog&amp;quot; title=&amp;quot;Setup dialog&amp;quot;&amp;gt;NOTE: this configuration dialog is still work-in-progress&amp;lt;/p&amp;gt;&amp;lt;label&amp;gt;&amp;lt;input id=&amp;quot;debugcb&amp;quot; type=&amp;quot;checkbox&amp;quot;' + checked + '&amp;gt;Enable Debug mode&amp;lt;/label&amp;gt;&amp;lt;p/&amp;gt;&amp;lt;div id=&amp;quot;progressbar&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;');&lt;br /&gt;
  setupDiv.click(function () {&lt;br /&gt;
    //alert(&amp;quot;changing persistent debug state&amp;quot;);&lt;br /&gt;
    Host.set_persistent('debug_mode_enabled', $('#debugcb').is(':checked'));&lt;br /&gt;
  });&lt;br /&gt;
  //MediaWiki editing stub, based on: https://www.mediawiki.org/wiki/API:Edit#Editing_via_Ajax&lt;br /&gt;
  //only added here to show some status info in the setup dialog&lt;br /&gt;
  Host.download('http://wiki.flightgear.org/api.php?action=query&amp;amp;prop=info|revisions&amp;amp;intoken=edit&amp;amp;rvprop=timestamp&amp;amp;titles=Main%20Page', function (response) {&lt;br /&gt;
    var message = 'FlightGear wiki login status (AJAX):';&lt;br /&gt;
    var status = response.statusText;&lt;br /&gt;
    var color = (status == 'OK') ? 'green' : 'red';&lt;br /&gt;
    Host.dbLog(message + status);&lt;br /&gt;
    var statusDiv = $('&amp;lt;p&amp;gt;' + message + status + '&amp;lt;/p&amp;gt;').css('color', color);&lt;br /&gt;
    setupDiv.append(statusDiv);&lt;br /&gt;
  });&lt;br /&gt;
  setupDiv.dialog();&lt;br /&gt;
} // setupDialog&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// this  can be used to download/cache $FG_ROOT/options.xml so that fgfs CLI arguments can be recognized and post-processed automatically&lt;br /&gt;
// which can help transforming postings correctly&lt;br /&gt;
function downloadOptionsXML() {&lt;br /&gt;
&lt;br /&gt;
  // download $FG_ROOT/options.xml&lt;br /&gt;
          Host.download(&amp;quot;https://sourceforge.net/p/flightgear/fgdata/ci/next/tree/options.xml?format=raw&amp;quot;, function(response) {&lt;br /&gt;
            var xml = response.responseText;&lt;br /&gt;
            var doc = Host.make_doc(xml, 'text/xml');&lt;br /&gt;
            // https://developer.mozilla.org/en-US/docs/Web/API/XPathResult&lt;br /&gt;
            var options = Host.eval_xpath(doc, '//*/option', XPathResult.ORDERED_NODE_SNAPSHOT_TYPE);&lt;br /&gt;
            &lt;br /&gt;
            // http://help.dottoro.com/ljgnejkp.php&lt;br /&gt;
            Host.dbLog(&amp;quot;Number of options found in options.xml:&amp;quot;+options.snapshotLength);&lt;br /&gt;
            &lt;br /&gt;
            // http://help.dottoro.com/ljtfvvpx.php&lt;br /&gt;
            &lt;br /&gt;
              // https://sourceforge.net/p/flightgear/fgdata/ci/next/tree/options.xml&lt;br /&gt;
              &lt;br /&gt;
            &lt;br /&gt;
          }); // end of options.xml download&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
} // downloadOptionsXML&lt;br /&gt;
&lt;br /&gt;
function getProfile(url=undefined) {&lt;br /&gt;
  &lt;br /&gt;
  if(url === undefined) &lt;br /&gt;
    url=window.location.href;&lt;br /&gt;
  else&lt;br /&gt;
    url=url;&lt;br /&gt;
  &lt;br /&gt;
  Host.dbLog(&amp;quot;getProfile call URL is:&amp;quot;+url);&lt;br /&gt;
  &lt;br /&gt;
  for (var profile in CONFIG) {&lt;br /&gt;
    if (url.match(CONFIG[profile].url_reg) !== null) {&lt;br /&gt;
      Host.dbLog('Matching website profile found');&lt;br /&gt;
      var invocations = Host.get_persistent(Host.getScriptVersion(), 0);&lt;br /&gt;
      Host.dbLog('Number of script invocations for version ' + Host.getScriptVersion() + ' is:' + invocations);&lt;br /&gt;
&lt;br /&gt;
      // determine if we want to show a config dialog&lt;br /&gt;
      if (invocations === 0) {&lt;br /&gt;
        Host.dbLog(&amp;quot;ask for config dialog to be shown&amp;quot;);&lt;br /&gt;
        var response = UI.confirm('This is your first time running version ' + Host.getScriptVersion() + '\nConfigure now?');&lt;br /&gt;
        if (response) {&lt;br /&gt;
                  &lt;br /&gt;
          // show configuration dialog (jQuery)&lt;br /&gt;
          setupDialog();&lt;br /&gt;
        } &lt;br /&gt;
        else {&lt;br /&gt;
        } // don't configure&lt;br /&gt;
&lt;br /&gt;
      }      &lt;br /&gt;
      &lt;br /&gt;
      // increment number of invocations, use the script's version number as the key, to prevent the config dialog from showing up again (except for updated scripts)&lt;br /&gt;
      // FIXME: this is triggered/incremented by each click ...&lt;br /&gt;
      Host.dbLog(&amp;quot;increment number of script invocations&amp;quot;);&lt;br /&gt;
      Host.set_persistent(Host.getScriptVersion(), invocations + 1);&lt;br /&gt;
      return CONFIG[profile];&lt;br /&gt;
    } // matched website profile&lt;br /&gt;
    Host.dbLog('Could not find matching URL in getProfile() call!');&lt;br /&gt;
  } // for each profile&lt;br /&gt;
}// Get the HTML code that is selected&lt;br /&gt;
&lt;br /&gt;
function getSelectedHtml() {&lt;br /&gt;
  // From http://stackoverflow.com/a/6668159&lt;br /&gt;
  var html = '',&lt;br /&gt;
  selection = document.getSelection();&lt;br /&gt;
  if (selection.rangeCount) {&lt;br /&gt;
    var container = document.createElement('div');&lt;br /&gt;
    for (var i = 0; i &amp;lt; selection.rangeCount; i++) {&lt;br /&gt;
      container.appendChild(selection.getRangeAt(i).cloneContents());&lt;br /&gt;
    }&lt;br /&gt;
    html = container.innerHTML;&lt;br /&gt;
  }&lt;br /&gt;
  Host.dbLog('instantCquote(): Unprocessed HTML\n\'' + html + '\'');&lt;br /&gt;
  return html;&lt;br /&gt;
}// Gets the selected text&lt;br /&gt;
&lt;br /&gt;
function getSelectedText() {&lt;br /&gt;
  return document.getSelection().toString();&lt;br /&gt;
}// Get the ID of the post&lt;br /&gt;
// (this needs some work so that it can be used by the AJAX mode, without an actual selection)&lt;br /&gt;
&lt;br /&gt;
function getPostId(selection, profile, focus) {&lt;br /&gt;
  if (focus !== undefined) {&lt;br /&gt;
    Host.dbLog(&amp;quot;Trying to get PostId with defined focus&amp;quot;);&lt;br /&gt;
    selection = selection.focusNode.parentNode;&lt;br /&gt;
  } else {&lt;br /&gt;
    Host.dbLog(&amp;quot;Trying to get PostId with undefined focus&amp;quot;);&lt;br /&gt;
    selection = selection.anchorNode.parentNode;&lt;br /&gt;
  }&lt;br /&gt;
  while (selection.id.match(profile.content.idStyle) === null) {&lt;br /&gt;
    selection = selection.parentNode;&lt;br /&gt;
  }&lt;br /&gt;
  Host.dbLog(&amp;quot;Selection id is:&amp;quot;+selection.id);&lt;br /&gt;
  return selection.id;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Checks that the selection is valid&lt;br /&gt;
function checkValid(selection, profile) {&lt;br /&gt;
  var ret = true,&lt;br /&gt;
  selection_cp = {&lt;br /&gt;
  },&lt;br /&gt;
  tags = profile.content.parentTag;&lt;br /&gt;
  for (var n = 0; n &amp;lt; 2; n++) {&lt;br /&gt;
    if (n === 0) {&lt;br /&gt;
      selection_cp = selection.anchorNode.parentNode;&lt;br /&gt;
    } else {&lt;br /&gt;
      selection_cp = selection.focusNode.parentNode;&lt;br /&gt;
    }&lt;br /&gt;
    while (true) {&lt;br /&gt;
      if (selection_cp.tagName === 'BODY') {&lt;br /&gt;
        ret = false;&lt;br /&gt;
        break;&lt;br /&gt;
      } else {&lt;br /&gt;
        var cont = false;&lt;br /&gt;
        for (var i = 0; i &amp;lt; tags.length; i++) {&lt;br /&gt;
          if (selection_cp[tags[0]] === tags[i]) {&lt;br /&gt;
            cont = true;&lt;br /&gt;
            break;&lt;br /&gt;
          }&lt;br /&gt;
        }&lt;br /&gt;
        if (cont) {&lt;br /&gt;
          break;&lt;br /&gt;
        } else {&lt;br /&gt;
          selection_cp = selection_cp.parentNode;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  ret = ret &amp;amp;&amp;amp; (getPostId(selection, profile) === getPostId(selection, profile, 1));&lt;br /&gt;
  return ret;&lt;br /&gt;
}// Extracts the raw text from a certain place, using an XPath&lt;br /&gt;
&lt;br /&gt;
function extractFieldInfo(profile, id, field) {&lt;br /&gt;
  &lt;br /&gt;
  if (field === 'content') {&lt;br /&gt;
    Host.dbLog(&amp;quot;Returning content (selection)&amp;quot;);&lt;br /&gt;
    return profile[field].selection();&lt;br /&gt;
  } else {&lt;br /&gt;
    Host.dbLog(&amp;quot;Extracting field via xpath:&amp;quot;+field);&lt;br /&gt;
    var xpath = '//*[@id=&amp;quot;' + id + '&amp;quot;]/' + profile[field].xpath;&lt;br /&gt;
    return Host.eval_xpath(document, xpath).stringValue; // document.evaluate(xpath, document, null, XPathResult.STRING_TYPE, null).stringValue;&lt;br /&gt;
  }&lt;br /&gt;
}// Change the text using specified transformations&lt;br /&gt;
&lt;br /&gt;
function applyTransformations(fieldInfo, trans) { &lt;br /&gt;
    for (var i = 0; i &amp;lt; trans.length; i++) {&lt;br /&gt;
      fieldInfo = trans[i](fieldInfo);&lt;br /&gt;
      Host.dbLog('applyTransformations(): Multiple transformation, transformation after loop #' + (i + 1) + ':\n\'' + fieldInfo + '\'');&lt;br /&gt;
    }&lt;br /&gt;
    return fieldInfo;&lt;br /&gt;
  &lt;br /&gt;
} //applyTransformations&lt;br /&gt;
&lt;br /&gt;
// Formats the quote&lt;br /&gt;
&lt;br /&gt;
function createCquote(data, indirect_speech=false) {&lt;br /&gt;
 if(!indirect_speech)&lt;br /&gt;
   return nonQuotedRef(data); // conventional/verbatim selection&lt;br /&gt;
  else { &lt;br /&gt;
    // pattern match the content using a vector of regexes&lt;br /&gt;
    data.content = transformSpeech(data.content, data.author, null, speechTransformations );&lt;br /&gt;
    return nonQuotedRef(data);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function nonQuotedRef(data) { //TODO: rename &lt;br /&gt;
  var template = Host.getTemplate();&lt;br /&gt;
  &lt;br /&gt;
  var substituted = template&lt;br /&gt;
  .replace('$CONTENT', data.content)&lt;br /&gt;
  .replace('$URL',data.url)&lt;br /&gt;
  .replace('$TITLE',data.title)  &lt;br /&gt;
  .replace('$AUTHOR',data.author)&lt;br /&gt;
  .replace('$DATE',datef(data.date))&lt;br /&gt;
  .replace('$ADDED',datef(data.date))&lt;br /&gt;
  .replace('$SCRIPT_VERSION', Host.getScriptVersion() );&lt;br /&gt;
  &lt;br /&gt;
  return substituted; &lt;br /&gt;
}// &lt;br /&gt;
&lt;br /&gt;
// Output the text.&lt;br /&gt;
// Tries the jQuery dialog, and falls back to window.prompt()&lt;br /&gt;
&lt;br /&gt;
function outputText(msg, original) {&lt;br /&gt;
  try {&lt;br /&gt;
    OUTPUT.jQueryTabbed(msg, original); &lt;br /&gt;
  } &lt;br /&gt;
  catch (err) {&lt;br /&gt;
    msg = msg.replace(/&amp;amp;lt;\/syntaxhighligh(.)&amp;gt;/g, '&amp;lt;/syntaxhighligh$1');&lt;br /&gt;
    OUTPUT.msgbox(msg);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// #############&lt;br /&gt;
// # Utilities #&lt;br /&gt;
// #############&lt;br /&gt;
&lt;br /&gt;
function extract(regex) {&lt;br /&gt;
  return function (text) {&lt;br /&gt;
    return text.match(regex) [1];&lt;br /&gt;
  };&lt;br /&gt;
}&lt;br /&gt;
function prepend(prefix) {&lt;br /&gt;
  return function (text) {&lt;br /&gt;
    return prefix + text;&lt;br /&gt;
  };&lt;br /&gt;
}&lt;br /&gt;
function removeComments(html) {&lt;br /&gt;
  return html.replace(/&amp;lt;!--.*?--&amp;gt;/g, '');&lt;br /&gt;
}// Not currently used (as of June 2015), but kept just in case&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// currently unused&lt;br /&gt;
function escapePipes(html) {&lt;br /&gt;
  html = html.replace(/\|\|/g, '{{!!}n}');&lt;br /&gt;
  html = html.replace(/\|\-/g, '{{!-}}');&lt;br /&gt;
  return html.replace(/\|/g, '{{!}}');&lt;br /&gt;
}// Converts HTML &amp;lt;a href=&amp;quot;...&amp;quot;&amp;gt;...&amp;lt;/a&amp;gt; tags to wiki links, internal if possible.&lt;br /&gt;
&lt;br /&gt;
function a2wikilink(html) {&lt;br /&gt;
  // Links to wiki images, because&lt;br /&gt;
  // they need special treatment, or else they get displayed.&lt;br /&gt;
  html = html.replace(/&amp;lt;a.*?href=&amp;quot;http:\/\/wiki\.flightgear\.org\/File:(.*?)&amp;quot;.*?&amp;gt;(.*?)&amp;lt;\/a&amp;gt;/g, '[[Media:$1|$2]]');&lt;br /&gt;
  // Wiki links without custom text.&lt;br /&gt;
  html = html.replace(/&amp;lt;a.*?href=&amp;quot;http:\/\/wiki\.flightgear\.org\/(.*?)&amp;quot;.*?&amp;gt;http:\/\/wiki\.flightgear\.org\/.*?&amp;lt;\/a&amp;gt;/g, '[[$1]]');&lt;br /&gt;
  // Links to the wiki with custom text&lt;br /&gt;
  html = html.replace(/&amp;lt;a.*?href=&amp;quot;http:\/\/wiki\.flightgear\.org\/(.*?)&amp;quot;.*?&amp;gt;(.*?)&amp;lt;\/a&amp;gt;/g, '[[$1|$2]]');&lt;br /&gt;
  // Remove underscores from all wiki links&lt;br /&gt;
  var list = html.match(/\[\[.*?\]\]/g);&lt;br /&gt;
  if (list !== null) {&lt;br /&gt;
    for (var i = 0; i &amp;lt; list.length; i++) {&lt;br /&gt;
      html = html.replace(list[i], underscore2Space(list[i]));&lt;br /&gt;
    }&lt;br /&gt;
  }  // Convert non-wiki links&lt;br /&gt;
  // TODO: identify forum/devel list links, and use the AJAX/Host.download helper to get a title/subject for unnamed links (using the existing xpath/regex helpers for that)&lt;br /&gt;
&lt;br /&gt;
  html = html.replace(/&amp;lt;a.*?href=&amp;quot;(.*?)&amp;quot;.*?&amp;gt;(.*?)&amp;lt;\/a&amp;gt;/g, '[$1 $2]');&lt;br /&gt;
  // Remove triple dots from external links.&lt;br /&gt;
  // Replace with raw URL (MediaWiki converts it to a link).&lt;br /&gt;
  list = html.match(/\[.*?(\.\.\.).*?\]/g);&lt;br /&gt;
  if (list !== null) {&lt;br /&gt;
    for (var i = 0; i &amp;lt; list.length; i++) {&lt;br /&gt;
      html = html.replace(list[i], list[i].match(/\[(.*?) .*?\]/) [1]);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return html;&lt;br /&gt;
}// Converts images, including images in &amp;lt;a&amp;gt; links&lt;br /&gt;
&lt;br /&gt;
function img2link(html) {&lt;br /&gt;
  html = html.replace(/&amp;lt;a[^&amp;lt;]*?href=&amp;quot;([^&amp;lt;]*?)&amp;quot;[^&amp;lt;]*?&amp;gt;&amp;lt;img.*?src=&amp;quot;http:\/\/wiki\.flightgear\.org\/images\/.*?\/.*?\/(.*?)&amp;quot;.*?&amp;gt;&amp;lt;\/a&amp;gt;/g, '[[File:$2|250px|link=$1]]');&lt;br /&gt;
  html = html.replace(/&amp;lt;img.*?src=&amp;quot;http:\/\/wiki\.flightgear\.org\/images\/.*?\/.*?\/(.*?)&amp;quot;.*?&amp;gt;/g, '[[File:$1|250px]]');&lt;br /&gt;
  html = html.replace(/&amp;lt;a[^&amp;lt;]*?href=&amp;quot;([^&amp;lt;]*?)&amp;quot;[^&amp;lt;]*?&amp;gt;&amp;lt;img.*?src=&amp;quot;(.*?)&amp;quot;.*?&amp;gt;&amp;lt;\/a&amp;gt;/g, '(see [$2 image], links to [$1 here])');&lt;br /&gt;
  return html.replace(/&amp;lt;img.*?src=&amp;quot;(.*?)&amp;quot;.*?&amp;gt;/g, '(see the [$1 linked image])');&lt;br /&gt;
}// Converts smilies&lt;br /&gt;
&lt;br /&gt;
function forum_smilies2text(html) {&lt;br /&gt;
  html = html.replace(/&amp;lt;img src=&amp;quot;\.\/images\/smilies\/icon_.*?\.gif&amp;quot; alt=&amp;quot;(.*?)&amp;quot;.*?&amp;gt;/g, '$1');&lt;br /&gt;
  for (var i = 0; i &amp;lt; EMOTICONS.length; i++) {&lt;br /&gt;
    html = html.replace(EMOTICONS[i][0], EMOTICONS[i][1]);&lt;br /&gt;
  }&lt;br /&gt;
  return html;&lt;br /&gt;
}// Converts font formatting&lt;br /&gt;
&lt;br /&gt;
function forum_fontstyle2wikistyle(html) {&lt;br /&gt;
  html = html.replace(/&amp;lt;span style=&amp;quot;font-weight: bold&amp;quot;&amp;gt;(.*?)&amp;lt;\/span&amp;gt;/g, '\'\'\'$1\'\'\'');&lt;br /&gt;
  html = html.replace(/&amp;lt;span style=&amp;quot;text-decoration: underline&amp;quot;&amp;gt;(.*?)&amp;lt;\/span&amp;gt;/g, '&amp;lt;u&amp;gt;$1&amp;lt;/u&amp;gt;');&lt;br /&gt;
  html = html.replace(/&amp;lt;span style=&amp;quot;font-style: italic&amp;quot;&amp;gt;(.*?)&amp;lt;\/span&amp;gt;/g, '\'\'$1\'\'');&lt;br /&gt;
  return html.replace(/&amp;lt;span class=&amp;quot;posthilit&amp;quot;&amp;gt;(.*?)&amp;lt;\/span&amp;gt;/g, '$1');&lt;br /&gt;
}// Converts code blocks&lt;br /&gt;
&lt;br /&gt;
function forum_code2syntaxhighlight(html) {&lt;br /&gt;
  var list = html.match(/&amp;lt;dl class=&amp;quot;codebox&amp;quot;&amp;gt;.*?&amp;lt;code&amp;gt;(.*?)&amp;lt;\/code&amp;gt;.*?&amp;lt;\/dl&amp;gt;/g),&lt;br /&gt;
  data = [&lt;br /&gt;
  ];&lt;br /&gt;
  if (list === null) return html;&lt;br /&gt;
  for (var n = 0; n &amp;lt; list.length; n++) {&lt;br /&gt;
    data = html.match(/&amp;lt;dl class=&amp;quot;codebox&amp;quot;&amp;gt;.*?&amp;lt;code&amp;gt;(.*?)&amp;lt;\/code&amp;gt;.*?&amp;lt;\/dl&amp;gt;/);&lt;br /&gt;
    html = html.replace(data[0], processCode(data));&lt;br /&gt;
  }&lt;br /&gt;
  return html;&lt;br /&gt;
}// Strips any whitespace from the beginning and end of a string&lt;br /&gt;
&lt;br /&gt;
function stripWhitespace(html) {&lt;br /&gt;
  html = html.replace(/^\s*?(\S)/, '$1');&lt;br /&gt;
  return html.replace(/(\S)\s*?\z/, '$1');&lt;br /&gt;
}// Process code, including basic detection of language&lt;br /&gt;
&lt;br /&gt;
function processCode(data) {&lt;br /&gt;
  var lang = '',&lt;br /&gt;
  code = data[1];&lt;br /&gt;
  code = code.replace(/&amp;amp;nbsp;/g, ' ');&lt;br /&gt;
  if (code.match(/=?.*?\(?.*?\)?;/) !== null) lang = 'nasal';&lt;br /&gt;
  if (code.match(/&amp;amp;lt;.*?&amp;amp;gt;.*?&amp;amp;lt;\/.*?&amp;amp;gt;/) !== null || code.match(/&amp;amp;lt;!--.*?--&amp;amp;gt;/) !== null) lang = 'xml';&lt;br /&gt;
  code = code.replace(/&amp;lt;br\/?&amp;gt;/g, '\n');&lt;br /&gt;
  return '&amp;lt;syntaxhighlight lang=&amp;quot;' + lang + '&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;\n' + code + '\n&amp;amp;lt;/syntaxhighlight&amp;gt;';&lt;br /&gt;
}// Converts quote blocks to Cquotes&lt;br /&gt;
&lt;br /&gt;
function forum_quote2cquote(html) {&lt;br /&gt;
  html = html.replace(/&amp;lt;blockquote class=&amp;quot;uncited&amp;quot;&amp;gt;&amp;lt;div&amp;gt;(.*?)&amp;lt;\/div&amp;gt;&amp;lt;\/blockquote&amp;gt;/g, '{{cquote|$1}}');&lt;br /&gt;
  if (html.match(/&amp;lt;blockquote&amp;gt;/g) === null) return html;&lt;br /&gt;
  var numQuotes = html.match(/&amp;lt;blockquote&amp;gt;/g).length;&lt;br /&gt;
  for (var n = 0; n &amp;lt; numQuotes; n++) {&lt;br /&gt;
    html = html.replace(/&amp;lt;blockquote&amp;gt;&amp;lt;div&amp;gt;&amp;lt;cite&amp;gt;(.*?) wrote.*?:&amp;lt;\/cite&amp;gt;(.*?)&amp;lt;\/div&amp;gt;&amp;lt;\/blockquote&amp;gt;/, '{{cquote|$2|$1}}');&lt;br /&gt;
  }&lt;br /&gt;
  return html;&lt;br /&gt;
}// Converts videos to wiki style&lt;br /&gt;
&lt;br /&gt;
function vid2wiki(html) {&lt;br /&gt;
  // YouTube&lt;br /&gt;
  html = html.replace(/&amp;lt;div class=&amp;quot;video-wrapper&amp;quot;&amp;gt;\s.*?&amp;lt;div class=&amp;quot;video-container&amp;quot;&amp;gt;\s*?&amp;lt;iframe class=&amp;quot;youtube-player&amp;quot;.*?width=&amp;quot;(.*?)&amp;quot; height=&amp;quot;(.*?)&amp;quot; src=&amp;quot;http:\/\/www\.youtube\.com\/embed\/(.*?)&amp;quot;.*?&amp;gt;&amp;lt;\/iframe&amp;gt;\s*?&amp;lt;\/div&amp;gt;\s*?&amp;lt;\/div&amp;gt;/g, '{{#ev:youtube|$3|$1x$2}}');&lt;br /&gt;
  // Vimeo&lt;br /&gt;
  html = html.replace(/&amp;lt;iframe src=&amp;quot;http:\/\/player\.vimeo\.com\/video\/(.*?)\?.*?&amp;quot; width=&amp;quot;(.*?)&amp;quot; height=&amp;quot;(.*?)&amp;quot;.*?&amp;gt;.*?&amp;lt;\/iframe&amp;gt;/g, '{{#ev:vimeo|$1|$2x$3}}');&lt;br /&gt;
  return html.replace(/\[.*? Watch on Vimeo\]/g, '');&lt;br /&gt;
}// Not currently used (as of June 2015), but kept just in case&lt;br /&gt;
&lt;br /&gt;
// currently unused&lt;br /&gt;
function escapeEquals(html) {&lt;br /&gt;
  return html.replace(/=/g, '{{=}}');&lt;br /&gt;
}// &amp;lt;br&amp;gt; to newline.&lt;br /&gt;
&lt;br /&gt;
function forum_br2newline(html) {&lt;br /&gt;
  html = html.replace(/&amp;lt;br\/?&amp;gt;&amp;lt;br\/?&amp;gt;/g, '\n');&lt;br /&gt;
  return html.replace(/&amp;lt;br\/?&amp;gt;/g, '\n\n');&lt;br /&gt;
}// Forum list to wiki style&lt;br /&gt;
&lt;br /&gt;
function list2wiki(html) {&lt;br /&gt;
  var list = html.match(/&amp;lt;ul&amp;gt;(.*?)&amp;lt;\/ul&amp;gt;/g);&lt;br /&gt;
  if (list !== null) {&lt;br /&gt;
    for (var i = 0; i &amp;lt; list.length; i++) {&lt;br /&gt;
      html = html.replace(/&amp;lt;li&amp;gt;(.*?)&amp;lt;\/li&amp;gt;/g, '* $1\n');&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  list = html.match(/&amp;lt;ol.*?&amp;gt;(.*?)&amp;lt;\/ol&amp;gt;/g);&lt;br /&gt;
  if (list !== null) {&lt;br /&gt;
    for (var i = 0; i &amp;lt; list.length; i++) {&lt;br /&gt;
      html = html.replace(/&amp;lt;li&amp;gt;(.*?)&amp;lt;\/li&amp;gt;/g, '# $1\n');&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  html = html.replace(/&amp;lt;\/?[uo]l&amp;gt;/g, '');&lt;br /&gt;
  return html;&lt;br /&gt;
}&lt;br /&gt;
function nowiki(text) {&lt;br /&gt;
  return '&amp;lt;nowiki&amp;gt;' + text + '&amp;lt;/nowiki&amp;gt;';&lt;br /&gt;
}// Returns the correct ordinal adjective&lt;br /&gt;
&lt;br /&gt;
function ordAdj(date) {&lt;br /&gt;
  date = date.toString();&lt;br /&gt;
  if (date == '11' || date == '12' || date == '13') {&lt;br /&gt;
    return 'th';&lt;br /&gt;
  } else if (date.substr(1) == '1' || date == '1') {&lt;br /&gt;
    return 'st';&lt;br /&gt;
  } else if (date.substr(1) == '2' || date == '2') {&lt;br /&gt;
    return 'nd';&lt;br /&gt;
  } else if (date.substr(1) == '3' || date == '3') {&lt;br /&gt;
    return 'rd';&lt;br /&gt;
  } else {&lt;br /&gt;
    return 'th';&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Formats the date to this format: Apr 26th, 2015&lt;br /&gt;
function datef(text) {&lt;br /&gt;
  var date = new Date(text);&lt;br /&gt;
  return MONTHS[date.getMonth()] + ' ' + date.getDate() + ordAdj(date.getDate()) + ', ' + date.getFullYear();&lt;br /&gt;
}&lt;br /&gt;
function underscore2Space(str) {&lt;br /&gt;
  return str.replace(/_/g, ' ');&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// IGNORE EVERYTHING THAT FOLLOWS: &lt;br /&gt;
// This is an experiment to use GA/GP (genetic programming) to help procedurally evolve xpath and regex expressions if/when the underlying websites change&lt;br /&gt;
// so that we don't have to manually update/edit the script accordingly (this would also work for mobile themes etc)&lt;br /&gt;
// For now, this is heavily based on the genetic.js framework/examples: http://subprotocol.com/system/genetic-hello-world.html&lt;br /&gt;
// The idea is to evolve the xpath/regex expression by evaluating its return value against the expected/desired value&lt;br /&gt;
// the most important thing here is having a suitable fitness function&lt;br /&gt;
// &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function evolve_expression_test() {&lt;br /&gt;
  &lt;br /&gt;
try {  &lt;br /&gt;
var genetic = Genetic.create();&lt;br /&gt;
&lt;br /&gt;
// TODO: use minimizer: redundant_bytes + duration_msec + xpath.length&lt;br /&gt;
genetic.optimize = Genetic.Optimize.Maximize;&lt;br /&gt;
genetic.select1 = Genetic.Select1.Tournament2;&lt;br /&gt;
genetic.select2 = Genetic.Select2.Tournament2;&lt;br /&gt;
 &lt;br /&gt;
   &lt;br /&gt;
genetic.seed = function() {&lt;br /&gt;
&lt;br /&gt;
    function randomString(len) {&lt;br /&gt;
        var text = &amp;quot;&amp;quot;;&lt;br /&gt;
        var charset = &amp;quot;\\abcdefghijklmnopqrstuvwxyz0123456789[] ()&amp;lt;&amp;gt;*.,&amp;quot;;&lt;br /&gt;
        for(var i=0;i&amp;lt;len;i++)&lt;br /&gt;
            text += charset.charAt(Math.floor(Math.random() * charset.length));&lt;br /&gt;
        &lt;br /&gt;
        return text; // &amp;quot;From:&amp;amp;(.*)$&amp;lt;.*8.*&amp;gt;&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // create random strings that are equal in length to solution&lt;br /&gt;
    return randomString( this.userData[&amp;quot;solution&amp;quot;].length);&lt;br /&gt;
};&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
genetic.mutate = function(entity) {&lt;br /&gt;
    &lt;br /&gt;
    function replaceAt(str, index, character) {&lt;br /&gt;
        return str.substr(0, index) + character + str.substr(index+character.length);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // chromosomal drift&lt;br /&gt;
    var i = Math.floor(Math.random()*entity.length);&lt;br /&gt;
    return replaceAt(entity, i, String.fromCharCode(entity.charCodeAt(i) + (Math.floor(Math.random()*2) ? 1 : -1)));&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
genetic.crossover = function(mother, father) {&lt;br /&gt;
&lt;br /&gt;
    // two-point crossover&lt;br /&gt;
    var len = mother.length;&lt;br /&gt;
    var ca = Math.floor(Math.random()*len);&lt;br /&gt;
    var cb = Math.floor(Math.random()*len);     &lt;br /&gt;
    if (ca &amp;gt; cb) {&lt;br /&gt;
        var tmp = cb;&lt;br /&gt;
        cb = ca;&lt;br /&gt;
        ca = tmp;&lt;br /&gt;
    }&lt;br /&gt;
        &lt;br /&gt;
    var son = father.substr(0,ca) + mother.substr(ca, cb-ca) + father.substr(cb);&lt;br /&gt;
    var daughter = mother.substr(0,ca) + father.substr(ca, cb-ca) + mother.substr(cb);&lt;br /&gt;
    &lt;br /&gt;
    return [son, daughter];&lt;br /&gt;
};&lt;br /&gt;
    &lt;br /&gt;
genetic.determineExcessBytes = function (text, needle) {&lt;br /&gt;
    return text.length - needle.length;&lt;br /&gt;
};&lt;br /&gt;
    &lt;br /&gt;
genetic.containsText = function (text, needle) {&lt;br /&gt;
    return text.search(needle);&lt;br /&gt;
};&lt;br /&gt;
  &lt;br /&gt;
genetic.isValid = function(exp) {&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
    &lt;br /&gt;
/* myFitness:&lt;br /&gt;
 * - must be a valid xpath/regex expression (try/call)&lt;br /&gt;
 * - must containsText the needle&lt;br /&gt;
 * - low relative offset in text (begin/end)&lt;br /&gt;
 * - excessBytes&lt;br /&gt;
 * - short expression  (expression length)&lt;br /&gt;
 * - expression footprint (runtime)&lt;br /&gt;
 */ &lt;br /&gt;
&lt;br /&gt;
// TODO: the fitness function should validate each xpath/regex first&lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
genetic.fitness = function(entity) {&lt;br /&gt;
    var fitness = 0;&lt;br /&gt;
    var result;&lt;br /&gt;
    var validExp = 0.1;&lt;br /&gt;
    var hasToken = 0.1;&lt;br /&gt;
   &lt;br /&gt;
  &lt;br /&gt;
    var t = this.userData.tests[0].haystack;&lt;br /&gt;
    //var regex = new RegExp(this.userData.solution);&lt;br /&gt;
    //var output = t.match( new RegExp(&amp;quot;From: (.*) &amp;lt;.*@.*&amp;gt;&amp;quot;))[1];  &lt;br /&gt;
    // TODO: use search &amp;amp; match for improving the fitness&lt;br /&gt;
  &lt;br /&gt;
    if (0)  &lt;br /&gt;
    try {&lt;br /&gt;
    var regex = new RegExp(entity);&lt;br /&gt;
    var output = t.search( regex);&lt;br /&gt;
    validExp = 5;&lt;br /&gt;
    //if (output) validExp = 50;&lt;br /&gt;
    }&lt;br /&gt;
    catch(e) {&lt;br /&gt;
    //validExp = 2;    &lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
   &lt;br /&gt;
    &lt;br /&gt;
    var i;&lt;br /&gt;
    for (i=0;i&amp;lt;entity.length;++i) {&lt;br /&gt;
        // increase fitness for each character that matches&lt;br /&gt;
        if (entity[i] == this.userData[&amp;quot;solution&amp;quot;][i])&lt;br /&gt;
            fitness += 1;&lt;br /&gt;
        &lt;br /&gt;
        // award fractions of a point as we get warmer&lt;br /&gt;
        fitness += (127-Math.abs(entity.charCodeAt(i) - this.userData[&amp;quot;solution&amp;quot;].charCodeAt(i)))/50;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
    return fitness + (1*validExp + 1* hasToken);&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
genetic.generation = function(pop, generation, stats) {&lt;br /&gt;
    // stop running once we've reached the solution&lt;br /&gt;
    return pop[0].entity != this.userData[&amp;quot;solution&amp;quot;];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
genetic.notification = function(pop, generation, stats, isFinished) {&lt;br /&gt;
&lt;br /&gt;
    function lerp(a, b, p) {&lt;br /&gt;
        return a + (b-a)*p;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    var value = pop[0].entity;&lt;br /&gt;
    this.last = this.last||value;&lt;br /&gt;
    &lt;br /&gt;
    if (pop != 0 &amp;amp;&amp;amp; value == this.last)&lt;br /&gt;
        return;&lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
    var solution = [];&lt;br /&gt;
    var i;&lt;br /&gt;
    for (i=0;i&amp;lt;value.length;++i) {&lt;br /&gt;
        var diff = value.charCodeAt(i) - this.last.charCodeAt(i);&lt;br /&gt;
        var style = &amp;quot;background: transparent;&amp;quot;;&lt;br /&gt;
        if (diff &amp;gt; 0) {&lt;br /&gt;
            style = &amp;quot;background: rgb(0,200,50); color: #fff;&amp;quot;;&lt;br /&gt;
        } else if (diff &amp;lt; 0) {&lt;br /&gt;
            style = &amp;quot;background: rgb(0,100,50); color: #fff;&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        solution.push(&amp;quot;&amp;lt;span style=\&amp;quot;&amp;quot; + style + &amp;quot;\&amp;quot;&amp;gt;&amp;quot; + value[i] + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
    var t = this.userData.tests[0].haystack;&lt;br /&gt;
    //console.log(&amp;quot;haystack is:&amp;quot;+t);&lt;br /&gt;
    // &amp;quot;From: John Doe &amp;lt;John@do...&amp;gt; - 2020-07-02 17:36:03&amp;quot;, needle: &amp;quot;John Doe&amp;quot;}, /From: (.*) &amp;lt;.*@.*&amp;gt;/&lt;br /&gt;
    var regex = new RegExp(this.userData.solution);&lt;br /&gt;
    //var output = t.match( new RegExp(&amp;quot;From: (.*) &amp;lt;.*@.*&amp;gt;&amp;quot;))[1];  &lt;br /&gt;
    // TODO: use search &amp;amp; match for improving the fitness&lt;br /&gt;
    var output = t.search( new RegExp(value));&lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
    var buf = &amp;quot;&amp;quot;;&lt;br /&gt;
    buf += &amp;quot;&amp;lt;tr&amp;gt;&amp;quot;;&lt;br /&gt;
    buf += &amp;quot;&amp;lt;td&amp;gt;&amp;quot; + generation + &amp;quot;&amp;lt;/td&amp;gt;&amp;quot;;&lt;br /&gt;
    buf += &amp;quot;&amp;lt;td&amp;gt;&amp;quot; + pop[0].fitness.toPrecision(5) + &amp;quot;&amp;lt;/td&amp;gt;&amp;quot;;&lt;br /&gt;
    buf += &amp;quot;&amp;lt;td&amp;gt;&amp;quot; + solution.join(&amp;quot;&amp;quot;) + &amp;quot;&amp;lt;/td&amp;gt;&amp;quot;;&lt;br /&gt;
    buf += &amp;quot;&amp;lt;td&amp;gt;&amp;quot; + output + &amp;quot;&amp;lt;/td&amp;gt;&amp;quot;;&lt;br /&gt;
    buf += &amp;quot;&amp;lt;/tr&amp;gt;&amp;quot;;&lt;br /&gt;
    $(&amp;quot;#results tbody&amp;quot;).prepend(buf);&lt;br /&gt;
    &lt;br /&gt;
    this.last = value;&lt;br /&gt;
};&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  /*&lt;br /&gt;
genetic.notification2 = function(pop, generation, stats, isFinished) {&lt;br /&gt;
&lt;br /&gt;
    function lerp(a, b, p) {&lt;br /&gt;
        return a + (b-a)*p;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    var value = pop[0].entity;&lt;br /&gt;
    this.last = this.last||value;&lt;br /&gt;
    &lt;br /&gt;
    if (pop != 0 &amp;amp;&amp;amp; value == this.last)&lt;br /&gt;
        return;&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    var solution = [];&lt;br /&gt;
    var i;&lt;br /&gt;
    for (i=0;i&amp;lt;value.length;++i) {&lt;br /&gt;
    &lt;br /&gt;
    solution.push(value[i]);&lt;br /&gt;
 } &lt;br /&gt;
    console.log(&amp;quot;Generation:&amp;quot;+ generation + &amp;quot; Fitness:&amp;quot; + pop[0].fitness.toPrecision(5) + &amp;quot; Solution:&amp;quot; + solution.join(&amp;quot;&amp;quot;));&lt;br /&gt;
  &lt;br /&gt;
    this.last = value;&lt;br /&gt;
};&lt;br /&gt;
  */&lt;br /&gt;
    &lt;br /&gt;
      &lt;br /&gt;
var config = {&lt;br /&gt;
            &amp;quot;iterations&amp;quot;: 4000&lt;br /&gt;
            , &amp;quot;size&amp;quot;: 250&lt;br /&gt;
            , &amp;quot;crossover&amp;quot;: 0.3&lt;br /&gt;
            , &amp;quot;mutation&amp;quot;: 0.4&lt;br /&gt;
            , &amp;quot;skip&amp;quot;: 30 // notifications&lt;br /&gt;
            //, &amp;quot;webWorkers&amp;quot;: false&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
var profile = CONFIG['Sourceforge Mailing list'];&lt;br /&gt;
var posting = profile.tests[0];&lt;br /&gt;
var author_xpath = profile.title.xpath;&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
var regexTests = [&lt;br /&gt;
  {haystack: &amp;quot;From: John Doe &amp;lt;John@do...&amp;gt; - 2020-07-02 17:36:03&amp;quot;, needle: &amp;quot;John Doe&amp;quot;}, &lt;br /&gt;
  {haystack: &amp;quot;From: Marc Twain &amp;lt;Marc@ta...&amp;gt; - 2010-01-03 07:36:03&amp;quot;, needle: &amp;quot;Marc Twain&amp;quot;},&lt;br /&gt;
  {haystack: &amp;quot;From: George W. Bush &amp;lt;GWB@wh...&amp;gt; - 2055-11-11 17:33:13&amp;quot;, needle: &amp;quot;George W. Bush&amp;quot;}&lt;br /&gt;
];&lt;br /&gt;
  &lt;br /&gt;
// the regex we want to evolve&lt;br /&gt;
var solution = &amp;quot;From: (.*) &amp;lt;.*@.*&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// let's assume, we'd like to evolve a regex expression like this one&lt;br /&gt;
var userData = {&lt;br /&gt;
            solution: solution,&lt;br /&gt;
            tests: regexTests                         &lt;br /&gt;
};    &lt;br /&gt;
    &lt;br /&gt;
genetic.evolve(config, userData);&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
//console.log(&amp;quot;genetic.js is loaded and working, but disabled for now&amp;quot;);    &lt;br /&gt;
    &lt;br /&gt;
  &lt;br /&gt;
} // try&lt;br /&gt;
catch (e) {&lt;br /&gt;
  console.log(&amp;quot;genetic.js error:\n&amp;quot; +e.message);&lt;br /&gt;
} // catch&lt;br /&gt;
  &lt;br /&gt;
} // evolveExpression_test()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if(0) //TODO: expose via development tab&lt;br /&gt;
try {&lt;br /&gt;
  // https://github.com/cazala/synaptic&lt;br /&gt;
  var Neuron = synaptic.Neuron,&lt;br /&gt;
    Layer = synaptic.Layer,&lt;br /&gt;
    Network = synaptic.Network,&lt;br /&gt;
    Trainer = synaptic.Trainer,&lt;br /&gt;
    Architect = synaptic.Architect;&lt;br /&gt;
  &lt;br /&gt;
  function Perceptron(input, hidden, output)&lt;br /&gt;
{&lt;br /&gt;
    // create the layers&lt;br /&gt;
    var inputLayer = new Layer(input);&lt;br /&gt;
    var hiddenLayer = new Layer(hidden);&lt;br /&gt;
    var outputLayer = new Layer(output);&lt;br /&gt;
&lt;br /&gt;
    // connect the layers&lt;br /&gt;
    inputLayer.project(hiddenLayer);&lt;br /&gt;
    hiddenLayer.project(outputLayer);&lt;br /&gt;
&lt;br /&gt;
    // set the layers&lt;br /&gt;
    this.set({&lt;br /&gt;
        input: inputLayer,&lt;br /&gt;
        hidden: [hiddenLayer],&lt;br /&gt;
        output: outputLayer&lt;br /&gt;
    });&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// extend the prototype chain&lt;br /&gt;
Perceptron.prototype = new Network();&lt;br /&gt;
Perceptron.prototype.constructor = Perceptron;&lt;br /&gt;
  &lt;br /&gt;
var myPerceptron = new Perceptron(2,3,1);&lt;br /&gt;
var myTrainer = new Trainer(myPerceptron);&lt;br /&gt;
&lt;br /&gt;
myTrainer.XOR(); // { error: 0.004998819355993572, iterations: 21871, time: 356 }&lt;br /&gt;
&lt;br /&gt;
myPerceptron.activate([0,0]); // 0.0268581547421616&lt;br /&gt;
myPerceptron.activate([1,0]); // 0.9829673642853368&lt;br /&gt;
myPerceptron.activate([0,1]); // 0.9831714267395621&lt;br /&gt;
myPerceptron.activate([1,1]); // 0.02128894618097928&lt;br /&gt;
  &lt;br /&gt;
   &lt;br /&gt;
console.log(&amp;quot;Syntaptic loaded&amp;quot;);&lt;br /&gt;
} catch(e) {&lt;br /&gt;
  UI.alert(e.message);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Appendix}}&lt;/div&gt;</summary>
		<author><name>Elgaton</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=FlightGear_wiki_talk:Instant-Refs&amp;diff=98418</id>
		<title>FlightGear wiki talk:Instant-Refs</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=FlightGear_wiki_talk:Instant-Refs&amp;diff=98418"/>
		<updated>2016-05-20T06:59:44Z</updated>

		<summary type="html">&lt;p&gt;Elgaton: /* External genetic/neural network libraries */ Libraries submitted to CDN&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== more sources ==&lt;br /&gt;
&lt;br /&gt;
at some point, we may also want to add support for other sources, such as:&lt;br /&gt;
* old forum URLs, i.e. not yet using the subdomain format (should be easy, it's just a different/additional URL after all)&lt;br /&gt;
* thread.gmane.org/gmane.games.flightgear.devel/&lt;br /&gt;
* jsbsim devel list&lt;br /&gt;
* github tickets&lt;br /&gt;
* the new SF.net issue tracker &lt;br /&gt;
* SF.net commit logs http://gitorious.org/fg/&lt;br /&gt;
* http://www.mail-archive.com/flightgear-devel@flightgear.org/ (until 2005)&lt;br /&gt;
* http://www.mail-archive.com/flightgear-devel@lists.sourceforge.net/maillist.html (until 10/2013)&lt;br /&gt;
&lt;br /&gt;
that should cover all important sources. And it would allow us to also use the same script to help populate [[FlightGear Newsletter]] &amp;amp; [[Changelog 3.2|changelogs]], but also [[Release plan/Lessons learned]]. So this could be a real time-saver. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 14:40, 1 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Automatic update of script and old quotes ==&lt;br /&gt;
Thanks for the heads-up. Now, that makes me wonder if I can adapt the script to automatically parse existing wiki articles and update cquotes there automatically by re-opening the URL and re-running the extraction logic :) BTW: That reminds me: I was going to investigate adopting the '''downloadURL''' attribute[http://stackoverflow.com/questions/15095055/why-isnt-my-greasemonkey-script-updating] so that scripts can auto-update --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 22:51, 11 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
:: if we should continue to see this widely used, having a good way to re-download and re-run the script on pages with existing cquotes would be a good way to automatically update quotes. For that, we would want to encode certain meta info in each template, e.g.:&lt;br /&gt;
* script version&lt;br /&gt;
* quoting date/time&lt;br /&gt;
* quote URL&lt;br /&gt;
* selection offsets &lt;br /&gt;
* quoting settings (format)&lt;br /&gt;
&lt;br /&gt;
We can hook into form submission to update arbitrary quotes/contents using this: http://commons.oreilly.com/wiki/index.php/Greasemonkey_Hacks/Developer_Tools#Intercept_and_Modify_Form_Submissions&lt;br /&gt;
&lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 07:19, 15 November 2015 (EST)&lt;br /&gt;
&lt;br /&gt;
=== Hosting ===&lt;br /&gt;
The script seems to be about to become sufficiently complex to deserve actual hosting:&lt;br /&gt;
* http://wiki.greasespot.net/User_Script_Hosting&lt;br /&gt;
* https://openuserjs.org/&lt;br /&gt;
&lt;br /&gt;
(that would allow updating the script automatically)&lt;br /&gt;
&lt;br /&gt;
: Hi, is there any progress being made on this? I think the best way to host it would be to put in in a SourceForge repository under the FlightGear project (I don't know if it allows direct downloads, though, and we would need to relicense the script because [https://opensource.org/faq#public-domain public domain licenses are not OSI-approved]); otherwise, I can submit it to [https://greasyfork.org/ GreasyFork] (OpenUserJS is unsuitable as [https://openuserjs.org/about/Terms-of-Service public domain licenses are not allowed]). -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 03:58, 1 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:: I don't think anybody has looked into this recently - however, relicensing should be a no-brainer, given that all the code is in the public domain anyway. I am not sure if it's worth the hassle to put up under sourceforge/FlightGear; we also need to keep in mind that this is not exactly the most popular &amp;quot;tool&amp;quot; around here. So, before this becomes even better accessible, it might be a good idea to comply with some of the requests made, e.g. by adding support for a different output mode (without using the FGCquote template, just the copied text, plus the ref part), so that quote-heavy pages don't look that obnoxious.&lt;br /&gt;
:: Regarding hosting in general, I still think it may be a good idea, but we would probably need to make sure that some requirements are met, e.g. having a revision history, and to provide other contributors with access-alternatively, we should maintain a copy of the script in the wiki, and add a note saying that changes to it will be reviewed/integrated with the hosted script by one of us (if you'd volunteer to help with that, I'd suggest to just go ahead and set up a public repository).&lt;br /&gt;
:: Admittedly, this is going to remain a fairly FG specific script, it would need quite a bit of work to become useful for other purposes (even though other OSS projects may be easy to support). --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 06:33, 1 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
::: OK, I think we can leave the script here and host it on GreasyFork (it allows public domain scripts) - I'll put the page on my watchlist to make sure I update the script there every time there's a version bump. Does that look good to you and the other contributors? -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 09:26, 1 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:::: Sounds good to me, given how the script has evolved over time, we've probably hit a natural limit already, i.e. being able to use multiple files easily, and update scripts automatically sounds like a useful thing to me. I don't know if greasyfork supports &amp;quot;teams&amp;quot; of contributors for better collaboration ? It might also be a good idea to generalize the script so that it supports arbitrary phpBB installations and mailing list archives other than just sourceforge (think gmane) - and maybe output formats other than just wikimedia markup, that way, the script may become more useful over time.--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 13:46, 1 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
::::: It doesn't as it only offers a user script downloading facility (source code repositories like GitHub and SourceForge are better suited for the kind of work you mention). I'll wait a bit in case Red Leader, Philosopher or bigstones have any objections/remarks, then I'll upload the script there. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 17:14, 1 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:: do they support extensions spread across multiple files ? That is something that would help us quite a bit cleaning up the current code, which has become a bit convoluted over time. Apart from that, nothing wrong with github et al - I am just not sure if they're suitable for automatically propagating updated changes.--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 10:12, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
::: No, not that I know of (generally speaking, all user scripts are made of a single .user.js file). We could &amp;quot;hack&amp;quot; it by splitting the current script in multiple files and requiring them from a main one as libraries via the &amp;lt;tt&amp;gt;@include&amp;lt;/tt&amp;gt; directive, but that would rule out most hosting solutions (many providers only allow GreaseMonkey scripts which include additional files only from a handful of trusted domains/CDNs, for safety reasons).&lt;br /&gt;
::: As for propagating changes on GitHub and other code repository, the update URL must remain constant throughout the lifetime of the script. I'm sure this can be done on GitHub by publishing updates not as releases (where the addresses change), but on GitHub Pages (a user script I use does exactly this); on SourceForge, the usual download hosting could do the trick, but I'd need to perform a test first. (I'd prefer SF to keep the script &amp;quot;inside&amp;quot; the FG project hierarchy, if possible). -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 10:50, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
: actually, user scripts can be compromised of multiple files, e.g. via the require directive [http://stackoverflow.com/questions/8695459/is-it-possible-to-split-greasemonkey-user-scripts-into-multiple-files]. Personally, I would like to make use of that - we are already using that to include jQuery stuff, and it would help us organize the script a little better. I am not oposed to seeing the script hosted as some part of FG/SF, but I just don't think it's going to be a very popular idea - so far, everything worked out without major hinderance, so I would rather use an independent hosting solution, or continue to use the wiki to ensure that the barrier to entry/contributing isn't raised, e.g. by going through merge requests etc. Major contributions to the script like those from bigstones or Red Leader were simply &amp;quot;dropped&amp;quot; here directly, so this seems to have worked out really well.--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 11:26, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:: I've checked the [https://greasyfork.org/it/help/external-scripts GreasyFork external script policy]: as long as all the files are hosted on/uploaded to GreasyFork, it's not a problem. (Also, sorry about the typo, I wrote &amp;lt;tt&amp;gt;@include&amp;lt;/tt&amp;gt; instead of &amp;lt;tt&amp;gt;@require&amp;lt;/tt&amp;gt; by mistake). I guess I can proceed with the upload now? -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 12:22, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
: sure, why not - it's in the public domain after all - feel free to make any changes to the script to have it auto-update. We can review everything once we have gathered a little more experience with this kind of scheme. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 12:27, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:: {{done}} - I'm updating the installation instructions in the main page. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 13:52, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
::: Script at: https://greasyfork.org/en/scripts/19331-instant-cquotes &lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 14:18, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:::: Regarding updates, bumping the version number is fine - I'll take the script at the wiki revision where the version is bumped and upload it. (Note that I will not perform any prior testing, so be extra careful - maybe I should add this in the note above the script?). -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 18:08, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:: sounds good, I will be sure to stop updating the version number without prior testing, we could also add some tests to the code to spot the more obvious mistakes - in fact, there is already an OpenLink helper that could be used to download a few postings and try to extract the corresponding fields, so that we would only bump the version number if that succeeds. BTW: Thanks for handling the hosting part, much appreciated ! --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 18:25, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Issues ==&lt;br /&gt;
=== too greedy non-greedy regexes ===&lt;br /&gt;
The problem described in the previous section regarding regexes that eat up half messages seems to be related to my  [http://blog.liip.ch/archive/2009/07/24/the-greedyness-of-non-greedy-regular-expressions.html misunderstanding of the non-greediness]. So, I managed to fix it for this one case, but this means that using .*? to match everything until you meet the following character (as I currently do pretty much everywhere) is dangerous and prone to failure. Any occurrence of that should be changed as I did in [http://wiki.flightgear.org/index.php?title=FlightGear_wiki:Instant-Cquotes&amp;amp;oldid=72839 this edit] and that's clearly cumbersome, not to say that it can still be incorrect: say I have&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;a someprop=&amp;quot;href&amp;quot; href=&amp;quot;http://www.link.org&amp;quot; ... &amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
If I want to mach anything between a and href, I use &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;[^(?:href)]*&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;, but that would match only up to the text inside someprop, so I'd have to check that it's not inside doublequotes... Well, I guess this is getting too complicated for handling it [http://blog.codinghorror.com/parsing-html-the-cthulhu-way/ the Chtulu way].&lt;br /&gt;
&lt;br /&gt;
So my approach would be: fix this whenever the problem comes up, but don't overdo because we're already moving in dangerous ground. Or, rewrite it all using ''only'' xpaths *sobs*.&lt;br /&gt;
--[[User:Bigstones|Bigstones]] ([[User talk:Bigstones|talk]]) 16:49, 17 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
=== regex vectors ===&lt;br /&gt;
&lt;br /&gt;
When testing things I realized that you are right: there are some scenarios where the regex may fail depending on how &amp;quot;complete&amp;quot; the selection is, because we obviously have hard-coded assumptions here. I'll see if it's feasible to also support vectors for regexes to extract the corresponding fields and try each regex in order to get a certain field, or if that doesn't make any sense... But quoting with/without author (anonymous quote) would be a valid test case here.--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 16:46, 16 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
: Probably going to look into this sooner or later because this could be a simple solution to also support PM quoting - without having to parse the actual URL, we'd just try different regexes in order and use the one that succeeds. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 16:46, 16 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
=== Syntaxhighlighting ===&lt;br /&gt;
Need to investigate what needs to be updated to support quoting code sections, as per [http://forum.flightgear.org/viewtopic.php?f=66&amp;amp;t=21855&amp;amp;p=212585#p212581] --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 22:33, 14 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
=== Postings that break our script for some reason ===&lt;br /&gt;
* http://forum.flightgear.org/viewtopic.php?f=19&amp;amp;t=23365&lt;br /&gt;
&lt;br /&gt;
== Misc notes ==&lt;br /&gt;
&lt;br /&gt;
=== Detecting failed XPaths === &lt;br /&gt;
you've got a point, we should probably check if xpath/regexes succeed or fail, and show a warning so that we know that the scripts needs to be updated because some xpath/regex may have changed. &lt;br /&gt;
&lt;br /&gt;
=== Paragraphs / br (trailing slash) ===&lt;br /&gt;
There are some minor issues now, i.e. newline2br will no longer contain the trailing forward slash, so there's probably some JavaScript/regex oddity involved here, maybe slashes just need to be escaped. Will be testing the code with a few different forum postings and check the resulting cquote&lt;br /&gt;
: {{done}}. That's because newline2br wasn't used at all in html mode. I added addNewlines which puts newlines after br's and list related tags, if there are more newlines to be added that should be the place.&lt;br /&gt;
: --[[User:Bigstones|Bigstones]] ([[User talk:Bigstones|talk]]) 14:03, 17 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
=== support/ignore highlighted keywords/smilies ===&lt;br /&gt;
see [[Understanding Forward Compatibility]] for examples&lt;br /&gt;
: {{done}} --[[User:Bigstones|Bigstones]] ([[User talk:Bigstones|talk]]) 15:13, 17 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Beyond just cquotes (newsletter/changelog) ==&lt;br /&gt;
&lt;br /&gt;
Gijs has recently revamped the newsletter template rather significantly, see: [[FlightGear_Newsletter_June_2014]], and [[User_talk:Gijs#06.2F2014_newsletter:_too_much_of_a_]] - basically, we could extend the script to support another output FORMAT to directly create markup for the newsletter/changelog. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 20:40, 30 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
== more styles/output formats ==&lt;br /&gt;
&lt;br /&gt;
looking at some of the cleanup done by Red Leader recently, we could also directly support other styles/output formats to directly provide a format that looks well enough without requiring tons of manual editing. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 11:11, 13 February 2015 (EST)&lt;br /&gt;
&lt;br /&gt;
== token matching for keywords/variables ==&lt;br /&gt;
&lt;br /&gt;
seems like it might make sense to match common keywords/acronyms and variables, such as e.g.:&lt;br /&gt;
* FG_ROOT =&amp;gt; [[$FG_ROOT]]&lt;br /&gt;
* FG_HOME =&amp;gt;  [[$FG_HOME]]&lt;br /&gt;
* FG_SRC =&amp;gt; [[$FG_SRC]]&lt;br /&gt;
&lt;br /&gt;
file names with a known prefix like $FG_ROOT could even be pattern-matched using git link: $FG_ROOT/Nasal/canvas/MapStructure.nas would become [[$FG_ROOT]]{{Git link|gitorious|fg/fgdata|master|Nasal/canvas/MapStructure.nass|text=/Nasal/canvas/MapStructure.nas}}&lt;br /&gt;
&lt;br /&gt;
Equally, we could match common property paths to use code tags, e.g.: /sim/rendering would become &amp;lt;code&amp;gt;/sim/rendering&amp;lt;/code&amp;gt;&lt;br /&gt;
Ultimately, it might be a good idea to get in touch with Johan_G, Gijs and Red Leader to see what kind of format they'd prefer, especially because this could then be directly used for creating newsletter contents. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 11:19, 13 February 2015 (EST)&lt;br /&gt;
&lt;br /&gt;
== matching repository references using git link template ==&lt;br /&gt;
&lt;br /&gt;
Most of us commonly refer to repository files using either the $FG_* references, or relative paths in the form of &amp;lt;code&amp;gt;src/Main/fg_init.cxx:line number&amp;lt;/code&amp;gt;, we could automatically convert such references using the git/repo link template, e.g.: &lt;br /&gt;
&lt;br /&gt;
{{FGCquote&lt;br /&gt;
  |Further investigation found that the launcher *is* trying to add this directory to fg-aircraft (src/GUI/QtLauncher.cxx:772), but that this doesn't work because this option is processed before the launcher is run (intentionally, to allow the launcher to find aircraft in fg-aircraft: '''src/Main/main.cxx:448''').&lt;br /&gt;
  |{{cite web |url=http://sourceforge.net/p/flightgear/mailman/message/33686356/&lt;br /&gt;
     |title=&amp;lt;nowiki&amp;gt;Re: [Flightgear-devel] Launcher issues on Linux&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
     |author=&amp;lt;nowiki&amp;gt;Rebecca N. Palmer&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
     |date=&amp;lt;nowiki&amp;gt;2015-04-01&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
   }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 12:48, 1 April 2015 (EDT)&lt;br /&gt;
&lt;br /&gt;
== chrome specific port ==&lt;br /&gt;
&lt;br /&gt;
Hi Red Leader, when/if you do come up with a chrome specific version of the script, I would suggest to refactor existing APIs accordingly, so that we can come up with a common library of general purpose/utility helpers, so that both scripts can co-exist and use a common/shared file (think all the extraction/transformation logic), by referencing an external .js/JavaScript file that will be maintained/updated and hosted separately. I think this could be accomplished easily using jsfiddle. So basically, I am suggesting to come up with a shared back-end for both versions of the script. Given the complexity we're reaching meanwhile, as well as the number of edits and contributors, it may also make sense to consider using github for this at some point. One of the main advantages being that we could easily distribute updates automatically to all people who've installed the script, without them having to do anything manually.--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 08:38, 23 June 2015 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Development resources ==&lt;br /&gt;
&lt;br /&gt;
* https://www.youtube.com/watch?v=xpXNDT0SxM0&lt;br /&gt;
* http://wiki.greasespot.net/GM_getResourceText&lt;br /&gt;
* http://stackoverflow.com/questions/14594346/create-a-config-or-options-page-for-a-greasemonkey-script&lt;br /&gt;
&lt;br /&gt;
== Future focus/development and priorities (De-quoting) ==&lt;br /&gt;
&lt;br /&gt;
Given that most people involved in maintaining the wiki don't seem to particularly appreciate the nature of articles consisting mainly of quotes, and that we don't seem to have any other good way to populate new articles quickly, I was thinking of changing the focus of the script to dynamically create articles using quotes (with proper refs), that would be merely copy-edited, i.e. using the process we are currently using to &amp;quot;de-quote&amp;quot; such articles by 1) categorizing related quotes, 2) coming up with headers/sub-headers, 3) re-writing/merging certain quotes, 4) attributing them - linking back to the quotes archives.&lt;br /&gt;
Should we decide to pursue this, the script would be turned into a &amp;quot;wizard&amp;quot; where we can topics and sub-topics (wiki headings) and then add arbitrary text using the existing approach, but without using cquotes - i.e. the focus would be on extracting relevant contents, distilling them down and adding plenty of refs, including a references section at the bottom. Some tokens/words could be changed dynamically, but some kind of proof-reading/copy-editing would still need to be done afterwards, because people tend to use first person speech in their announcements/postings, which we would need to convert to 3rd person semi-automagically. Thoughts/ideas ?--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 07:11, 15 November 2015 (EST)&lt;br /&gt;
&lt;br /&gt;
== changing and automating regex/xpath handling ==&lt;br /&gt;
{{See also|#Genetic_Expression_solver}}&lt;br /&gt;
&lt;br /&gt;
We have currently hard-coded handling of different websites, regexes and xpath expressions so that things are a  bit fragile at the moment, and once a website changes its style/template, our script would break immediately. However, we could change the way the script works by using a very simple NN (neural network) to come up with matching regex/xpath expressions automatically. The way this could work would be &amp;quot;supervised&amp;quot; training, where we would replace/adapt our existing CONFIG hash with a vector of URLs and contents to be extracted (date, time, title, posting). This kind of data would suffice entirely for a neural network to self-train itself and &amp;quot;learn&amp;quot; how to come up with regex/xpath expressions to extract the relevant contents, including not only hard-coded websites like sourceforge, but even completely different websites (think gmane) - because the &amp;quot;learning&amp;quot; routine would self-adapt by looking at how to get its contents, and never contain any hard-coded regex/xpath expressions anymore. The CONFIG hash would end up being a vector with &amp;quot;training data&amp;quot; for different websites to be supported. And whenever an expression fails, it could re-train itself accordingly.--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 13:33, 15 November 2015 (EST)&lt;br /&gt;
&lt;br /&gt;
== nested quotes and AJAX for thread titles ==&lt;br /&gt;
&lt;br /&gt;
{{FGCquote&lt;br /&gt;
|1= http://sourceforge.net/p/flightgear/mailman/message/33451055/&lt;br /&gt;
{{cquote|As we move forward with FlightGear development and future versions, we will be expanding the &amp;quot;in app&amp;quot; aircraft center. This dialog inside flightgear lets you select, download, and switch to any of the aircraft in the library.|Curt}}&lt;br /&gt;
|2= {{cite web&lt;br /&gt;
  | url    = http://forum.flightgear.org/viewtopic.php?p=259879#p259879&lt;br /&gt;
  | title  = &amp;lt;nowiki&amp;gt;Re: New Canvas GUI&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  | author = &amp;lt;nowiki&amp;gt;Hooray&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  | date   = Oct 7th, 2015&lt;br /&gt;
  }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== AJAX mode/testing ==&lt;br /&gt;
&lt;br /&gt;
We should probably add a dialog to store credentials that we can use for accessing the wiki, which would need to be shown after installing the script, i.e. first-time use&lt;br /&gt;
&lt;br /&gt;
* http://stackoverflow.com/questions/14594346/create-a-config-or-options-page-for-a-greasemonkey-script&lt;br /&gt;
* http://commons.oreilly.com/wiki/index.php/Greasemonkey_Hacks/Getting_Started#During_Installation&lt;br /&gt;
* https://www.safaribooksonline.com/library/view/greasemonkey-hacks/0596101651/ch01s06.html&lt;br /&gt;
&lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 12:59, 20 November 2015 (EST)&lt;br /&gt;
&lt;br /&gt;
== libraries ==&lt;br /&gt;
&lt;br /&gt;
Referring to the [[#Hosting]] section, and my comment on wanting to use additional libs (like jQuery), I am primarily thinking about using a wizard-framework (e.g. jQuery steps) and a framework for creating wikimedia editor plugins (actions):&lt;br /&gt;
&lt;br /&gt;
* http://mstratman.github.io/jQuery-Smart-Wizard/&lt;br /&gt;
* http://www.jquery-steps.com/&lt;br /&gt;
* http://www.jqueryrain.com/demo/jquery-step-form-wizard/&lt;br /&gt;
* https://www.mediawiki.org/wiki/Extension:WikiEditor&lt;br /&gt;
&lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 12:07, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== About dequoting the script's article ==&lt;br /&gt;
&lt;br /&gt;
Thanks for doing this, but I am frankly not sure if it's worth the effort - there are much more popular/important articles using tons of quotes than this one, and given the reputation of the script, having quotes in this article may actually be a useful thing to make the case for having quotes in the first place - thus, I would frankly not spend much time going through this particular article - in fact, I'd be very surprised if the greasyfork download stats showed more than 3-5 people actually downloading, and using, the script - so this is really just a niche tool, and we probably better spend our time doing other things, and reviewing other wiki articles, than the script's article - at the very least, I would suggest to retain the references to the original discussions revolving these quotes (just my 2c). --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 19:00, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
: {{done}} I've added back the quotes as references. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 02:53, 3 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Script configuration (persistence) ==&lt;br /&gt;
&lt;br /&gt;
* https://wiki.greasespot.net/GM_config&lt;br /&gt;
* https://github.com/sizzlemctwizzle/GM_config/wiki&lt;br /&gt;
* https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API&lt;br /&gt;
&lt;br /&gt;
== Work in progress ==&lt;br /&gt;
&lt;br /&gt;
We have now several more or less related development efforts going on, and the code is also growing because of that - so it seems to make sense to summarize what's been going on recently. In general, all changes were made in response to the collection of feature requests and ideas we have accumulated over time  - specifically, that means that the following roadmap is in the process of being implemented:&lt;br /&gt;
&lt;br /&gt;
* establish unit testing, and add a few self-tests, so that the script can be more easily tested, updated/reviewed in the future&lt;br /&gt;
* rework the script to more easily support other sources (think gmane)&lt;br /&gt;
* make it much easier to update modified xpath/regex expressions (i.e. provide a UI for that)&lt;br /&gt;
* support persistence for script-specific settings&lt;br /&gt;
* make it easier for people to port/maintain the script by encapsulating platform specifics&lt;br /&gt;
* support asynchronous fetching of postings (AJAX), e.g. to fetch posting titles, attachments etc&lt;br /&gt;
* prepare the groundwork for supporting template-based output formats (think newsletter, changelog, articles)&lt;br /&gt;
* review what's necessary to allow the script to update fgcquote-based quotes automagically&lt;br /&gt;
&lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 16:47, 4 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== External genetic/neural network libraries ==&lt;br /&gt;
While uploading the latest version of the script, I noticed that the Genetic and Synaptic libraries are hosted on sites not on [https://greasyfork.org/en/help/external-scripts the approved GreasyFork list]. Shall I ask them to host them? -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 13:28, 11 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
: Thanks for pointing that out, I missed that completely, because everything is working correctly here - but obviously, I rarely get to actually download/install the latest version via greasyfork. Those libs should be safe to be added to the list, i.e. they're fairly established/popular, lest I'd not be using them. For now, this is just an experiment anyway. The idea is to update the xpath/regex code to evolve if/when the underlying website (theme) changes. But if there is a problem, we could use other libs - the code is just used for testing ATM. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 13:41, 11 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
* https://github.com/subprotocol/genetic-js&lt;br /&gt;
* https://github.com/cazala/synaptic&lt;br /&gt;
&lt;br /&gt;
:: {{ongoing}} I have submitted the libraries to the JSDelivr CDN; once they are up, I'll change the source URLs in the script and update it on GreasyFork as well. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 18:32, 17 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
::: Hi Elgaton, thank you for taking care of this, it's very much appreciated ! --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 18:55, 17 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:::: You're welcome! My merge requests for the CDN were approved (this took a bit longer than expected because I had made a small mistake - I forgot to include a file required by the Genetic.js library). The libraries should be up in a day or two, at which point I'll update the URLs in the script and submit the new version to GreasyFork. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 02:59, 20 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Genetic Expression solver ==&lt;br /&gt;
[[File:Instant-cquotes-genetic-regex-solving.png|thumb|Screenshot showing the instant cquotes script with integrated regex solving support using genetic algorithms.]]&lt;br /&gt;
&lt;br /&gt;
The genetic-js framework has been integrated, it is intended to help solve xpath/regex expressions procedurally using genetic algorithms/programming. &lt;br /&gt;
&lt;br /&gt;
The idea is to provide a set of desired outputs (needles), available input data (haystack), and use existing (possibly outdated) regex/xpath expressions to seed a pool with potential solutions for retrieving the desired output. For now, this is just proof-of-concept, i.e. just an experiment.&lt;br /&gt;
&lt;br /&gt;
For example, let's consider the typical format of a from header for any sourceforge posting:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var regexTests = [&lt;br /&gt;
  {haystack: &amp;quot;From: John Doe &amp;lt;John@do...&amp;gt; - 2020-07-02 17:36:03&amp;quot;, needle: &amp;quot;John Doe&amp;quot;}, &lt;br /&gt;
  {haystack: &amp;quot;From: Marc Twain &amp;lt;Marc@ta...&amp;gt; - 2010-01-03 07:36:03&amp;quot;, needle: &amp;quot;Marc Twain&amp;quot;},&lt;br /&gt;
  {haystack: &amp;quot;From: George W. Bush &amp;lt;GWB@wh...&amp;gt; - 2055-11-11 17:33:13&amp;quot;, needle: &amp;quot;George W. Bush&amp;quot;}&lt;br /&gt;
];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The basic idea is to run a fitness function and score regex expressions based on not throwing an exception (which makes them valid), and by checking if the desired tokens are part of the output string, and evolve (mutate/cross-over) the &amp;quot;fittest&amp;quot; expressions - i.e. those that satisfy at least /some/ of the heuristics.&lt;br /&gt;
&lt;br /&gt;
Some of the metrics that can be used by the fitness function to determine if an expression is &amp;quot;fit&amp;quot;, are:&lt;br /&gt;
* valid expression&lt;br /&gt;
* relative offset/excess bytes in matches string&lt;br /&gt;
* number of examples it can successfully extract&lt;br /&gt;
* length of the expression&lt;br /&gt;
* runtime of the expression&lt;br /&gt;
&lt;br /&gt;
The search space, and runtime, can be significantly reduced by looking at similarities between all examples and coming up with a subset string that contains all identical components (e.g. the &amp;lt;code&amp;gt;From:&amp;lt;/code&amp;gt; part in the author regex) and use that for seeding the initial generations.&lt;br /&gt;
&lt;br /&gt;
Ultimately, this would allow the script to self-update its regex/xpath expressions if/when the underlying website (themes) change, but it would also allow to add support for new websites, without ever manually adding the required xpath/regex expressions, i.e. all that is needed is a sufficiently large number of example datasets to obtain the author, date and title information, and a URL for the script to download the HTML markup of the posting in question:&lt;br /&gt;
&lt;br /&gt;
{{Note|The date field won't work as is, because it's actually post-processed using a transformation function, so we'd need to undo the transformation or use the actual date string instead}}&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt; // vector with tests to be executed for sanity checks (unit testing)&lt;br /&gt;
    tests: [&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://sourceforge.net/p/flightgear/mailman/message/35059454/',&lt;br /&gt;
        author: 'Erik Hofman',&lt;br /&gt;
        date: 'May 3rd, 2016', // NOTE: using the transformed date here &lt;br /&gt;
        title: 'Re: [Flightgear-devel] Auto altimeter setting at startup (?)'&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://sourceforge.net/p/flightgear/mailman/message/35059961/',&lt;br /&gt;
        author: 'Ludovic Brenta',&lt;br /&gt;
        date: 'May 3rd, 2016',&lt;br /&gt;
        title: 'Re: [Flightgear-devel] dual-control-tools and the limit on packet size'&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://sourceforge.net/p/flightgear/mailman/message/20014126/',&lt;br /&gt;
        author: 'Tim Moore',&lt;br /&gt;
        date: 'Aug 4th, 2008',&lt;br /&gt;
        title: 'Re: [Flightgear-devel] Cockpit displays (rendering, modelling)'&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://sourceforge.net/p/flightgear/mailman/message/23518343/',&lt;br /&gt;
        author: 'Tim Moore',&lt;br /&gt;
        date: 'Sep 10th, 2009',&lt;br /&gt;
        title: '[Flightgear-devel] Atmosphere patch from John Denker'&lt;br /&gt;
      } // add other tests below&lt;br /&gt;
&lt;br /&gt;
    ], // end of vector with self-tests&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note how this no longer contains any hard-coded xpath/regex expressions - instead, the script can refer to the website specific defaults, and try those first, and if they fail, use those to seed new generations and evolve them procedurally until all tests succeed.&lt;br /&gt;
&lt;br /&gt;
For a regex to be valid, it must work for all tests/examples.&lt;br /&gt;
&lt;br /&gt;
Once the regex solver is working correctly, the code can be further generalized to also evolve xpath expressions (NOTE: the DOMParser API is /not/ available to webworkers ...) and chain those two components together.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* http://regex.inginf.units.it/how.html&lt;br /&gt;
* http://www.i-programmer.info/programming/perl/9503-automatically-generating-regular-expressions-with-genetic-programming.html&lt;br /&gt;
* http://jkff.info/articles/ire/&lt;br /&gt;
* http://www.networkworld.com/article/2955126/software/genetic-programming-meets-regular-expressions.html&lt;br /&gt;
* https://handcraftsman.wordpress.com/2012/04/11/evolving-a-regular-expression-with-go/&lt;br /&gt;
* http://stackoverflow.com/questions/4880402/how-to-auto-generate-regex-from-given-list-of-strings&lt;br /&gt;
* http://regex.inginf.units.it/&lt;br /&gt;
* http://www.genetic-programming.org/hc2014/Bartoli-Paper.pdf&lt;br /&gt;
&lt;br /&gt;
== Hierarchical Clustering  ==&lt;br /&gt;
&lt;br /&gt;
Been tinkering with a JavaScript module to automatically cluster postings based on certain keywords in the topic/title or posting (e.g. Nasal, Canvas, 2D API, rendering): https://harthur.github.io/clusterfck/&lt;br /&gt;
&lt;br /&gt;
Note that in conjunction with processing article sections and/or whole articles, this could help automatically come up with matching postings for articles and vice versa.&lt;br /&gt;
&lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 18:11, 19 May 2016 (EDT)&lt;/div&gt;</summary>
		<author><name>Elgaton</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=FlightGear_wiki_talk:Instant-Refs&amp;diff=98349</id>
		<title>FlightGear wiki talk:Instant-Refs</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=FlightGear_wiki_talk:Instant-Refs&amp;diff=98349"/>
		<updated>2016-05-17T22:32:42Z</updated>

		<summary type="html">&lt;p&gt;Elgaton: /* External genetic/neural network libraries */ Uploaded libraries to JSDelivr&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== more sources ==&lt;br /&gt;
&lt;br /&gt;
at some point, we may also want to add support for other sources, such as:&lt;br /&gt;
* old forum URLs, i.e. not yet using the subdomain format (should be easy, it's just a different/additional URL after all)&lt;br /&gt;
* thread.gmane.org/gmane.games.flightgear.devel/&lt;br /&gt;
* jsbsim devel list&lt;br /&gt;
* github tickets&lt;br /&gt;
* the new SF.net issue tracker &lt;br /&gt;
* SF.net commit logs http://gitorious.org/fg/&lt;br /&gt;
* http://www.mail-archive.com/flightgear-devel@flightgear.org/ (until 2005)&lt;br /&gt;
* http://www.mail-archive.com/flightgear-devel@lists.sourceforge.net/maillist.html (until 10/2013)&lt;br /&gt;
&lt;br /&gt;
that should cover all important sources. And it would allow us to also use the same script to help populate [[FlightGear Newsletter]] &amp;amp; [[Changelog 3.2|changelogs]], but also [[Release plan/Lessons learned]]. So this could be a real time-saver. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 14:40, 1 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Automatic update of script and old quotes ==&lt;br /&gt;
Thanks for the heads-up. Now, that makes me wonder if I can adapt the script to automatically parse existing wiki articles and update cquotes there automatically by re-opening the URL and re-running the extraction logic :) BTW: That reminds me: I was going to investigate adopting the '''downloadURL''' attribute[http://stackoverflow.com/questions/15095055/why-isnt-my-greasemonkey-script-updating] so that scripts can auto-update --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 22:51, 11 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
:: if we should continue to see this widely used, having a good way to re-download and re-run the script on pages with existing cquotes would be a good way to automatically update quotes. For that, we would want to encode certain meta info in each template, e.g.:&lt;br /&gt;
* script version&lt;br /&gt;
* quoting date/time&lt;br /&gt;
* quote URL&lt;br /&gt;
* selection offsets &lt;br /&gt;
* quoting settings (format)&lt;br /&gt;
&lt;br /&gt;
We can hook into form submission to update arbitrary quotes/contents using this: http://commons.oreilly.com/wiki/index.php/Greasemonkey_Hacks/Developer_Tools#Intercept_and_Modify_Form_Submissions&lt;br /&gt;
&lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 07:19, 15 November 2015 (EST)&lt;br /&gt;
&lt;br /&gt;
=== Hosting ===&lt;br /&gt;
The script seems to be about to become sufficiently complex to deserve actual hosting:&lt;br /&gt;
* http://wiki.greasespot.net/User_Script_Hosting&lt;br /&gt;
* https://openuserjs.org/&lt;br /&gt;
&lt;br /&gt;
(that would allow updating the script automatically)&lt;br /&gt;
&lt;br /&gt;
: Hi, is there any progress being made on this? I think the best way to host it would be to put in in a SourceForge repository under the FlightGear project (I don't know if it allows direct downloads, though, and we would need to relicense the script because [https://opensource.org/faq#public-domain public domain licenses are not OSI-approved]); otherwise, I can submit it to [https://greasyfork.org/ GreasyFork] (OpenUserJS is unsuitable as [https://openuserjs.org/about/Terms-of-Service public domain licenses are not allowed]). -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 03:58, 1 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:: I don't think anybody has looked into this recently - however, relicensing should be a no-brainer, given that all the code is in the public domain anyway. I am not sure if it's worth the hassle to put up under sourceforge/FlightGear; we also need to keep in mind that this is not exactly the most popular &amp;quot;tool&amp;quot; around here. So, before this becomes even better accessible, it might be a good idea to comply with some of the requests made, e.g. by adding support for a different output mode (without using the FGCquote template, just the copied text, plus the ref part), so that quote-heavy pages don't look that obnoxious.&lt;br /&gt;
:: Regarding hosting in general, I still think it may be a good idea, but we would probably need to make sure that some requirements are met, e.g. having a revision history, and to provide other contributors with access-alternatively, we should maintain a copy of the script in the wiki, and add a note saying that changes to it will be reviewed/integrated with the hosted script by one of us (if you'd volunteer to help with that, I'd suggest to just go ahead and set up a public repository).&lt;br /&gt;
:: Admittedly, this is going to remain a fairly FG specific script, it would need quite a bit of work to become useful for other purposes (even though other OSS projects may be easy to support). --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 06:33, 1 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
::: OK, I think we can leave the script here and host it on GreasyFork (it allows public domain scripts) - I'll put the page on my watchlist to make sure I update the script there every time there's a version bump. Does that look good to you and the other contributors? -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 09:26, 1 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:::: Sounds good to me, given how the script has evolved over time, we've probably hit a natural limit already, i.e. being able to use multiple files easily, and update scripts automatically sounds like a useful thing to me. I don't know if greasyfork supports &amp;quot;teams&amp;quot; of contributors for better collaboration ? It might also be a good idea to generalize the script so that it supports arbitrary phpBB installations and mailing list archives other than just sourceforge (think gmane) - and maybe output formats other than just wikimedia markup, that way, the script may become more useful over time.--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 13:46, 1 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
::::: It doesn't as it only offers a user script downloading facility (source code repositories like GitHub and SourceForge are better suited for the kind of work you mention). I'll wait a bit in case Red Leader, Philosopher or bigstones have any objections/remarks, then I'll upload the script there. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 17:14, 1 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:: do they support extensions spread across multiple files ? That is something that would help us quite a bit cleaning up the current code, which has become a bit convoluted over time. Apart from that, nothing wrong with github et al - I am just not sure if they're suitable for automatically propagating updated changes.--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 10:12, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
::: No, not that I know of (generally speaking, all user scripts are made of a single .user.js file). We could &amp;quot;hack&amp;quot; it by splitting the current script in multiple files and requiring them from a main one as libraries via the &amp;lt;tt&amp;gt;@include&amp;lt;/tt&amp;gt; directive, but that would rule out most hosting solutions (many providers only allow GreaseMonkey scripts which include additional files only from a handful of trusted domains/CDNs, for safety reasons).&lt;br /&gt;
::: As for propagating changes on GitHub and other code repository, the update URL must remain constant throughout the lifetime of the script. I'm sure this can be done on GitHub by publishing updates not as releases (where the addresses change), but on GitHub Pages (a user script I use does exactly this); on SourceForge, the usual download hosting could do the trick, but I'd need to perform a test first. (I'd prefer SF to keep the script &amp;quot;inside&amp;quot; the FG project hierarchy, if possible). -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 10:50, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
: actually, user scripts can be compromised of multiple files, e.g. via the require directive [http://stackoverflow.com/questions/8695459/is-it-possible-to-split-greasemonkey-user-scripts-into-multiple-files]. Personally, I would like to make use of that - we are already using that to include jQuery stuff, and it would help us organize the script a little better. I am not oposed to seeing the script hosted as some part of FG/SF, but I just don't think it's going to be a very popular idea - so far, everything worked out without major hinderance, so I would rather use an independent hosting solution, or continue to use the wiki to ensure that the barrier to entry/contributing isn't raised, e.g. by going through merge requests etc. Major contributions to the script like those from bigstones or Red Leader were simply &amp;quot;dropped&amp;quot; here directly, so this seems to have worked out really well.--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 11:26, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:: I've checked the [https://greasyfork.org/it/help/external-scripts GreasyFork external script policy]: as long as all the files are hosted on/uploaded to GreasyFork, it's not a problem. (Also, sorry about the typo, I wrote &amp;lt;tt&amp;gt;@include&amp;lt;/tt&amp;gt; instead of &amp;lt;tt&amp;gt;@require&amp;lt;/tt&amp;gt; by mistake). I guess I can proceed with the upload now? -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 12:22, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
: sure, why not - it's in the public domain after all - feel free to make any changes to the script to have it auto-update. We can review everything once we have gathered a little more experience with this kind of scheme. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 12:27, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:: {{done}} - I'm updating the installation instructions in the main page. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 13:52, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
::: Script at: https://greasyfork.org/en/scripts/19331-instant-cquotes &lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 14:18, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:::: Regarding updates, bumping the version number is fine - I'll take the script at the wiki revision where the version is bumped and upload it. (Note that I will not perform any prior testing, so be extra careful - maybe I should add this in the note above the script?). -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 18:08, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:: sounds good, I will be sure to stop updating the version number without prior testing, we could also add some tests to the code to spot the more obvious mistakes - in fact, there is already an OpenLink helper that could be used to download a few postings and try to extract the corresponding fields, so that we would only bump the version number if that succeeds. BTW: Thanks for handling the hosting part, much appreciated ! --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 18:25, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Issues ==&lt;br /&gt;
=== too greedy non-greedy regexes ===&lt;br /&gt;
The problem described in the previous section regarding regexes that eat up half messages seems to be related to my  [http://blog.liip.ch/archive/2009/07/24/the-greedyness-of-non-greedy-regular-expressions.html misunderstanding of the non-greediness]. So, I managed to fix it for this one case, but this means that using .*? to match everything until you meet the following character (as I currently do pretty much everywhere) is dangerous and prone to failure. Any occurrence of that should be changed as I did in [http://wiki.flightgear.org/index.php?title=FlightGear_wiki:Instant-Cquotes&amp;amp;oldid=72839 this edit] and that's clearly cumbersome, not to say that it can still be incorrect: say I have&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;a someprop=&amp;quot;href&amp;quot; href=&amp;quot;http://www.link.org&amp;quot; ... &amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
If I want to mach anything between a and href, I use &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;[^(?:href)]*&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;, but that would match only up to the text inside someprop, so I'd have to check that it's not inside doublequotes... Well, I guess this is getting too complicated for handling it [http://blog.codinghorror.com/parsing-html-the-cthulhu-way/ the Chtulu way].&lt;br /&gt;
&lt;br /&gt;
So my approach would be: fix this whenever the problem comes up, but don't overdo because we're already moving in dangerous ground. Or, rewrite it all using ''only'' xpaths *sobs*.&lt;br /&gt;
--[[User:Bigstones|Bigstones]] ([[User talk:Bigstones|talk]]) 16:49, 17 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
=== regex vectors ===&lt;br /&gt;
&lt;br /&gt;
When testing things I realized that you are right: there are some scenarios where the regex may fail depending on how &amp;quot;complete&amp;quot; the selection is, because we obviously have hard-coded assumptions here. I'll see if it's feasible to also support vectors for regexes to extract the corresponding fields and try each regex in order to get a certain field, or if that doesn't make any sense... But quoting with/without author (anonymous quote) would be a valid test case here.--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 16:46, 16 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
: Probably going to look into this sooner or later because this could be a simple solution to also support PM quoting - without having to parse the actual URL, we'd just try different regexes in order and use the one that succeeds. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 16:46, 16 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
=== Syntaxhighlighting ===&lt;br /&gt;
Need to investigate what needs to be updated to support quoting code sections, as per [http://forum.flightgear.org/viewtopic.php?f=66&amp;amp;t=21855&amp;amp;p=212585#p212581] --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 22:33, 14 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
=== Postings that break our script for some reason ===&lt;br /&gt;
* http://forum.flightgear.org/viewtopic.php?f=19&amp;amp;t=23365&lt;br /&gt;
&lt;br /&gt;
== Misc notes ==&lt;br /&gt;
&lt;br /&gt;
=== Detecting failed XPaths === &lt;br /&gt;
you've got a point, we should probably check if xpath/regexes succeed or fail, and show a warning so that we know that the scripts needs to be updated because some xpath/regex may have changed. &lt;br /&gt;
&lt;br /&gt;
=== Paragraphs / br (trailing slash) ===&lt;br /&gt;
There are some minor issues now, i.e. newline2br will no longer contain the trailing forward slash, so there's probably some JavaScript/regex oddity involved here, maybe slashes just need to be escaped. Will be testing the code with a few different forum postings and check the resulting cquote&lt;br /&gt;
: {{done}}. That's because newline2br wasn't used at all in html mode. I added addNewlines which puts newlines after br's and list related tags, if there are more newlines to be added that should be the place.&lt;br /&gt;
: --[[User:Bigstones|Bigstones]] ([[User talk:Bigstones|talk]]) 14:03, 17 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
=== support/ignore highlighted keywords/smilies ===&lt;br /&gt;
see [[Understanding Forward Compatibility]] for examples&lt;br /&gt;
: {{done}} --[[User:Bigstones|Bigstones]] ([[User talk:Bigstones|talk]]) 15:13, 17 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Beyond just cquotes (newsletter/changelog) ==&lt;br /&gt;
&lt;br /&gt;
Gijs has recently revamped the newsletter template rather significantly, see: [[FlightGear_Newsletter_June_2014]], and [[User_talk:Gijs#06.2F2014_newsletter:_too_much_of_a_]] - basically, we could extend the script to support another output FORMAT to directly create markup for the newsletter/changelog. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 20:40, 30 June 2014 (UTC)&lt;br /&gt;
&lt;br /&gt;
== more styles/output formats ==&lt;br /&gt;
&lt;br /&gt;
looking at some of the cleanup done by Red Leader recently, we could also directly support other styles/output formats to directly provide a format that looks well enough without requiring tons of manual editing. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 11:11, 13 February 2015 (EST)&lt;br /&gt;
&lt;br /&gt;
== token matching for keywords/variables ==&lt;br /&gt;
&lt;br /&gt;
seems like it might make sense to match common keywords/acronyms and variables, such as e.g.:&lt;br /&gt;
* FG_ROOT =&amp;gt; [[$FG_ROOT]]&lt;br /&gt;
* FG_HOME =&amp;gt;  [[$FG_HOME]]&lt;br /&gt;
* FG_SRC =&amp;gt; [[$FG_SRC]]&lt;br /&gt;
&lt;br /&gt;
file names with a known prefix like $FG_ROOT could even be pattern-matched using git link: $FG_ROOT/Nasal/canvas/MapStructure.nas would become [[$FG_ROOT]]{{Git link|gitorious|fg/fgdata|master|Nasal/canvas/MapStructure.nass|text=/Nasal/canvas/MapStructure.nas}}&lt;br /&gt;
&lt;br /&gt;
Equally, we could match common property paths to use code tags, e.g.: /sim/rendering would become &amp;lt;code&amp;gt;/sim/rendering&amp;lt;/code&amp;gt;&lt;br /&gt;
Ultimately, it might be a good idea to get in touch with Johan_G, Gijs and Red Leader to see what kind of format they'd prefer, especially because this could then be directly used for creating newsletter contents. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 11:19, 13 February 2015 (EST)&lt;br /&gt;
&lt;br /&gt;
== matching repository references using git link template ==&lt;br /&gt;
&lt;br /&gt;
Most of us commonly refer to repository files using either the $FG_* references, or relative paths in the form of &amp;lt;code&amp;gt;src/Main/fg_init.cxx:line number&amp;lt;/code&amp;gt;, we could automatically convert such references using the git/repo link template, e.g.: &lt;br /&gt;
&lt;br /&gt;
{{FGCquote&lt;br /&gt;
  |Further investigation found that the launcher *is* trying to add this directory to fg-aircraft (src/GUI/QtLauncher.cxx:772), but that this doesn't work because this option is processed before the launcher is run (intentionally, to allow the launcher to find aircraft in fg-aircraft: '''src/Main/main.cxx:448''').&lt;br /&gt;
  |{{cite web |url=http://sourceforge.net/p/flightgear/mailman/message/33686356/&lt;br /&gt;
     |title=&amp;lt;nowiki&amp;gt;Re: [Flightgear-devel] Launcher issues on Linux&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
     |author=&amp;lt;nowiki&amp;gt;Rebecca N. Palmer&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
     |date=&amp;lt;nowiki&amp;gt;2015-04-01&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
   }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 12:48, 1 April 2015 (EDT)&lt;br /&gt;
&lt;br /&gt;
== chrome specific port ==&lt;br /&gt;
&lt;br /&gt;
Hi Red Leader, when/if you do come up with a chrome specific version of the script, I would suggest to refactor existing APIs accordingly, so that we can come up with a common library of general purpose/utility helpers, so that both scripts can co-exist and use a common/shared file (think all the extraction/transformation logic), by referencing an external .js/JavaScript file that will be maintained/updated and hosted separately. I think this could be accomplished easily using jsfiddle. So basically, I am suggesting to come up with a shared back-end for both versions of the script. Given the complexity we're reaching meanwhile, as well as the number of edits and contributors, it may also make sense to consider using github for this at some point. One of the main advantages being that we could easily distribute updates automatically to all people who've installed the script, without them having to do anything manually.--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 08:38, 23 June 2015 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Development resources ==&lt;br /&gt;
&lt;br /&gt;
* https://www.youtube.com/watch?v=xpXNDT0SxM0&lt;br /&gt;
* http://wiki.greasespot.net/GM_getResourceText&lt;br /&gt;
* http://stackoverflow.com/questions/14594346/create-a-config-or-options-page-for-a-greasemonkey-script&lt;br /&gt;
&lt;br /&gt;
== Future focus/development and priorities (De-quoting) ==&lt;br /&gt;
&lt;br /&gt;
Given that most people involved in maintaining the wiki don't seem to particularly appreciate the nature of articles consisting mainly of quotes, and that we don't seem to have any other good way to populate new articles quickly, I was thinking of changing the focus of the script to dynamically create articles using quotes (with proper refs), that would be merely copy-edited, i.e. using the process we are currently using to &amp;quot;de-quote&amp;quot; such articles by 1) categorizing related quotes, 2) coming up with headers/sub-headers, 3) re-writing/merging certain quotes, 4) attributing them - linking back to the quotes archives.&lt;br /&gt;
Should we decide to pursue this, the script would be turned into a &amp;quot;wizard&amp;quot; where we can topics and sub-topics (wiki headings) and then add arbitrary text using the existing approach, but without using cquotes - i.e. the focus would be on extracting relevant contents, distilling them down and adding plenty of refs, including a references section at the bottom. Some tokens/words could be changed dynamically, but some kind of proof-reading/copy-editing would still need to be done afterwards, because people tend to use first person speech in their announcements/postings, which we would need to convert to 3rd person semi-automagically. Thoughts/ideas ?--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 07:11, 15 November 2015 (EST)&lt;br /&gt;
&lt;br /&gt;
== changing and automating regex/xpath handling ==&lt;br /&gt;
{{See also|#Genetic_Expression_solver}}&lt;br /&gt;
&lt;br /&gt;
We have currently hard-coded handling of different websites, regexes and xpath expressions so that things are a  bit fragile at the moment, and once a website changes its style/template, our script would break immediately. However, we could change the way the script works by using a very simple NN (neural network) to come up with matching regex/xpath expressions automatically. The way this could work would be &amp;quot;supervised&amp;quot; training, where we would replace/adapt our existing CONFIG hash with a vector of URLs and contents to be extracted (date, time, title, posting). This kind of data would suffice entirely for a neural network to self-train itself and &amp;quot;learn&amp;quot; how to come up with regex/xpath expressions to extract the relevant contents, including not only hard-coded websites like sourceforge, but even completely different websites (think gmane) - because the &amp;quot;learning&amp;quot; routine would self-adapt by looking at how to get its contents, and never contain any hard-coded regex/xpath expressions anymore. The CONFIG hash would end up being a vector with &amp;quot;training data&amp;quot; for different websites to be supported. And whenever an expression fails, it could re-train itself accordingly.--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 13:33, 15 November 2015 (EST)&lt;br /&gt;
&lt;br /&gt;
== nested quotes and AJAX for thread titles ==&lt;br /&gt;
&lt;br /&gt;
{{FGCquote&lt;br /&gt;
|1= http://sourceforge.net/p/flightgear/mailman/message/33451055/&lt;br /&gt;
{{cquote|As we move forward with FlightGear development and future versions, we will be expanding the &amp;quot;in app&amp;quot; aircraft center. This dialog inside flightgear lets you select, download, and switch to any of the aircraft in the library.|Curt}}&lt;br /&gt;
|2= {{cite web&lt;br /&gt;
  | url    = http://forum.flightgear.org/viewtopic.php?p=259879#p259879&lt;br /&gt;
  | title  = &amp;lt;nowiki&amp;gt;Re: New Canvas GUI&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  | author = &amp;lt;nowiki&amp;gt;Hooray&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  | date   = Oct 7th, 2015&lt;br /&gt;
  }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== AJAX mode/testing ==&lt;br /&gt;
&lt;br /&gt;
We should probably add a dialog to store credentials that we can use for accessing the wiki, which would need to be shown after installing the script, i.e. first-time use&lt;br /&gt;
&lt;br /&gt;
* http://stackoverflow.com/questions/14594346/create-a-config-or-options-page-for-a-greasemonkey-script&lt;br /&gt;
* http://commons.oreilly.com/wiki/index.php/Greasemonkey_Hacks/Getting_Started#During_Installation&lt;br /&gt;
* https://www.safaribooksonline.com/library/view/greasemonkey-hacks/0596101651/ch01s06.html&lt;br /&gt;
&lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 12:59, 20 November 2015 (EST)&lt;br /&gt;
&lt;br /&gt;
== libraries ==&lt;br /&gt;
&lt;br /&gt;
Referring to the [[#Hosting]] section, and my comment on wanting to use additional libs (like jQuery), I am primarily thinking about using a wizard-framework (e.g. jQuery steps) and a framework for creating wikimedia editor plugins (actions):&lt;br /&gt;
&lt;br /&gt;
* http://mstratman.github.io/jQuery-Smart-Wizard/&lt;br /&gt;
* http://www.jquery-steps.com/&lt;br /&gt;
* http://www.jqueryrain.com/demo/jquery-step-form-wizard/&lt;br /&gt;
* https://www.mediawiki.org/wiki/Extension:WikiEditor&lt;br /&gt;
&lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 12:07, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== About dequoting the script's article ==&lt;br /&gt;
&lt;br /&gt;
Thanks for doing this, but I am frankly not sure if it's worth the effort - there are much more popular/important articles using tons of quotes than this one, and given the reputation of the script, having quotes in this article may actually be a useful thing to make the case for having quotes in the first place - thus, I would frankly not spend much time going through this particular article - in fact, I'd be very surprised if the greasyfork download stats showed more than 3-5 people actually downloading, and using, the script - so this is really just a niche tool, and we probably better spend our time doing other things, and reviewing other wiki articles, than the script's article - at the very least, I would suggest to retain the references to the original discussions revolving these quotes (just my 2c). --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 19:00, 2 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
: {{done}} I've added back the quotes as references. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 02:53, 3 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Script configuration (persistence) ==&lt;br /&gt;
&lt;br /&gt;
* https://wiki.greasespot.net/GM_config&lt;br /&gt;
* https://github.com/sizzlemctwizzle/GM_config/wiki&lt;br /&gt;
* https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API&lt;br /&gt;
&lt;br /&gt;
== Work in progress ==&lt;br /&gt;
&lt;br /&gt;
We have now several more or less related development efforts going on, and the code is also growing because of that - so it seems to make sense to summarize what's been going on recently. In general, all changes were made in response to the collection of feature requests and ideas we have accumulated over time  - specifically, that means that the following roadmap is in the process of being implemented:&lt;br /&gt;
&lt;br /&gt;
* establish unit testing, and add a few self-tests, so that the script can be more easily tested, updated/reviewed in the future&lt;br /&gt;
* rework the script to more easily support other sources (think gmane)&lt;br /&gt;
* make it much easier to update modified xpath/regex expressions (i.e. provide a UI for that)&lt;br /&gt;
* support persistence for script-specific settings&lt;br /&gt;
* make it easier for people to port/maintain the script by encapsulating platform specifics&lt;br /&gt;
* support asynchronous fetching of postings (AJAX), e.g. to fetch posting titles, attachments etc&lt;br /&gt;
* prepare the groundwork for supporting template-based output formats (think newsletter, changelog, articles)&lt;br /&gt;
* review what's necessary to allow the script to update fgcquote-based quotes automagically&lt;br /&gt;
&lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 16:47, 4 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== External genetic/neural network libraries ==&lt;br /&gt;
While uploading the latest version of the script, I noticed that the Genetic and Synaptic libraries are hosted on sites not on [https://greasyfork.org/en/help/external-scripts the approved GreasyFork list]. Shall I ask them to host them? -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 13:28, 11 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
: Thanks for pointing that out, I missed that completely, because everything is working correctly here - but obviously, I rarely get to actually download/install the latest version via greasyfork. Those libs should be safe to be added to the list, i.e. they're fairly established/popular, lest I'd not be using them. For now, this is just an experiment anyway. The idea is to update the xpath/regex code to evolve if/when the underlying website (theme) changes. But if there is a problem, we could use other libs - the code is just used for testing ATM. --[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 13:41, 11 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
* https://github.com/subprotocol/genetic-js&lt;br /&gt;
* https://github.com/cazala/synaptic&lt;br /&gt;
&lt;br /&gt;
:: {{ongoing}} I have submitted the libraries to the JSDelivr CDN; once they are up, I'll change the source URLs in the script and update it on GreasyFork as well. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 18:32, 17 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Genetic Expression solver ==&lt;br /&gt;
[[File:Instant-cquotes-genetic-regex-solving.png|thumb|Screenshot showing the instant cquotes script with integrated regex solving support using genetic algorithms.]]&lt;br /&gt;
&lt;br /&gt;
The genetic-js framework has been integrated, it is intended to help solve xpath/regex expressions procedurally using genetic algorithms/programming. &lt;br /&gt;
&lt;br /&gt;
The idea is to provide a set of desired outputs (needles), available input data (haystack), and use existing (possibly outdated) regex/xpath expressions to seed a pool with potential solutions for retrieving the desired output. For now, this is just proof-of-concept, i.e. just an experiment.&lt;br /&gt;
&lt;br /&gt;
For example, let's consider the typical format of a from header for any sourceforge posting:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var regexTests = [&lt;br /&gt;
  {haystack: &amp;quot;From: John Doe &amp;lt;John@do...&amp;gt; - 2020-07-02 17:36:03&amp;quot;, needle: &amp;quot;John Doe&amp;quot;}, &lt;br /&gt;
  {haystack: &amp;quot;From: Marc Twain &amp;lt;Marc@ta...&amp;gt; - 2010-01-03 07:36:03&amp;quot;, needle: &amp;quot;Marc Twain&amp;quot;},&lt;br /&gt;
  {haystack: &amp;quot;From: George W. Bush &amp;lt;GWB@wh...&amp;gt; - 2055-11-11 17:33:13&amp;quot;, needle: &amp;quot;George W. Bush&amp;quot;}&lt;br /&gt;
];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The basic idea is to run a fitness function and score regex expressions based on not throwing an exception (which makes them valid), and by checking if the desired tokens are part of the output string, and evolve (mutate/cross-over) the &amp;quot;fittest&amp;quot; expressions - i.e. those that satisfy at least /some/ of the heuristics.&lt;br /&gt;
&lt;br /&gt;
Some of the metrics that can be used by the fitness function to determine if an expression is &amp;quot;fit&amp;quot;, are:&lt;br /&gt;
* valid expression&lt;br /&gt;
* relative offset/excess bytes in matches string&lt;br /&gt;
* number of examples it can successfully extract&lt;br /&gt;
* length of the expression&lt;br /&gt;
* runtime of the expression&lt;br /&gt;
&lt;br /&gt;
The search space, and runtime, can be significantly reduced by looking at similarities between all examples and coming up with a subset string that contains all identical components (e.g. the &amp;lt;code&amp;gt;From:&amp;lt;/code&amp;gt; part in the author regex) and use that for seeding the initial generations.&lt;br /&gt;
&lt;br /&gt;
Ultimately, this would allow the script to self-update its regex/xpath expressions if/when the underlying website (themes) change, but it would also allow to add support for new websites, without ever manually adding the required xpath/regex expressions, i.e. all that is needed is a sufficiently large number of example datasets to obtain the author, date and title information, and a URL for the script to download the HTML markup of the posting in question:&lt;br /&gt;
&lt;br /&gt;
{{Note|The date field won't work as is, because it's actually post-processed using a transformation function, so we'd need to undo the transformation or use the actual date string instead}}&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt; // vector with tests to be executed for sanity checks (unit testing)&lt;br /&gt;
    tests: [&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://sourceforge.net/p/flightgear/mailman/message/35059454/',&lt;br /&gt;
        author: 'Erik Hofman',&lt;br /&gt;
        date: 'May 3rd, 2016', // NOTE: using the transformed date here &lt;br /&gt;
        title: 'Re: [Flightgear-devel] Auto altimeter setting at startup (?)'&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://sourceforge.net/p/flightgear/mailman/message/35059961/',&lt;br /&gt;
        author: 'Ludovic Brenta',&lt;br /&gt;
        date: 'May 3rd, 2016',&lt;br /&gt;
        title: 'Re: [Flightgear-devel] dual-control-tools and the limit on packet size'&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://sourceforge.net/p/flightgear/mailman/message/20014126/',&lt;br /&gt;
        author: 'Tim Moore',&lt;br /&gt;
        date: 'Aug 4th, 2008',&lt;br /&gt;
        title: 'Re: [Flightgear-devel] Cockpit displays (rendering, modelling)'&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        url: 'https://sourceforge.net/p/flightgear/mailman/message/23518343/',&lt;br /&gt;
        author: 'Tim Moore',&lt;br /&gt;
        date: 'Sep 10th, 2009',&lt;br /&gt;
        title: '[Flightgear-devel] Atmosphere patch from John Denker'&lt;br /&gt;
      } // add other tests below&lt;br /&gt;
&lt;br /&gt;
    ], // end of vector with self-tests&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note how this no longer contains any hard-coded xpath/regex expressions - instead, the script can refer to the website specific defaults, and try those first, and if they fail, use those to seed new generations and evolve them procedurally until all tests succeed.&lt;br /&gt;
&lt;br /&gt;
For a regex to be valid, it must work for all tests/examples.&lt;br /&gt;
&lt;br /&gt;
Once the regex solver is working correctly, the code can be further generalized to also evolve xpath expressions (NOTE: the DOMParser API is /not/ available to webworkers ...) and chain those two components together.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* http://regex.inginf.units.it/how.html&lt;br /&gt;
* http://www.i-programmer.info/programming/perl/9503-automatically-generating-regular-expressions-with-genetic-programming.html&lt;br /&gt;
* http://jkff.info/articles/ire/&lt;br /&gt;
* http://www.networkworld.com/article/2955126/software/genetic-programming-meets-regular-expressions.html&lt;br /&gt;
* https://handcraftsman.wordpress.com/2012/04/11/evolving-a-regular-expression-with-go/&lt;br /&gt;
* http://stackoverflow.com/questions/4880402/how-to-auto-generate-regex-from-given-list-of-strings&lt;br /&gt;
* http://regex.inginf.units.it/&lt;br /&gt;
* http://www.genetic-programming.org/hc2014/Bartoli-Paper.pdf&lt;/div&gt;</summary>
		<author><name>Elgaton</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Template:Forum_link&amp;diff=98344</id>
		<title>Template:Forum link</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Template:Forum_link&amp;diff=98344"/>
		<updated>2016-05-17T20:01:00Z</updated>

		<summary type="html">&lt;p&gt;Elgaton: Try using the decimal version of the HTML entity&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;span class=&amp;quot;plainlinks&amp;quot;&amp;gt;[https://forum.flightgear.org/viewtopic.php?&amp;lt;!--&lt;br /&gt;
--&amp;gt;{{#if:{{{f|}}}|f={{{f}}}&amp;lt;!-- Add an ampersand if t, p or hilit are present afterwards&lt;br /&gt;
--&amp;gt;{{#if:{{{t|}}}|&amp;amp;|{{#if:{{{p|}}}|&amp;amp;|{{#if:{{{hilit|}}}|&amp;amp;|}}}}}}&amp;lt;!--&lt;br /&gt;
--&amp;gt;|}}{{#if:{{{t|}}}|t={{{t}}}&amp;lt;!-- Add an ampersand if p or hilit are present afterwards&lt;br /&gt;
--&amp;gt;{{#if:{{{p|}}}|&amp;amp;|{{#if:{{{hilit|}}}|&amp;amp;|}}}}&amp;lt;!--&lt;br /&gt;
--&amp;gt;|}}{{#if:{{{p|}}}|p={{{p}}}&amp;lt;!-- Add an ampersand if hilit is present afterwards&lt;br /&gt;
--&amp;gt;{{#if:{{{hilit|}}}|&amp;amp;|}}&amp;lt;!--&lt;br /&gt;
--&amp;gt;|}}{{#if:{{{hilit|}}}|hilit={{{hilit}}}|}}{{#if:{{{label|}}}|&amp;amp;#35;{{{label}}}|}} {{#if:{{{title|}}}|''{{{title}}}'' on the forum|Forum link}}]&amp;lt;/span&amp;gt;{{#if: {{{noicon|}}} | | &amp;amp;#32;[[File:FlightGear icon 15px.png|This is a link to the FlightGear forum|link=Template:Forumref]] }}&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{Informative template|1=&lt;br /&gt;
__NOTOC__&lt;br /&gt;
== Goal ==&lt;br /&gt;
A template to standardize forum links.&lt;br /&gt;
&lt;br /&gt;
== Usage ==&lt;br /&gt;
 {{obr}}'''forumref'''{{!}}title={{!}}''t=''{{!}}''p=''{{!}}''label=''{{!}}''hilit=''{{!}}''f=''{{!}}''noicon=''{{cbr}}&lt;br /&gt;
&lt;br /&gt;
; title: Topic title&lt;br /&gt;
&lt;br /&gt;
; t: Thread number to be passed to phpBB's viewtopic.php (optional)&lt;br /&gt;
&lt;br /&gt;
; p: Post number to be passed to phpBB's viewtopic.php (optional)&lt;br /&gt;
&lt;br /&gt;
; label: HTML label, used for jumping to posts (optional)&lt;br /&gt;
&lt;br /&gt;
; hilit: Words on the forum posts to be highlighted (optional)&lt;br /&gt;
&lt;br /&gt;
; f: Forum number to be passed to phpBB's viewtopic.php (optional)&lt;br /&gt;
&lt;br /&gt;
; noicon: If true, the little FlightGear icon ([[File:FlightGear icon 15px.png]]) will not be shown.&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;{{forumref|title=FlightGear Newsletter|t=7794}}&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{forumref|title=FlightGear Newsletter|t=7794}}&lt;br /&gt;
&lt;br /&gt;
== Related template ==&lt;br /&gt;
* {{tl|forum}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Link templates]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Elgaton</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Template:Forum_link&amp;diff=98343</id>
		<title>Template:Forum link</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Template:Forum_link&amp;diff=98343"/>
		<updated>2016-05-17T19:58:55Z</updated>

		<summary type="html">&lt;p&gt;Elgaton: Fix numbered list being created when the ''label'' parameter was passed&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;span class=&amp;quot;plainlinks&amp;quot;&amp;gt;[https://forum.flightgear.org/viewtopic.php?&amp;lt;!--&lt;br /&gt;
--&amp;gt;{{#if:{{{f|}}}|f={{{f}}}&amp;lt;!-- Add an ampersand if t, p or hilit are present afterwards&lt;br /&gt;
--&amp;gt;{{#if:{{{t|}}}|&amp;amp;|{{#if:{{{p|}}}|&amp;amp;|{{#if:{{{hilit|}}}|&amp;amp;|}}}}}}&amp;lt;!--&lt;br /&gt;
--&amp;gt;|}}{{#if:{{{t|}}}|t={{{t}}}&amp;lt;!-- Add an ampersand if p or hilit are present afterwards&lt;br /&gt;
--&amp;gt;{{#if:{{{p|}}}|&amp;amp;|{{#if:{{{hilit|}}}|&amp;amp;|}}}}&amp;lt;!--&lt;br /&gt;
--&amp;gt;|}}{{#if:{{{p|}}}|p={{{p}}}&amp;lt;!-- Add an ampersand if hilit is present afterwards&lt;br /&gt;
--&amp;gt;{{#if:{{{hilit|}}}|&amp;amp;|}}&amp;lt;!--&lt;br /&gt;
--&amp;gt;|}}{{#if:{{{hilit|}}}|hilit={{{hilit}}}|}}{{#if:{{{label|}}}|&amp;amp;num;{{{label}}}|}} {{#if:{{{title|}}}|''{{{title}}}'' on the forum|Forum link}}]&amp;lt;/span&amp;gt;{{#if: {{{noicon|}}} | | &amp;amp;#32;[[File:FlightGear icon 15px.png|This is a link to the FlightGear forum|link=Template:Forumref]] }}&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{Informative template|1=&lt;br /&gt;
__NOTOC__&lt;br /&gt;
== Goal ==&lt;br /&gt;
A template to standardize forum links.&lt;br /&gt;
&lt;br /&gt;
== Usage ==&lt;br /&gt;
 {{obr}}'''forumref'''{{!}}title={{!}}''t=''{{!}}''p=''{{!}}''label=''{{!}}''hilit=''{{!}}''f=''{{!}}''noicon=''{{cbr}}&lt;br /&gt;
&lt;br /&gt;
; title: Topic title&lt;br /&gt;
&lt;br /&gt;
; t: Thread number to be passed to phpBB's viewtopic.php (optional)&lt;br /&gt;
&lt;br /&gt;
; p: Post number to be passed to phpBB's viewtopic.php (optional)&lt;br /&gt;
&lt;br /&gt;
; label: HTML label, used for jumping to posts (optional)&lt;br /&gt;
&lt;br /&gt;
; hilit: Words on the forum posts to be highlighted (optional)&lt;br /&gt;
&lt;br /&gt;
; f: Forum number to be passed to phpBB's viewtopic.php (optional)&lt;br /&gt;
&lt;br /&gt;
; noicon: If true, the little FlightGear icon ([[File:FlightGear icon 15px.png]]) will not be shown.&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;{{forumref|title=FlightGear Newsletter|t=7794}}&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{forumref|title=FlightGear Newsletter|t=7794}}&lt;br /&gt;
&lt;br /&gt;
== Related template ==&lt;br /&gt;
* {{tl|forum}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Link templates]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Elgaton</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Template:News&amp;diff=98319</id>
		<title>Template:News</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Template:News&amp;diff=98319"/>
		<updated>2016-05-17T14:01:32Z</updated>

		<summary type="html">&lt;p&gt;Elgaton: Dequoted&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LangSwitch&lt;br /&gt;
| en = &amp;lt;!-- English --&amp;gt;&lt;br /&gt;
: [[FlightGear Newsletter {{#time: F Y | {{{date|last month}}} | en }}]] ([[FlightGear Newsletter|archive]])&lt;br /&gt;
* '''May 17, 2016:''' The [[FlightGear Build Server]] is now able to build the 2016.2 nightly full builds with the latest [[LEBL]] scenery pack included; they can be downloaded from the [https://sourceforge.net/projects/flightgear/files/unstable/ nightly build page]. The version on the &amp;lt;tt&amp;gt;next&amp;lt;/tt&amp;gt; branch is now 2016.3.0; users compiling FlightGear from source need to recompile SimGear ''and'' FlightGear ''and'' use the latest FGData to avoid the infamous &amp;quot;version number mismatch&amp;quot; error message.&lt;br /&gt;
* '''February 17, 2016:''' FlightGear 2016.1.1 &amp;quot;San Francisco&amp;quot; is released.&lt;br /&gt;
* '''November 2015:''' FlightGear is the SourceForge [https://sourceforge.net/blog/november-2015-community-choice-project-of-the-month-flightgear/ Community Choice Project of the Month].&lt;br /&gt;
* '''April 15, 2015:''' FlightGear completes the move from [http://gitorious.org Gitorious] to [https://sourceforge.net/ SourceForge].&lt;br /&gt;
* '''February 17, 2015:''' FlightGear 3.4 is released.&lt;br /&gt;
* '''February 14, 2015:''' The [[FlightGear Wiki]] exceeds [[Special:Statistics|2,000]] articles.&lt;br /&gt;
| de = &amp;lt;!-- German --&amp;gt;&lt;br /&gt;
: [[FlightGear Newsletter {{#time: F Y | {{{date|last month}}} | en }}]] ([[FlightGear Newsletter|Archiv]])&lt;br /&gt;
* '''17. Februar 2016:''' FlightGear 2016.1.1 &amp;quot;San Francisco&amp;quot; ist freigegeben.&lt;br /&gt;
* '''2015 November:''' FlightGear ist die SourceForge [https://sourceforge.net/blog/november-2015-community-choice-project-of-the-month-flightgear/ Gemeinschaft Wahl Projekt des Monats].&lt;br /&gt;
* '''15. April 2015:''' FlightGear vervollständigt den Umzug von [http://gitorious.org Gitorious] auf [https://sourceforge.net/ SourceForge].&lt;br /&gt;
* '''17. Februar 2015:''' FlightGear 3.4 ist freigegeben.&lt;br /&gt;
* '''14. Februar 2015:''' Die [[:de:FlightGear Wiki|FlightGear Wiki]] überschreitet [[Special:Statistics|2000]] Artikel.&lt;br /&gt;
| es = &amp;lt;!-- Spanish --&amp;gt;&lt;br /&gt;
: [[FlightGear Newsletter {{#time: F Y | {{{date|last month}}} | en }}]] ([[FlightGear Newsletter|archivo]])&lt;br /&gt;
* '''17 de de febrero de, 2016:''' FlightGear 2016.1.1 &amp;quot;San Francisco&amp;quot; se libera.&lt;br /&gt;
* '''De noviembre de 2015:''' FlightGear es el SourceForge [https://sourceforge.net/blog/november-2015-community-choice-project-of-the-month-flightgear/ Community Choice Proyecto del mes].&lt;br /&gt;
* '''15 de de abril de, 2015:''' FlightGear completa el paso de [http://gitorious.org Gitorious] a [https://sourceforge.net/ SourceForge].&lt;br /&gt;
* '''17 de de febrero de, 2015:''' FlightGear 3.4 se libera.&lt;br /&gt;
* '''14 de de febrero de, 2015:''' El [[FlightGear Wiki]] excede de [[Special:Statistics|2.000]] artículos.&lt;br /&gt;
| ca = &amp;lt;!-- Catalan --&amp;gt;&lt;br /&gt;
: [[FlightGear Newsletter {{#time: F Y | {{{date|last month}}} | en }}]] ([[FlightGear Newsletter|Arxiu]])&lt;br /&gt;
* '''17 de de febrer de, 2016:''' FlightGear 2016.1.1 &amp;quot;San Francisco&amp;quot; s'allibera.&lt;br /&gt;
* '''De novembre de 2015:''' FlightGear és el SourceForge [https://sourceforge.net/blog/november-2015-community-choice-project-of-the-month-flightgear/ Community Choice Projecte del mes].&lt;br /&gt;
* '''15 d'abril de, 2015:''' FlightGear completa el pas de [http://gitorious.org Gitorious] a [https://sourceforge.net/ SourceForge].&lt;br /&gt;
* '''17 de de febrer de, 2015:''' FlightGear 3.4 s'allibera.&lt;br /&gt;
* '''14 a de febrer de, 2015:''' El [[:ca:FlightGear Wiki|FlightGear Wiki]] excedeix de [[Special:Statistics|2.000]] articles.&lt;br /&gt;
| it = &amp;lt;!-- Italian --&amp;gt;&lt;br /&gt;
: [[FlightGear Newsletter {{#time: F Y | {{{date|last month}}} | en }}]] ([[FlightGear Newsletter|archivio]])&lt;br /&gt;
* '''17 febbraio 2016:''' FlightGear 2016.1.1 &amp;quot;San Francisco&amp;quot;, viene rilasciato.&lt;br /&gt;
* '''novembre 2015:''' FlightGear è la SourceForge [https://sourceforge.net/blog/november-2015-community-choice-project-of-the-month-flightgear/ Community Choice Progetto del mese].&lt;br /&gt;
* '''15 aprile 2015:''' FlightGear completa il passaggio da [http://gitorious.org Gitorious] a [https://sourceforge.net/ SourceForge].&lt;br /&gt;
* '''17 febbraio 2015:''' FlightGear 3.4 viene rilasciato.&lt;br /&gt;
* '''14 febbraio 2015:''' Il [[FlightGear Wiki]] supera [[Special:Statistics|2.000]] articoli.&lt;br /&gt;
| nl = &amp;lt;!-- Dutch --&amp;gt;&lt;br /&gt;
: [[FlightGear Newsletter {{#time: F Y | {{{date|last month}}} | en }}]] ([[FlightGear Newsletter|archief]])&lt;br /&gt;
* '''17 februari 2016:''' FlightGear 2016.1.1 &amp;quot;San Francisco&amp;quot; wordt losgelaten.&lt;br /&gt;
* '''November 2015:''' FlightGear is de SourceForge [https://sourceforge.net/blog/november-2015-community-choice-project-of-the-month-flightgear/ Gemeenschap Choice Project van de Maand].&lt;br /&gt;
* '''15 april 2015:''' FlightGear de overgang van [http://gitorious.org Gitorious] tot [https://sourceforge.net/ SourceForge] voltooid.&lt;br /&gt;
* '''17 februari 2015:''' FlightGear 3.4 is vrijgegeven.&lt;br /&gt;
* '''14 februari 2015:''' De [[FlightGear Wiki]] hoger dan [[Special:Statistics|2000]] artikelen.&lt;br /&gt;
| pl = &amp;lt;!-- Polish --&amp;gt;&lt;br /&gt;
: [[FlightGear Newsletter {{#time: F Y | {{{date|last month}}} | en }}]] ([[FlightGear Newsletter|archiwum]])&lt;br /&gt;
* '''17 lutego 2016:''' FlightGear 2016.1.1 &amp;quot;San Francisco&amp;quot; zostanie zwolniony.&lt;br /&gt;
* '''Listopad 2015:''' FlightGear jest SourceForge [https://sourceforge.net/blog/november-2015-community-choice-project-of-the-month-flightgear/ Społeczność Wybór Projekt miesiąca].&lt;br /&gt;
* '''15 kwietnia 2015:''' FlightGear kończy przejście od [http://gitorious.org Gitorious] na [https://sourceforge.net/ SourceForge].&lt;br /&gt;
* '''17 lutego 2015:''' FlightGear 3.4 zostanie zwolniony.&lt;br /&gt;
* '''14 lutego 2015:''' [[:pl:FlightGear Wiki|FlightGear Wiki]] przekracza [[Special:Statistics|2000]] artykułów.&lt;br /&gt;
| pt = &amp;lt;!-- Português --&amp;gt;&lt;br /&gt;
: [[FlightGear Newsletter {{#time: F Y | {{{date|last month}}} | en }}]] ([[FlightGear Newsletter|arquivo]])&lt;br /&gt;
* '''17 de Fevereiro de 2016:''' Lançado o FlightGear 2016.1.1 &amp;quot;San Francisco&amp;quot;.&lt;br /&gt;
* '''Novembro de 2015:''' FlightGear é escolhido o [https://sourceforge.net/blog/november-2015-community-choice-project-of-the-month-flightgear/ Projeto do Mês da Comunidade SourceForge].&lt;br /&gt;
* '''15 de Abril de 2015:''' FlightGear completa a mudança do [http://gitorious.org Gitorious] para [https://sourceforge.net/ SourceForge].&lt;br /&gt;
* '''17 de Fevereiro de 2015:''' Lançado o FlightGear 3.4.&lt;br /&gt;
* '''14 de Fevereiro de 2015:''' O [[FlightGear Wiki]] ultrapassou [[Special:Statistics|2,000]] artigos.&lt;br /&gt;
}}&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{Informative template|1=&lt;br /&gt;
This template contains the news section as displayed on the [[Main Page]], for each single language.&lt;br /&gt;
&lt;br /&gt;
== Usage ==&lt;br /&gt;
* Use no more than five news items (excluding the newsletter)&lt;br /&gt;
* Use short text lines&lt;br /&gt;
* Use present tense&lt;br /&gt;
&lt;br /&gt;
== Related templates ==&lt;br /&gt;
* {{tl|Localized Release Announcement}}&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Templates]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Elgaton</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=FlightGear_wiki:Village_pump&amp;diff=98257</id>
		<title>FlightGear wiki:Village pump</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=FlightGear_wiki:Village_pump&amp;diff=98257"/>
		<updated>2016-05-15T13:06:03Z</updated>

		<summary type="html">&lt;p&gt;Elgaton: /* Reorganizing the Git articles */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Archives|[[/Archive 2012|2012]]|[[/Archive 2013|2013]]|[[/Archive 2014|2014]]|[[/Archive 2015|2015]]}}&lt;br /&gt;
{{shortcut|FGW:VP}}&lt;br /&gt;
Welcome to the '''Village Pump'''. This page is used to discuss the technical issues, operations and guidelines of the [[FlightGear wiki]].&lt;br /&gt;
&lt;br /&gt;
Please &amp;lt;span class=&amp;quot;plainlinks&amp;quot;&amp;gt;[{{fullurl:{{FULLPAGENAME}}|action=edit&amp;amp;section=new}} add new topics]&amp;lt;/span&amp;gt; to the '''bottom''' of this page.&lt;br /&gt;
&lt;br /&gt;
Old discussion should be moved to a [[FlightGear wiki:Village pump/Archive YEAR]]. These discussions can then be moved to a relevant talk page if appropriate.&lt;br /&gt;
&lt;br /&gt;
== Welcome template? ==&lt;br /&gt;
I have been thinking about suggesting a welcome template, for example named {{obr}}welcome{{cbr}}, to place on top of (at least) new users user discussion pages.&lt;br /&gt;
&lt;br /&gt;
It should welcome the (new) user&lt;br /&gt;
&lt;br /&gt;
In addition, it should probably mention and/or link to pages mentioning:&lt;br /&gt;
* The introduction page/tutorial (Hmm, I do not think I did finish that one. See [[Help talk:Tutorial]] ([http://wiki.flightgear.org/index.php?title=Help_talk:Tutorial&amp;amp;oldid=70843 perm])).&lt;br /&gt;
* Help pages&lt;br /&gt;
* How to use categories (in particular not like #tags, ;-) but also that image and article categories should be separate, but link to each other)&lt;br /&gt;
* The portals&lt;br /&gt;
* The style manual&lt;br /&gt;
* Discussion pages and where to discuss what:&lt;br /&gt;
** How to use discussion pages&lt;br /&gt;
** The wiki in general:  The village pump (this page)&lt;br /&gt;
** Wiki articles:  Article discussion pages&lt;br /&gt;
** Wiki user actions:  User discussion pages&lt;br /&gt;
&lt;br /&gt;
Maybe it should also mention that FGAddon aircraft, effects, other features etc. (except for their articles) and their bugs should be discussed on the forum, unless developers say otherwise, and that core features should be discussed on the developer mailing list and core bugs on the bug tracker.&lt;br /&gt;
&lt;br /&gt;
—[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 20:31, 30 January 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
: I think this is a great idea.  A nice concise summary with links to help a new user navigate the FlightGear jungle would be a great addition.  It should however remain very short with simple sentences - while being complete - as many users are not native speakers.  So maybe there should be translations of the template with manually added links at the bottom for easy access to all the translations?&lt;br /&gt;
&lt;br /&gt;
: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 03:35, 12 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: Regarding an introduction article, I have come to the conclusion that a complete but long article is probably not as helpful as short but specific help pages.  In essence the latter would be easier to navigate and absorb.  I have therefore started to slowly split up some of the help pages and have added one more section to [[Help:Contents]].&lt;br /&gt;
:: I think that a welcome phrase, a link to that page and the [[FlightGear wiki:Manual of Style|style manual]] might actually suffice for a welcome template for now.  It is at least better than what we currently have (i.e. more or less nothing).&lt;br /&gt;
:: —[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 14:47, 4 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: I now consider&lt;br /&gt;
::* A Welcome message&lt;br /&gt;
::* A link to this page&lt;br /&gt;
::* A link to the help pages&lt;br /&gt;
::* A link to the manual of style&lt;br /&gt;
::* Some final welcoming words&lt;br /&gt;
&lt;br /&gt;
:: A welcome template should probably also very briefly mention a pet peeve of mine: the categories.&lt;br /&gt;
:: Many (if not most) image uploaders seem to treat them like tags, but if say all screenshots of aircraft (probably &amp;gt;2000) would end up at [[:Category:Aircraft]] (instead of under a subcategory to [[:Category:Screenshots of aircraft]]), of what use would that page be when looking for a specific one?  If people would like to be able to search for an aircraft, a concise but comprehensive image description is very hard to beat.&lt;br /&gt;
:: How do I convey all that in a way that is, short, to the point and easy to absorb (and act by)? And where is the best place?&lt;br /&gt;
:: —[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 02:46, 8 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: An early draft is now at [[User:Johan G/Template:Welcome to the wiki]]&lt;br /&gt;
:: —[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 02:52, 18 April 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
::: Some comments on the draft:&lt;br /&gt;
::: * I'm not fully sure about using a prominent box - I think it stands out a bit too much. Wikipedia {{wikipedia|Template:Welcome|uses a simple thread on the Talk page}}; as an alternative, we could use lighter colors.&lt;br /&gt;
::: * I've also expanded the text a bit. My proposal would be (I've put it in a box, but I'm for the &amp;quot;thread&amp;quot; solution):&lt;br /&gt;
&amp;lt;div style=&amp;quot;background: #fff; border: 1px #585858 solid; padding: 12px; margin: 12px&amp;quot;&amp;gt;&lt;br /&gt;
[[Image:Example.png|left]] '''Welcome to the FlightGear wiki, {{#if: {{{name|}}} | {{{name}}} | {{BASEPAGENAME}}}}'''! We hope you will enjoy your stay!&lt;br /&gt;
&lt;br /&gt;
See [[Help:Contents#Reading|Reading]] to learn how wikis work. You can also [[Special:CategoryTree/Root category|browse the existing page categories]].&lt;br /&gt;
&lt;br /&gt;
Should you wish to create or edit some articles, ''do so''! Here are some resources to get you started:&lt;br /&gt;
* [[Help:Contents#Editing|How to edit pages]]&lt;br /&gt;
* [[Help:Discussion pages|Discussion pages]], where we discuss and agree on potential improvements&lt;br /&gt;
* [[FlightGear wiki:Manual of Style|The Manual of Style]], a set of guidelines to help editors maintain a consistent style and formatting (please follow them)&lt;br /&gt;
* [[Help:Contents|Wiki help page]]&lt;br /&gt;
&lt;br /&gt;
If you have any questions, just start a topic on the [[FlightGear wiki:Village pump|''Discuss!'' page]]. Again, welcome!&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
::: ...where the image on the left is an appropriately chosen icon.&lt;br /&gt;
::: Finally, we could use the {{mediawiki|Extension:NewUserMessage|NewUserMessage extension}} to have the wiki software automatically post the message to the new user's talk page.&lt;br /&gt;
::: ---- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 17:30, 1 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Permanently removing spam bots ==&lt;br /&gt;
For permanently removing spam bots, has the [https://www.mediawiki.org/wiki/Extension:UserMerge UserMerge] Mediawiki extension been considered?  I use that regularly on [http://wiki.nmr-relax.com my own wiki], though there we have also reverted to communicating to the person via email before manually granting access (probably not an option here), as all of the Mediawiki captcha methods were recently cracked.&lt;br /&gt;
&lt;br /&gt;
[[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 03:15, 12 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
: Oh, for the extension, we simply have a user called 'Spam bot' in a blocked state, and merge the spam bot accounts into this one, deleting the old account.&lt;br /&gt;
: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 03:20, 12 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: I'd use the [https://www.mediawiki.org/wiki/Extension:AbuseFilter abuse filter extension] instead (much more powerful and automated) - other users have also proposed different remedies, see [http://forum.flightgear.org/viewtopic.php?f=42&amp;amp;t=28734 this forum thread]. Anyway, Gijs is going to upgrade MediaWiki shortly and review the current anti-spam measures.&lt;br /&gt;
:: -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 06:26, 13 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
::: A lot of the spam bots are using their name as advertising nowadays, so the [https://www.mediawiki.org/wiki/Extension:UserMerge UserMerge] extension is the only one I know which will allow a user and associated name to be permanently deleted.&lt;br /&gt;
&lt;br /&gt;
::: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 12:04, 14 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:::: The problem now is that they're also adding the information to the page title, so that it will still show up in the deletion logs [http://wiki.flightgear.org/Special:Log/delete] in other words, there's still some SEO juice associated with deleted entries ... Another idea would be to allow admins to temporarily disable wiki registrations/article creation, e.g. if more than 2 admins agree, this could be done to protect the wiki from spam attacks.&lt;br /&gt;
&lt;br /&gt;
::::: Hooray, you should sign your posts ;)  The bots don't target the deletion logs, as that's a little pointless.  It's a Special:* page, and the default Mediawiki robots.txt file tells all search engines to not index these pages.  User pages, page histories, etc. are however normally indexed.&lt;br /&gt;
&lt;br /&gt;
::::: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 14:36, 19 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: The point was not what the bots are targeting, but what shows up in the logs - i.e. SEO-wise - Gijs' article blacklist stuff should help with that hopefully. PS: I could not find the signature button on the mobile device I am using, and I am not too good at remembering the correct number of tildes ;-) [[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 15:04, 19 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
== WIP vs. Under construction ==&lt;br /&gt;
I have been beginning to miss the under construction template[http://wiki.flightgear.org/index.php?title=Template:Under_Construction&amp;amp;direction=prev&amp;amp;oldid=46229] more and more (though I could it definitively could be improved).&lt;br /&gt;
&lt;br /&gt;
I have begun to appreciate the need to differentiate between letting readers that a page is to be considered a yet to be finished construction site (though we in a way have that through the {{tl|incomplete}} template) and letting the reader (and other editors) that a page will receive a large amount of work for some hours or even days, usually the use for {{tl|WIP}}.&lt;br /&gt;
&lt;br /&gt;
In summary i miss templates giving a clear distinction between conditions akin to &amp;quot;Under construction&amp;quot; and &amp;quot;Caution - Wet floors&amp;quot;, rather than &amp;quot;being worked on&amp;quot; and &amp;quot;could need more work&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
—[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 10:11, 17 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
== [[Fr/Pilote automatique]] ==&lt;br /&gt;
Bonjour,&lt;br /&gt;
&lt;br /&gt;
Je viens de créer la page de traduction en français de l'article original en anglais [[Autopilot]]. Vu mes faibles compétences en matière de pilotage, vu que je n'ai pas sur ma version téléchargée d'avion avec un pilote automatique, la traduction doit souffrir quelques approximations, si ce n'est des contresens plus ennuyeux. Si quelques bonnes âmes plus qualifiées pouvaient me faire la grâce d'une relecture... merci d'avance.&lt;br /&gt;
&lt;br /&gt;
Cordialement, et Hop ! --[[User:F-WTSS|F-WTSS]] ([[User talk:F-WTSS|talk]]) 15:30, 18 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
== MediaWiki updated to 1.26.2 ==&lt;br /&gt;
I've updated MediaWiki to the latest stable release (1.26.2) today. I've still got to update some of the extensions, so there may be regressions for now. Please report bugs if you find any. For a list of changes, see https://www.mediawiki.org/wiki/Release_notes/1.26&lt;br /&gt;
&lt;br /&gt;
[[User:Gijs|Gijs]] ([[User talk:Gijs|talk]]) 10:47, 19 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
: Cheers!  I was hoping that it would solve the uneditable Chinese, Russian, and other non-latin character-based pages (Polish strangely as well), but unfortunately [[FlightGear_wiki:Village_pump/Archive_2015#UTF-8_language_pages_cannot_be_edited|that issue remains]].&lt;br /&gt;
&lt;br /&gt;
: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 10:54, 19 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: Hm, looks that will require quite some attention indeed. I'm afraid that'll has to wait for now.&lt;br /&gt;
:: [[User:Gijs|Gijs]] ([[User talk:Gijs|talk]]) 12:29, 19 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
=== Nasal Syntaxhighlighting ===&lt;br /&gt;
: Thanks for your efforts, btw: Nasal syntax highlighting is gone again.&lt;br /&gt;
: {{unsigned|17:22, 19 February 2016‎|Hooray}}&lt;br /&gt;
&lt;br /&gt;
:: Unfortunately this time it isn't me forgetting to copy a file. The SyntaxHighlight extension no longer uses GeSHi, but has switched to Pygments. This means our Nasal mapping no longer works and has to be re-written. If anyone is interested, be my guest. See http://pygments.org/docs/lexerdevelopment/&lt;br /&gt;
:: [[User:Gijs|Gijs]] ([[User talk:Gijs|talk]]) 12:29, 19 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
::: Hi Gijs,&lt;br /&gt;
::: I'm interested in making a Pygments Nasal lexer, but unfortunately I won't be able to work on it until the end of March at the earliest.&lt;br /&gt;
::: [[User:Red_Leader|&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;'''''Red Leader'''''&amp;lt;/span&amp;gt;]] ([[User_talk:Red_Leader|Talk]], [[Special:Contributions/Red_Leader|contribs]]) 16:59, 23 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:::: Unless Gijs is facing any problems, I don't think it's necessarily needed, see my comment/suggestion in this revision: [http://wiki.flightgear.org/index.php?title=FlightGear_wiki:Village_pump&amp;amp;oldid=93166] [[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 17:20, 23 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:::Hi Gijs,&lt;br /&gt;
:::Here's the code for a Nasal lexer. Be warned, it's thoroughly untested, but has the following features:&lt;br /&gt;
:::* Full support for all three string types (backtick, single quote, and double quote), including escapes and formatting strings (e.g., for {{func link|sprintf}}).&lt;br /&gt;
:::* All kinds of numbers, including numbers in scientific notation and octal and hex numbers.&lt;br /&gt;
:::* All global functions and variables as of FG v2016.1.1.&lt;br /&gt;
:::* Some of the commonly-used &amp;lt;code&amp;gt;props.Node&amp;lt;/code&amp;gt; methods.&lt;br /&gt;
:::* All the other things that can be expected (keywords, punctuation, etc.).&lt;br /&gt;
:::I have also created a lexer based on the XML lexer for XML with embedded Nasal, which I thought would be useful.&lt;br /&gt;
:::Regards,&lt;br /&gt;
:::[[User:Red_Leader|&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;'''''Red Leader'''''&amp;lt;/span&amp;gt;]] ([[User_talk:Red_Leader|Talk]], [[Special:Contributions/Red_Leader|contribs]]) 16:35, 2 April 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:::http://pygments.org/docs/lexerdevelopment/#adding-and-testing-a-new-lexer&lt;br /&gt;
:::&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
	Lexer for Nasal.&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
from pygments.lexer import RegexLexer, words, include, inherit, bygroups, using&lt;br /&gt;
from pygments.token import Text, Keyword, Name, String, Number, Operator, Punctuation, Comment&lt;br /&gt;
from pygments.lexers.html import XmlLexer&lt;br /&gt;
&lt;br /&gt;
__all__ = ['NasalLexer', 'XMLNasalLexer']&lt;br /&gt;
&lt;br /&gt;
class NasalLexer(RegexLexer):&lt;br /&gt;
&lt;br /&gt;
	name = 'Nasal'&lt;br /&gt;
	aliases = ['nasal']&lt;br /&gt;
	filenames = ['*.nas']&lt;br /&gt;
&lt;br /&gt;
	tokens = {&lt;br /&gt;
		'formatters': [&lt;br /&gt;
			(r'%[-#0 +]*(?:[0-9]+)?(?:\.[0-9]+)?[dis%couxXeEfFgG]', String.Interpol),&lt;br /&gt;
		],&lt;br /&gt;
		'backtick': [&lt;br /&gt;
			(r'`', String.Backtick, '#pop'),&lt;br /&gt;
			(r'[^`\\]+', String.Backtick),&lt;br /&gt;
			(r'\\n|\\r|\\t|\\`|\\\\|\\x[0-9a-fA-F]{2}', String.Escape),&lt;br /&gt;
		],&lt;br /&gt;
		'sqstring': [&lt;br /&gt;
			(r&amp;quot;'&amp;quot;, String.Single, '#pop'),&lt;br /&gt;
			(r&amp;quot;[^'\\%]+&amp;quot;, String.Single),&lt;br /&gt;
			(r&amp;quot;\\'&amp;quot;, String.Escape),&lt;br /&gt;
			include('formatters'),&lt;br /&gt;
		],&lt;br /&gt;
		'dqstring': [&lt;br /&gt;
			(r'&amp;quot;', String.Double, '#pop'),&lt;br /&gt;
			(r'[^&amp;quot;\\%]+', String.Double),&lt;br /&gt;
			(r'\\n|\\r|\\t|\\&amp;quot;|\\\\|\\x[0-9a-fA-F]{2}', String.Escape),&lt;br /&gt;
			include('formatters'),&lt;br /&gt;
		],&lt;br /&gt;
		'root': [&lt;br /&gt;
			(r'\s+', Text),&lt;br /&gt;
			(r'#.*?$'m, Comment.Single),&lt;br /&gt;
			(r':|\?|[!=&amp;lt;&amp;gt;+\-*\/~&amp;amp;|^]=?', Operator),&lt;br /&gt;
			(words(('or', 'and'), suffix=r'\b'), Operator.Word),&lt;br /&gt;
			(r'[{(\[})\]\.;,]', Punctuation),&lt;br /&gt;
			(words(('for', 'foreach', 'forindex', 'while', 'break', 'return', 'continue', 'if', 'else', 'elsif'), suffix=r'\b'), Keyword),&lt;br /&gt;
			(words(('var', 'func'), suffix=r'\b'), Keyword.Declaration),&lt;br /&gt;
			(words(('nil'), suffix=r'\b'), Keyword.Constant),&lt;br /&gt;
			(words(('me', 'arg'), suffix=r'\b'), Name.Builtin.Pseudo),&lt;br /&gt;
			(words(('new', 'del', 'getNode', 'getParent', 'getChild', 'getChildren', 'removeChild', 'removeChildren', 'removeAllChildren', 'getName', 'getIndex', 'getType', 'getAttribute', 'setAttribute', 'getValue', 'setValue', 'setIntValue', 'setBoolValue', 'setDoubleValue', 'unalias', 'alias', 'getPath', 'getBoolValue', 'remove', 'setValues', 'getValues', 'initNode'), suffix=r'\b'), Keyword.Pseudo),&lt;br /&gt;
			(r'0o[0-7]+', Number.Oct),&lt;br /&gt;
			(r'0x[0-9a-fA-F]+', Number.Hex),&lt;br /&gt;
			(r'\d*(?:\.\d*)?[eE][+-]?\d+', Number.Float),&lt;br /&gt;
			(r'\d*\.\d*', Number.Float),&lt;br /&gt;
			(r'\b[0-9]+\b', Number.Integer),&lt;br /&gt;
			(words(('D2R', 'R2D', 'FT2M', 'M2FT', 'IN2M', 'M2IN', 'NM2M', 'M2NM', 'KT2MPS', 'MPS2KT', 'FPS2KT', 'KT2FPS', 'LB2KG', 'KG2LB', 'GAL2L', 'L2GAL'), suffix=r'\b'), Name.Variable.Global),&lt;br /&gt;
			(words(('abort', 'abs', 'addcommand', 'airportinfo', 'airwaysRoute', 'assert', 'carttogeod', 'cmdarg', 'courseAndDistance', 'createViaTo', 'createDiscontinuity', 'createWP', 'createWPFrom', 'defined', 'directory', 'fgcommand', 'findAirportsByICAO', 'findAirportsWithinRange', 'findFixesByID', 'findNavaidByFrequency', 'findNavaidsByFrequency', 'findNavaidsByID', 'findNavaidsWithinRange', 'finddata', 'flightplan', 'geodinfo', 'geodtocart', 'getprop', 'greatCircleMove', 'interpolate', 'isa', 'logprint', 'magvar', 'maketimer', 'md5', 'navinfo', 'parse_markdown', 'parsexml', 'print', 'printf', 'printlog', 'rand', 'registerFlightPlanDelegate', 'removecommand', 'removelistener', 'resolvepath', 'setlistener', 'setprop', 'settimer', 'srand', 'systime', 'thisfunc', 'tileIndex', 'tilePath', 'values'), suffix=r'\b'), Name.Builtin),&lt;br /&gt;
			(words(('append', 'bind', 'call', 'caller', 'chr', 'closure', 'cmp', 'compile', 'contains', 'delete', 'die', 'find', 'ghosttype', 'id', 'int', 'keys', 'left', 'num', 'pop', 'right', 'setsize', 'size', 'sort', 'split', 'sprintf', 'streq', 'substr', 'subvec', 'typeof'), suffix=r'\b'), Name.Builtin),&lt;br /&gt;
			(words(('_createCondition', '_fgcommand', '_interpolate', '_setlistener'), suffix=r'\b'), Keyword.Reserved),&lt;br /&gt;
			(r'`', String.Backtick, 'backtick'),&lt;br /&gt;
			(r&amp;quot;'&amp;quot;, String.Single, 'sqstring'),&lt;br /&gt;
			(r'&amp;quot;', String.Double 'dqstring'),&lt;br /&gt;
			(r'\b_\w*?\b', Keyword.Reserved),&lt;br /&gt;
			#(r'\b\w*?\b', Name),&lt;br /&gt;
		]&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
class XMLNasalLexer(XmlLexer):&lt;br /&gt;
	&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
	For Nasal code embedded in XML files.&lt;br /&gt;
	&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	name = 'XML-Nasal'&lt;br /&gt;
	aliases = ['xml-nasal', 'xml-ns']&lt;br /&gt;
&lt;br /&gt;
	tokens = {&lt;br /&gt;
		'root': [&lt;br /&gt;
			(r'(&amp;lt;(?:load|unload|script)&amp;gt;)(&amp;lt;!\[CDATA\[)?(.*?)(]]&amp;gt;)?(&amp;lt;/(?:load|unload|script)&amp;gt;)', bygroups(Name.Tag, Comment.Preproc, using(NasalLexer), Comment.Preproc, Name.Tag),&lt;br /&gt;
			inherit,&lt;br /&gt;
		],&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:: We can use the ECMAScript/JavaScript lexer[http://pygments.org/docs/lexers/#lexers-for-javascript-and-related-languages] for now, my suggestion would be to copy that over to a file so that we can work on a custom Nasal lexer (Syntax  is almost identical, with a few different keywords, and many others being irrelevant). What is missing/different can be obtained from other lexers that are similar, e.g. [http://pygments.org/docs/lexers/#lexers-for-other-c-like-languages] [[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 15:45, 19 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: Okay, here's the better/quick&amp;amp;easy way: We have Nasal support for some fairly popular editors, like [http://wiki.flightgear.org/Howto:Syntax_highlighting_for_Nasal#Vim|vim](originally created by Melchior&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/flightgear/ci/next/tree/scripts/syntax/nasal.vim&amp;lt;/ref&amp;gt;), listed at [[Howto:Syntax_highlighting_for_Nasal]] - there are various free converters available that will read such a syntaxhighlighting file and convert it to a pygments class, e.g. see: https://github.com/honza/vim2pygments [[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 16:00, 19 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
==== References ====&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== The repository link templates ==&lt;br /&gt;
=== Complete overhaul of the repository link templates ===&lt;br /&gt;
&lt;br /&gt;
I have now performed a complete overhaul of the repository link templates (see {{tl|repo link/doc related}}).  This was motivated by the incomplete state of these templates, the lack of standardisation, the lack of SourceForge git repository support for {{tl|repo link}}, web-interface only support, etc.  I have used a lot of recursive transclusion for standardisation, so that there is a single point for updating for any FlightGear infrastructure changes.  This is the master {{tl|repo link}} template.  All the other templates are subtemplates which recursively transclude from this master template.  I have also created a number of documentation templates for simplifying template maintenance (see {{tl|repo link/doc related‎}}, {{tl|repo link/doc specific file git‎‎}}, {{tl|repo link/doc git clone‎‎}}, and {{tl|repo link/doc commit}}).  The changes were constrained to maintain backwards compatibility as much as possible.  However I would like to break this to allow the following templates to be updated to transclude from the master {{tl|repo link}} template:&lt;br /&gt;
&lt;br /&gt;
* {{tl|flightgear file}},&lt;br /&gt;
* {{tl|simgear file}},&lt;br /&gt;
* {{tl|fgdata file}},&lt;br /&gt;
* {{tl|fgaddon file}}.&lt;br /&gt;
&lt;br /&gt;
If no one objects, I would like to completely break these and expand and rename the parameter set to match the other &amp;lt;nowiki&amp;gt;{{* file}}&amp;lt;/nowiki&amp;gt; repository templates (e.g. {{tl|terragear file}}).  My overhaul currently does not include Hooray's ideas for non command line usages, i.e. different GUIs, but it enables it to be easily added via the master template and the addition of a single parameter to any subtemplates.&lt;br /&gt;
&lt;br /&gt;
[[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 15:05, 25 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
: I don't have any objections myself, I appreciate all the work you are putting into this, and would like to thank you for helping us clean up all that mess by doing such unglamorous work ;-) I also appreciate that your changes would facilitate adding a non-CLI mode to the corresponding templates. However, I would suggest to wait for Gijs' feedback, because he's ultimately the most likely person to veto something around here ;-) [[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 17:31, 25 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: Johan seems to be the one who did a lot of the initial work on these &amp;lt;nowiki&amp;gt;{{* file}}&amp;lt;/nowiki&amp;gt; templates, and Red Leader with the {{tl|repo link}} template.  And they were involved in the general discussions ([[http://wiki.flightgear.org/index.php?title=FlightGear_wiki:Village_pump&amp;amp;oldid=87148#Repository_link_templates perm]).  But I know Gijs was also involved in the design.&lt;br /&gt;
&lt;br /&gt;
:: For the non-CLI mode, that will need -a lot- more planning.  For example a definitive list of all these modes would be useful.  Should this use an optional Mediawiki pop up extension showing a link to a general page that describes the action for all different GUIs, CLI, etc.?  Should we have a switch box so that the reader can switch in-text between CLI, and the numerous GUIs?  Are we going to have a large set of screenshots for each GUI?  If so, I would strongly recommend the [https://www.mediawiki.org/wiki/Extension:Labeled_Section_Transclusion labelled section transclusion extension] for creating a single page for one GUI with everything for that GUI, as a tutorial.  Here is [http://wiki.nmr-relax.com/Relax_4.0.1 an external example where I have used this], to fragment the base release page to create [http://wiki.nmr-relax.com/Relax_release_descriptions this meta page], as well as many other meta pages.&lt;br /&gt;
&lt;br /&gt;
:: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 03:14, 26 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
I am also thinking of changing the name of the &amp;lt;nowiki&amp;gt;{{* file}}&amp;lt;/nowiki&amp;gt; templates, as I hope to make the scope of the templates far more general.  The name &amp;lt;nowiki&amp;gt;{{* source}}&amp;lt;/nowiki&amp;gt; or &amp;lt;nowiki&amp;gt;{{* repo}}&amp;lt;/nowiki&amp;gt; might be better.  For example these will allow the repository commit, tree view, log view (and maybe rss feed), with or without a file/directory path.  And I would like to generalise this to handle both the SF web-interface and non-web net protocols (git://, ssh://, svn://, etc.).  It will allow for CLI instructions to be built up and embedded in &amp;lt;nowiki&amp;gt;{{#tag:source|&amp;lt;content&amp;gt;|lang=sh}}&amp;lt;/nowiki&amp;gt; tags.  And I will defer all infrastructure decisions in the subtemplates to the single point of {{tl|project infrastructure}}, so that if there are changes in the future, then only this single template needs to be updated to update the entire wiki.&lt;br /&gt;
&lt;br /&gt;
[[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 03:22, 26 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
: The {{tl|project infrastructure}} template as a single point provider of various project infrastructure names and URL pairs seem like a great idea.  If it work out well it will really lessen the maintenance by having less places needing updates, while allowing the various repository templates to be simple to use, in essence by having comprehensible names and no boiler plate parameters for their users.&lt;br /&gt;
: —[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 15:15, 27 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
==== Repository link update ====&lt;br /&gt;
For those following, I have massively expanded the capabilities of the {{tl|repo link}} template:&lt;br /&gt;
* The SourceForge URLs are now comprehensive.&lt;br /&gt;
* Full support for the new query-based URLs for the Gitorious archives.&lt;br /&gt;
* Functional GitLab URLs.&lt;br /&gt;
* Generic repository support (used to create the {{tl|openscenegraph co}} template).&lt;br /&gt;
* Detailed documentation and extensive examples for checking the implementation (if you find any non-supported links, please add these as examples).&lt;br /&gt;
* Isolation of the '''cmd''' parameter from the CLI options &amp;amp;mdash; this is to enable future support for non-CLI instructions based on the value of '''cmd'''.&lt;br /&gt;
&lt;br /&gt;
I have also completed a large set of subtemplates of {{tl|repo link}}, see the list at {{tl|repo link/doc related}}.  This includes a full set of &amp;lt;nowiki&amp;gt;{{* source}}&amp;lt;/nowiki&amp;gt; templates.  I have left the original &amp;lt;nowiki&amp;gt;{{* file}}&amp;lt;/nowiki&amp;gt; templates, rather than renaming and modifying them, so these are now redundant.  All of the &amp;lt;nowiki&amp;gt;{{* source}}&amp;lt;/nowiki&amp;gt;, &amp;lt;nowiki&amp;gt;{{* commit}}&amp;lt;/nowiki&amp;gt;, &amp;lt;nowiki&amp;gt;{{* clone}}&amp;lt;/nowiki&amp;gt;, and &amp;lt;nowiki&amp;gt;{{* co}}&amp;lt;/nowiki&amp;gt; templates transclude from the master {{tl|repo link}} template to do all of the work.&lt;br /&gt;
&lt;br /&gt;
One important template is {{tl|gitorious source}}.  The support for the new query-based URLs for the Gitorious archives is now quite comprehensive in {{tl|repo link}}.  Therefore I have converted almost every single FlightGear wiki link to https://gitorious.org to use {{tl|gitorious source}} instead.  This fixes a lot of broken links and broken git instructions.  I have reduced the number of hits for gitorious.org on the wiki (searching just for &amp;quot;gitorious&amp;quot;) to 22 hits.  This includes 2 very outdated articles ([[FlightGear Git: aircraft authors]], [[Fr/FlightGear et Git]]), 15 locked newsletters, 1 with no longer existent Gitorious merge request links, and 4 base URL links for Hangars.  This way we can maintain the Gitorious web interface links and git command instructions in a functional state by simply updating the single source of {{tl|repo link}}.&lt;br /&gt;
&lt;br /&gt;
[[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 11:38, 29 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
: I just remembered [[Special:LinkSearch]], so make that 184 broken gitorious.org links remaining.  Lots more work to do :)&lt;br /&gt;
&lt;br /&gt;
: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 14:46, 29 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
For some of these templates, e.g. {{tl|repo link/doc usage}}, I'm trying to implement some logic for automatic whitespace padding for documentation formatting, but the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;{{#len:string}}&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; function is not enabled.  According to {{mediawiki|Wikitext_parser/Core_parser_functions#.23len}} and {{mediawiki|Extension:StringFunctions}}, the option &amp;lt;code&amp;gt;$wgPFEnableStringFunctions = true;&amp;lt;/code&amp;gt; should be set (in &amp;lt;code&amp;gt;LocalSettings.php&amp;lt;/code&amp;gt;).  Unless there is a reason for not using this, I was wondering if someone could enable this?  Cheers!&lt;br /&gt;
&lt;br /&gt;
[[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 09:53, 8 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
=== Archived newsletters and dead links? ===&lt;br /&gt;
&lt;br /&gt;
Do we have a policy for the dead links in the FlightGear newsletters?  It is obviously good to preserve the historic state.  But there are many Gitorious links that could be made functional again using the {{tl|gitorious source}} template to point to the historic Gitorious archives (including the official FlightGear repositories, rather than using {{tl|fgdata source}}, for example).  The https://gitorious.org links have been converted from URL/path based to query based, so absolutely all of the old links are broken.  I am steadily converting all Gitorious links to use the [[Template:repo link/doc related|{{obr}}repo link{{cbr}} family of templates]], with the exception of the newsletters.&lt;br /&gt;
&lt;br /&gt;
[[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 04:52, 8 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
: I think it could be a good idea to try update old links in those newsletters.  I sometimes look back at things and tend to think that I probably are not the only one doing that.&lt;br /&gt;
: I wonder if the rotten links should be replaced or stricken, but I think they could just as well be replaced.  The key thing is that they go to the same resource or content, not weather they have been updated or not (also, the change will be visible in the revision history after all).&lt;br /&gt;
: —[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 07:11, 8 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: I should add that I'm using [http://wiki.flightgear.org/index.php?title=Special:LinkSearch&amp;amp;limit=500&amp;amp;offset=0&amp;amp;target=http%3A%2F%2Fgitorious.org &amp;lt;nowiki&amp;gt;Special:LinkSearch for http://gitorious.org&amp;lt;/nowiki&amp;gt;] and [http://wiki.flightgear.org/index.php?title=Special:LinkSearch&amp;amp;limit=500&amp;amp;offset=0&amp;amp;target=https%3A%2F%2Fgitorious.org &amp;lt;nowiki&amp;gt;Special:LinkSearch for https://gitorious.org&amp;lt;/nowiki&amp;gt;].  And I am also not touching the &amp;lt;code&amp;gt;User*&amp;lt;/code&amp;gt; pages, &amp;lt;code&amp;gt;*talk*&amp;lt;/code&amp;gt; pages, or pages tagged as out of date or up for deletion.  For the newsletters I might look at these later when the broken Gitorious links are fixed in the rest of the wiki but, as these are locked, someone else might have make the switch to {{tl|gitorious source}}, {{tl|gitorious url}}, {{tl|gitorious clone}}, and {{tl|gitorious merge request}}.&lt;br /&gt;
&lt;br /&gt;
:: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 02:53, 9 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
::: I will temporarily add a table here for the templates in the newsletters and will slowly fix them one by one together with any other admin.&lt;br /&gt;
{{navbox&lt;br /&gt;
| title = Click &amp;quot;show&amp;quot; to show --&amp;gt;&lt;br /&gt;
| state = collapsed&lt;br /&gt;
| navbar = plain&lt;br /&gt;
| list1 =&lt;br /&gt;
http:...&lt;br /&gt;
{{{!}} class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Fixed !! Newsletter !! Gitorious URL !! Notes&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter May 2010]]&lt;br /&gt;
{{!}} http://gitorious.org/fg&lt;br /&gt;
{{!}} No equivalent link for the Gitorious archive - project pages are dead.  Maybe just use http://gitorious.org/?&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter May 2010]]&lt;br /&gt;
{{!}} http://gitorious.org/fg&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter September 2010]]&lt;br /&gt;
{{!}} http://gitorious.org/fg/flightgear/commit/5c6fe952598053fa63631fc0161d666f22a50f51&lt;br /&gt;
{{!}} Functional link, equivalent to {{gitorious url|fg|flightgear|commit=5c6fe952598053fa63631fc0161d666f22a50f51}}.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter September 2010]]&lt;br /&gt;
{{!}} http://gitorious.org/fg/flightgear/commit/5c6fe952598053fa63631fc0161d666f22a50f51&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter January 2011]]&lt;br /&gt;
{{!}} http://gitorious.org/jsbsim/jsbsim&lt;br /&gt;
{{!}} Functional link.  Switched to {{gitorious url|jsbsim|jsbsim}} to future-protect the link.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter January 2011]]&lt;br /&gt;
{{!}} http://gitorious.org/jsbsim/jsbsim&lt;br /&gt;
{{!}} Functional link.  Switched to {{gitorious url|jsbsim|jsbsim}} to future-protect the link.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter February 2011]]&lt;br /&gt;
{{!}} http://gitorious.org/headtrack&lt;br /&gt;
&lt;br /&gt;
http://gitorious.org/arduinocockpit&lt;br /&gt;
{{!}} Project pages are dead, switched to {{gitorious url|headtrack|headtrack}}&lt;br /&gt;
&lt;br /&gt;
{{gitorious url|arduinocockpit|arduinocockpit}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter February 2011]]&lt;br /&gt;
{{!}} http://gitorious.org/arduinocockpi&lt;br /&gt;
&lt;br /&gt;
http://gitorious.org/headtrack&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter March 2011]]&lt;br /&gt;
{{!}} http://gitorious.org/lockheed-l10-electra&lt;br /&gt;
{{!}} Missing project - i.e. {{gitlab source|user=emilianh|repo=Lockheed-L10-Electra|text=migrated to GitLab}}.  Switched to {{gitlab source|user=emilianh|repo=Lockheed-L10-Electra}}.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter March 2011]]&lt;br /&gt;
{{!}} http://gitorious.org/lockheed-l10-electra&lt;br /&gt;
{{!}} Switched to {{gitlab source|user=emilianh|repo=Lockheed-L10-Electra}}.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter November 2011]]&lt;br /&gt;
{{!}} http://gitorious.org/flightgear-aircraft&lt;br /&gt;
{{!}} Switched to {{gitorious source}} and rephrased text slightly to help readers find the repositories.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter October 2012]]&lt;br /&gt;
{{!}} http://gitorious.org/anders-hangar/mtb_20m/trees/master&lt;br /&gt;
{{!}} Switch to {{gitorious url|proj=anders-hangar|repo=mtb_20m}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter March 2013]]&lt;br /&gt;
{{!}} http://gitorious.org/fg/flightgear/blobs/next/scripts/java/FGClient/src/FGFSDemo.java&lt;br /&gt;
{{!}} Switched to {{gitorious url|proj=fg|repo=flightgear|path=scripts/java/FGClient/src/FGFSDemo.java}}.  This points to the old Gitorious repository to protect against path changes in the future.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter September 2013]]&lt;br /&gt;
{{!}} http://gitorious.org/boeing/707&lt;br /&gt;
{{!}} Switched to {{gitorious source|proj=boeing|repo=707}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter September 2013]]&lt;br /&gt;
{{!}} http://gitorious.org/boeing/707&lt;br /&gt;
{{!}} Switched to {{gitorious source|proj=boeing|repo=707}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter November 2013]]&lt;br /&gt;
{{!}} http://gitorious.org/fg/fgrun&lt;br /&gt;
{{!}} Switch to {{gitorious url|proj=fg|repo=fgrun}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter November 2013]]&lt;br /&gt;
{{!}} http://gitorious.org/fg/fgrun&lt;br /&gt;
{{!}} Switch to {{gitorious url|proj=fg|repo=fgrun}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter July 2014]]&lt;br /&gt;
{{!}} http://gitorious.org/nasal-support/nasal-npp&lt;br /&gt;
{{!}} Switched to {{gitorious url|nasal-support|nasal-npp}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter April 2015]]&lt;br /&gt;
{{!}} http://gitorious.org&lt;br /&gt;
{{!}} Switched to {{tl|gitorious source}} without parameters for the Gitorious base URL, to future-protect it.&lt;br /&gt;
{{!}}}&lt;br /&gt;
&lt;br /&gt;
https:...&lt;br /&gt;
{{{!}} class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Fixed !! Newsletter !! Gitorious URL !! Notes&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter April 2011]]&lt;br /&gt;
{{!}} https://gitorious.org/papillon81/flightgear-custom-scenery/&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/dvanmosselbeen/flightgear-custom-scenery&lt;br /&gt;
{{!}} Switched to {{gitorious source|dvanmosselbeen|flightgear-custom-scenery}} and {{gitorious source|papillon81|flightgear-custom-scenery}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter April 2011]]&lt;br /&gt;
{{!}} https://gitorious.org/dvanmosselbeen/flightgear-custom-scenery&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/papillon81/flightgear-custom-scenery/&lt;br /&gt;
{{!}} Switched to {{gitorious source|dvanmosselbeen|flightgear-custom-scenery}} and {{gitorious source|papillon81|flightgear-custom-scenery}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter July 2011]]&lt;br /&gt;
{{!}} https://gitorious.org/dvanmosselbeen/flightgear-custom-scenery&lt;br /&gt;
{{!}} Switched to {{gitorious source|dvanmosselbeen|flightgear-custom-scenery}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter July 2011]]&lt;br /&gt;
{{!}} https://gitorious.org/dvanmosselbeen/flightgear-custom-scenery&lt;br /&gt;
{{!}} Switched to {{gitorious source|dvanmosselbeen|flightgear-custom-scenery}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter December 2011]]&lt;br /&gt;
{{!}} https://gitorious.org/dvanmosselbeen/flightgear-custom-scenery&lt;br /&gt;
{{!}} Switched to {{gitorious source|dvanmosselbeen|flightgear-custom-scenery}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Fr/Nouvelles du projet FlightGear - décembre 2011]]&lt;br /&gt;
{{!}} https://gitorious.org/dvanmosselbeen/flightgear-custom-scenery&lt;br /&gt;
{{!}} Switched to {{gitorious source|dvanmosselbeen|flightgear-custom-scenery}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter April 2012]]&lt;br /&gt;
{{!}} https://gitorious.org/fg/fgdata/blobs/master/Aircraft/Instruments-3d/garmin196/README&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/fgdata/blobs/master/Aircraft/Instruments-3d/garmin196/doc/doc-en.htm&lt;br /&gt;
{{!}} Switched to {{fgdata source|path=Aircraft/Instruments-3d/garmin196/README|full=1}} and {{fgdata source|path=Aircraft/Instruments-3d/garmin196/doc/doc-en.htm|full=1}} to point to the current FGData locations and removed the name &amp;quot;Gitorious&amp;quot; to make the text of the Garmin 196 GPS section still relevant&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter August 2012]]&lt;br /&gt;
{{!}} https://gitorious.org/mil-mi-6&lt;br /&gt;
{{!}} Switched to {{gitorious url|proj=mil-mi-6|repo=mi6dev}}, and changed from the non-existent project page to the main repository.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter October 2012]]&lt;br /&gt;
{{!}} https://gitorious.org/fgradar&lt;br /&gt;
{{!}} Switched from the project page to the direct repository {{gitorious url|fgradar|fgradar}}.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter March 2013]]&lt;br /&gt;
{{!}} https://gitorious.org/fg/flightgear/commit/913727239d6776c0508d206f395e16c265413ec3&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/flightgear/commit/eba03b5e469824ee8f1494723fcddbbc56155a08&lt;br /&gt;
{{!}} Switched to {{flightgear url|commit=913727239d6776c0508d206f395e16c265413ec3}} and {{flightgear url|commit=eba03b5e469824ee8f1494723fcddbbc56155a08}}.  This deliberately points to the current repository.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter April 2013]]&lt;br /&gt;
{{!}} https://gitorious.org/fg-radi/osm2city&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/scenery-france-850&lt;br /&gt;
{{!}} Switched to the new GitLab repository {{gitlab source|proj=fg-radi|repo=osm2city|full=1}}&lt;br /&gt;
&lt;br /&gt;
and removed the no longer existent scenery-france-850 repository, replacing it with &amp;quot;&amp;lt;s&amp;gt;Scenery repository (Gitorious)&amp;lt;/s&amp;gt;&amp;quot;.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter October 2013]]&lt;br /&gt;
{{!}} https://gitorious.org/fg/galvedros-fgdata&lt;br /&gt;
{{!}} Switch to {{gitorious url|proj=fg|repo=galvedros-fgdata}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter October 2013]]&lt;br /&gt;
{{!}} https://gitorious.org/fg/galvedros-fgdata&lt;br /&gt;
{{!}} Switch to {{gitorious url|proj=fg|repo=galvedros-fgdata}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter November 2013]]&lt;br /&gt;
{{!}} https://gitorious.org/ec130/&lt;br /&gt;
{{!}} Switched from the project page to the direct repository {{gitorious source|ec130|ec130}}.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter November 2013]]&lt;br /&gt;
{{!}} https://gitorious.org/ec130/&lt;br /&gt;
{{!}} Switched from the project page to the direct repository {{gitorious source|ec130|ec130}}.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter February 2014]]&lt;br /&gt;
{{!}} https://gitorious.org/fg/philosophers-fgdata/source/022bef27f05d4837d720f63c6507b47466ff2a59:Nasal/console/repl.nas#L436&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/philosophers-fgdata/source/nasal-console:Nasal/console&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/fgdata/commit/eaaf816b772649d5b0826a1d0bdd166dbc5b968f&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/flightgear/commit/34ed79e5f88ffdfc5e651a1fe3e639cb8f4d3353&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/flightgear/commit/5eee5e42ae4f5cf56283b3bf5a3be46efc2b51c4&lt;br /&gt;
&lt;br /&gt;
https://www.gitorious.org/fg/flightgear/merge_requests/26&lt;br /&gt;
{{!}} Switched to {{gitorious source|proj=fg|repo=philosophers-fgdata|branch=nasal-console|path=Nasal/console/repl.nas|line=708}}&lt;br /&gt;
&lt;br /&gt;
{{gitorious url|proj=fg|repo=philosophers-fgdata|branch=nasal-console|path=Nasal/console|view=tree}}&lt;br /&gt;
&lt;br /&gt;
{{fgdata-old url|commit=eaaf816b772649d5b0826a1d0bdd166dbc5b968f}}&lt;br /&gt;
&lt;br /&gt;
{{flightgear commit|34ed79e5f88ffdfc5e651a1fe3e639cb8f4d3353}}&lt;br /&gt;
&lt;br /&gt;
{{gitorious merge request|mr=54}}&lt;br /&gt;
&lt;br /&gt;
{{gitorious merge request|mr=26}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter February 2014]]&lt;br /&gt;
{{!}} https://gitorious.org/fg/philosophers-fgdata/source/022bef27f05d4837d720f63c6507b47466ff2a59:Nasal/console/repl.nas#L436&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/philosophers-fgdata/source/nasal-console:Nasal/console&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/fgdata/commit/eaaf816b772649d5b0826a1d0bdd166dbc5b968f&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/flightgear/commit/34ed79e5f88ffdfc5e651a1fe3e639cb8f4d3353&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/flightgear/commit/5eee5e42ae4f5cf56283b3bf5a3be46efc2b51c4&lt;br /&gt;
&lt;br /&gt;
https://www.gitorious.org/fg/flightgear/merge_requests/26&lt;br /&gt;
{{!}} Changes match the English article.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter April 2014]]&lt;br /&gt;
{{!}} https://gitorious.org/fg/fgdata/flightgear?p=fg/fgdata:flightgear.git;a=blob;f=keyboard.xml&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/fgdata?p=fg:fgdata.git;a=commit;h=f8c56dcc52ffd3d6dfca1d39dc4a72b6b3478368&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/hoorays-flightgear?p=fg:hoorays-flightgear.git;a=shortlog;h=refs/heads/topics/cppbind-fgprotocol&lt;br /&gt;
{{!}} This first link was the broken {{tl|git link}} template (see the table below).  The other two links are not in the article?!&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter June 2014]]&lt;br /&gt;
{{!}} https://gitorious.org/eddp-custom-scenery/eddp-custom-scenery/&lt;br /&gt;
{{!}} Switched to {{tl|gitorious clone}} to provide functional '''git clone''' instructions.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter November 2014]]&lt;br /&gt;
{{!}} https://gitorious.org/fg/hoorays-fgdata/source/2857d8fc9fcfe2bb162a9eb9d3dcca4d41b3a876:Nasal/ai/aim9/aim9.fdm#L9&lt;br /&gt;
{{!}} Switch to {{gitorious url|proj=fg|repo=hoorays-fgdata|commit=2857d8fc9fcfe2bb162a9eb9d3dcca4d41b3a876|path=Nasal/ai/aim9/aim9.fdm|line=9}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter January 2015]]&lt;br /&gt;
{{!}} https://gitorious.org/fg/canvas-hackers-fgdata/source/f59c42134a5a77e343981dcff8278c3e2f094e87&lt;br /&gt;
{{!}} Switch to {{gitorious url|proj=fg|repo=canvas-hackers-fgdata|commit=f59c42134a5a77e343981dcff8278c3e2f094e87|view=summary}}&lt;br /&gt;
{{!}}}&lt;br /&gt;
&lt;br /&gt;
Broken templates:...&lt;br /&gt;
{{{!}} class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Fixed !! Newsletter !! Template !! Notes&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter April 2014]]&lt;br /&gt;
{{!}} {{tlx|Git link|gitorious|fg/fgdata|master|keyboard.xml|pre=$FG_ROOT/}}&lt;br /&gt;
{{!}} Switched to {{fgdata source|path=keyboard.xml|pre=$FG_ROOT}} to fix the Gitorious link created by the broken and depreciated {{tl|git link}} template.&lt;br /&gt;
{{!}}}&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
::: —[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 12:06, 9 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:::: I've added a '''notes''' column to help a little.&lt;br /&gt;
&lt;br /&gt;
:::: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 12:30, 9 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
=== Elimination of the dead Gitorious links ===&lt;br /&gt;
Thanks largely to the diversity and flexibility of the [[:Category:Repository link templates|{{obr}}repo link{{cbr}} family of templates]], I have now managed to eliminate almost every last dead Gitorious link in the FlightGear wiki!  The locked Newsletter articles, user pages, and talk pages are the only exceptions.  The page counts from the (Main) namespace are:&lt;br /&gt;
* [http://wiki.flightgear.org/index.php?target=http%3A%2F%2Fgitorious.org&amp;amp;namespace=0&amp;amp;title=Special%3ALinkSearch &amp;lt;nowiki&amp;gt;Special:LinkSearch for http://gitorious.org&amp;lt;/nowiki&amp;gt;] &amp;amp;mdash; 37.  Of these, 17 are for the front page with the news of the Gitorious to SourceForge migration, and the rest are Newsletters.&lt;br /&gt;
* [http://wiki.flightgear.org/index.php?title=Special:LinkSearch&amp;amp;limit=500&amp;amp;offset=0&amp;amp;target=https%3A%2F%2Fgitorious.org&amp;amp;namespace=0 &amp;lt;nowiki&amp;gt;Special:LinkSearch for https://gitorious.org&amp;lt;/nowiki&amp;gt;] &amp;amp;mdash; 166.  Most of these links are valid and created by the {{obr}}gitorious *{{cbr}} subtemplates of {{tl|repo link}}.  The remaining broken links are all in the locked Newsletters.&lt;br /&gt;
The Howto:* pages are not in the (Main) wiki namespace, but I've knocked those out too.&lt;br /&gt;
&lt;br /&gt;
[[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 13:54, 10 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
: thanks for doing all this unglamorous work - I am sorry that Gijs was apparently too busy to follow up on my suggestion to either provide you with admin access around here, or at least to help you run a Python script to do all this work in an automated, rather than manual, fashion. Hopefully, things will work out better next time. Again, thank you. Like I said, I think you should definitely be given admin access on the wiki, especially given your recent contributions - and I would gladly have my wiki status downgraded accordingly. In fact, if I was able to directly promote accounts accordingly, I would have done so months ago - however, it seems that Gijs is the only one to have those privileges, and he mentioned off-list that he's kinda busy with RL/exams etc, so it is to be expected that he's going to become a bottleneck more often - hopefully, this will be recongized as an actual issue, so that there will be more people able to promote new wiki admins. Sorry that things didn't work out better this time, and thanks so much for doing all this stuff manually. -[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 14:49, 10 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: No problems!  As for automating this, that would not have been possible.  If you look at the changes, you'll see that each one is different &amp;lt;sup&amp;gt;[http://wiki.flightgear.org/index.php?title=Special:RecentChanges&amp;amp;to=20160310210655&amp;amp;limit=500]&amp;lt;/sup&amp;gt;.  I had to check each one, and update the link as required.&lt;br /&gt;
&lt;br /&gt;
:: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 16:08, 10 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
::: There's three of us actually (Curt, Simon and myself), no need to wait on me. See http://wiki.flightgear.org/index.php?title=Special%3AListUsers&amp;amp;username=&amp;amp;group=bureaucrat&amp;amp;limit=100 (Sek is inactive nowadays) ;-)&lt;br /&gt;
::: Please note that forum pms are really not the best way to contact me. I very much prefer email over forum pms as it's a lot easier to filter out the huge amounts of nonsense I'm receiving from stuff requiring actual attention.&lt;br /&gt;
::: Anyhow I've just  promoted Bugman so he can edit locked articles.&lt;br /&gt;
::: [[User:Gijs|Gijs]] ([[User talk:Gijs|talk]]) 05:06, 11 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:::: Thank you.  I'll try to preserve the original intent of the Newsletters while fixing the broken links (maybe even preserving any original URLs as Mediawiki link text, while pointing to the new URL).  I will use the {{obr}}gitorious *{{cbr}} templates to point to the historical sources, and will probably use this for all of the Gitorious URLs so that we have full control over any future URL breakages via the single location of {{tl|repo link}}.  For example, if they change the gitorious.org domain name to a https://archive.org subdomain (i.e. gitorious.archive.org).&lt;br /&gt;
&lt;br /&gt;
:::: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 06:40, 11 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
=== Regex parsing of template parameters? ===&lt;br /&gt;
&lt;br /&gt;
For the {{tl|repo link}} template, I am currently trying to work out what to do for git branches and tags on the SourceForge infrastructure.  The problem is that the presence of the character &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt; within a branch or tag name requires the text &amp;lt;code&amp;gt;/~&amp;lt;/code&amp;gt; to be appended to that name in the URL, for example:&lt;br /&gt;
&lt;br /&gt;
* Tag &amp;lt;code&amp;gt;version/2016.1.1&amp;lt;/code&amp;gt;:  https://sourceforge.net/p/flightgear/simgear/ci/version/2016.1.1/~/tree/simgear/ephemeris/ephemeris.cxx&lt;br /&gt;
* Branch &amp;lt;code&amp;gt;release/2016.1&amp;lt;/code&amp;gt;:  https://sourceforge.net/p/flightgear/simgear/ci/release/2016.1/~/tree/simgear/ephemeris/ephemeris.cxx&lt;br /&gt;
&lt;br /&gt;
I haven't found out a way to use regex to parse the &amp;lt;code&amp;gt;tag&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;branch&amp;lt;/code&amp;gt; template parameters to automate this, hence I am thinking of just giving the instruction for the template user to append this text to the &amp;lt;code&amp;gt;tag&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;branch&amp;lt;/code&amp;gt; parameter text themselves.  However this is not ideal - a change of this behaviour on the SourceForge side requires end pages with SourceForge URLs to be updated, rather than just updating {{tl|repo link}}.  I was wondering about possibility of installing the extension:&lt;br /&gt;
&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Extension:RegexParserFunctions Extension:RegexParserFunctions]&lt;br /&gt;
&lt;br /&gt;
Though I'm not 100% sure if that will work.  Or does someone else know an alternative?  Cheers!&lt;br /&gt;
&lt;br /&gt;
[[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 12:09, 22 April 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
: not a solution, just a potential workaround would be checking for the most common prefix strings used in tags/branches (e.g. version, release, topic, topics) and explicitly rewrite the URL accordingly to append the /~ suffix -[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 12:59, 22 April 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:: That might be a solution.  But I don't know how to do that without regex ;)  We really only have #ifeq statements, but that has to match the whole string.&lt;br /&gt;
&lt;br /&gt;
:: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 13:44, 22 April 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Discussion about quotes on the wiki ==&lt;br /&gt;
{{usr|Hooray}} have started a page now at [[FlightGear wiki:Quoting Guidelines]] ([http://wiki.flightgear.org/index.php?title=FlightGear_wiki:Quoting_Guidelines&amp;amp;oldid=96104 perm]) for a discussion regarding guidelines for the use of quotes on the wiki.  Join the discussion.&lt;br /&gt;
&lt;br /&gt;
—[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 18:17, 21 March 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In slight relation to this I have tried to make the wiki more consistently use the most common spelling and case, &amp;quot;Instant-Cquotes&amp;quot; and have changed the automatic categorization accordingly.  All articles using the {{tl|FGCquote}} template can now be found in [[:Category:Articles containing Instant-Cquotes]] (currently some ~250 articles).&lt;br /&gt;
&lt;br /&gt;
—[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 08:21, 23 March 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Reorganizing the Git articles ==&lt;br /&gt;
I've noticed that the [[Category:Git|Git articles]] suffer from duplication and are in part obsolete (especially with regard to the instructions for running Git on Windows). Thus, I propose the following reorganization:&lt;br /&gt;
* [[Development workflow]]: reorganization to explain how the patch submission process is organized from a high-level point of view (forking the repository from SourceForge, developing, pushing the commits to the personal fork, submitting a merge request/sending a patch to the mailing list);&lt;br /&gt;
* [[FlightGear Git]]: leave as is;&lt;br /&gt;
* '''Installing and configuring Git''' - new article about installing Git and configuring it (setting the username/e-mail address); merge the contents of [[FlightGear Git on Windows]] and [[Resources WRT running git on Win32]] here;&lt;br /&gt;
* [[FlightGear Git for laymen]] - make it follow [[FGW:MOS]], merge the contents of [[Howto:Start using git]] here;&lt;br /&gt;
* [[FlightGear Git: core developers]] and [[FlightGear Git: data developers]] - I'm uncertain about what I should do with them: the only piece information that would not be written in other articles is the list of alternative methods for cloning FGData;&lt;br /&gt;
* [[FlightGear Git: gitiquette]] and [[FlightGear Git: tips]] - make them follow [[FGW:MOS]].&lt;br /&gt;
Any comments? -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 06:11, 13 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
: This is sorely needed!  For [[FlightGear Git: core developers]] and [[FlightGear Git: data developers]], maybe these can be merged into something like [[FlightGear Git: working with the repositories]]?  The only real difference is the URL, but that is a minor difference with the [[:Category:Repository link templates]].  This could be generalised into a set of instructions for working with all git repositories for the core infrastructure, including forking and merge requests, with a current focus on the SourceForge web and non-web interfaces.&lt;br /&gt;
&lt;br /&gt;
: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 08:17, 13 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:: Yes, I was thinking about a similar solution as well. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 10:16, 13 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
: For the reorganisation of the articles, it would be good to make a lot of use of the {{tl|Project infrastructure}} template.  This will abstract away the SourceForge infrastructure (well some instructions will be 100% SourceForge specific, so it won't be perfect).  I would like to however have [[Template talk:Project infrastructure#Slight variation of the current architecture|Johan's design]] implemented first, as it would be quite beneficial.&lt;br /&gt;
&lt;br /&gt;
: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 18:43, 14 May 2016 (EDT)&lt;br /&gt;
:: Thanks, didn't know it existed. Right now I'm fixing some last-minute bugs before the release, but I'll have a look at this. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 09:05, 15 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== UTF-8 language pages cannot be edited ==&lt;br /&gt;
&lt;br /&gt;
This is a continuation of [[FlightGear wiki:Village pump/Archive 2015#UTF-8 language pages cannot be edited]].  I can see that wiki editors are [[Zh/FlightGear Wiki|forced to create workarounds]], as the [[Main page]] in Chinese [http://wiki.flightgear.org/index.php?title=Zh/%E9%A6%96%E9%A1%B5&amp;amp;action=edit cannot be edited].  I think it is quite important to solve this ''&amp;quot;A database query error has occurred. This may indicate a bug in the software&amp;quot;'' issue.  As the fix is quite dangerous (see {{mediawiki|Topic:S1q54kosfdkhz6w1}}), do we have a backup system?  Do we have regular mysql and ftp dumps that can be backed up locally using rsync?&lt;br /&gt;
&lt;br /&gt;
[[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 05:16, 15 May 2016 (EDT)&lt;/div&gt;</summary>
		<author><name>Elgaton</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Development_workflow&amp;diff=98243</id>
		<title>Development workflow</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Development_workflow&amp;diff=98243"/>
		<updated>2016-05-14T21:45:51Z</updated>

		<summary type="html">&lt;p&gt;Elgaton: Restructuring; work in progress&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WIP}}&lt;br /&gt;
{{Git}}&lt;br /&gt;
This page is meant to be a high-level introduction to the '''development workflow''' of FlightGear, that is, the process developers follow to contribute their work to the project.&lt;br /&gt;
&lt;br /&gt;
== The big picture ==&lt;br /&gt;
Everything is stored in several Git ''repositories'' (collection of files) on SourceForge. You can find a list of them in the [[FlightGear Git]] page.&lt;br /&gt;
&lt;br /&gt;
Only a handful of developers have ''commit access'', that is, the right to make changes to those repositories without prior approval. This is done to ensure that only people showing a good, consistent contribution track record and good judgement are able to perform such modifications unsupervised.&amp;lt;ref&amp;gt;[http://www.flightgear.org/flightgear-policy-document FlightGear Policy Document and Roadmap]&amp;lt;/ref&amp;gt; For this reason, once a developer contributes some work, it will need to be ''staged'' for approval by another contributor having commit access.&lt;br /&gt;
&lt;br /&gt;
== Life of a patch ==&lt;br /&gt;
The contribution process can be divided in the following phases.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- TODO: add links to the relevant Wiki pages --&amp;gt;&lt;br /&gt;
# '''Clone the repositories you would like to contribute to and fetch them.''' In this context, a ''clone'' is a personal copy of the original repository created for temporarily keeping your proposed modifications until they are accepted into the project. You will need to clone the original repository and download the data to your computer.&lt;br /&gt;
# '''Perform the desired modifications''' and publish them to your clone.&lt;br /&gt;
# When you are ready to get your work accepted, '''submit a merge request'''. A developer will check your contribution before merging it into the project repositories. Fix any issues that are found during the review.&lt;br /&gt;
# Once your work is included, '''monitor the [[FlightGear build server|build server]], the [[Mailing lists|mailing lists]] and the forum''' to check for bugs you might have inadvertently introduced.&lt;br /&gt;
&lt;br /&gt;
== Scenery and aircraft contributions ==&lt;br /&gt;
Due (mostly) to their file size, scenery and aircraft are stored using different file management systems and, thus, do not follow the process outlined in this article.&lt;br /&gt;
* Scenery contributions should be submitted to the [[FlightGear Scenery Database]].&lt;br /&gt;
* Aircraft contributors should follow the instructions given in [[FGAddon]].&lt;br /&gt;
&lt;br /&gt;
== Tips ==&lt;br /&gt;
* If you need to take a design decision or want to get some preliminary feedback, ask people on the {{Mailing list e-mail address|flightgear-devel}} mailing list and/or on the forum.&lt;br /&gt;
&lt;br /&gt;
{{Appendix}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Core developer documentation]][[Category:Git]]&lt;/div&gt;</summary>
		<author><name>Elgaton</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=FlightGear_Git&amp;diff=98216</id>
		<title>FlightGear Git</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=FlightGear_Git&amp;diff=98216"/>
		<updated>2016-05-13T23:18:28Z</updated>

		<summary type="html">&lt;p&gt;Elgaton: Small refactoring, added repository table&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Git}}&lt;br /&gt;
'''Git''' is a {{wikipedia|version control system}} used by the [[FlightGear]] project to store all the files required to build and run the simulator. This includes all the programs, the data (e.g. textures, sounds), supporting tools, etc. Git tracks updates to every file as developers from around the world work together concurrently to create new versions. The sole exception is the official [[FGAddon]] aircraft repository that is Subversion rather than Git based.&lt;br /&gt;
&lt;br /&gt;
While new FlightGear features and additions are in development, they are available from Git before they are available in the standard release version. Using Git allows users to use the newest possible version of FlightGear from the latest source files, to experiment with new aircraft or other features. However, it is not a beginner's tool. Using Git can expose the user to unstable features that show ugly error messages, or crash the computer. &lt;br /&gt;
&lt;br /&gt;
As of May 2016, the repositories are located at [https://sourceforge.net/p/flightgear SourceForge].&lt;br /&gt;
&lt;br /&gt;
== Motivation ==&lt;br /&gt;
In May 2010, after a hardware failure on the [[CVS]] servers, the FlightGear project changed its version control system from CVS to Git.&lt;br /&gt;
&lt;br /&gt;
Much has been written on the advantages of Git over CVS. For the FlightGear project, some advantages are:&lt;br /&gt;
* Much better support for branches and merging branches. This is especially important for creating bug fix releases for major releases while still allowing work on the next major release to continue. It is also very nice for a developer's personal workflow.&lt;br /&gt;
* Easier path for contributors to submit changes and developers to integrate them.&lt;br /&gt;
* Much better support for everyday tasks like searching the project history for changes, viewing changes, bisecting the project history to find the original source of a bug.&lt;br /&gt;
&lt;br /&gt;
== Repositories and branches ==&lt;br /&gt;
The FlightGear project is split up in the repositories listed below.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Name&lt;br /&gt;
! Contents&lt;br /&gt;
! Remarks&lt;br /&gt;
|-&lt;br /&gt;
| {{simgear source|text=simgear}}&lt;br /&gt;
| The simulation engine that FlightGear uses.&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |&lt;br /&gt;
Those repositories have the following branches:&lt;br /&gt;
* ''next'': current tip of new development. This branch should always compile and run, but various things could be broken.&lt;br /&gt;
* ''release/*'': containing former and (if a specific branch was made for them) upcoming releases.&lt;br /&gt;
|-&lt;br /&gt;
| {{flightgear source|text=flightgear}}&lt;br /&gt;
| FlightGear itself.&lt;br /&gt;
|-&lt;br /&gt;
| {{fgdata source|text=fgdata}}&lt;br /&gt;
| All data (default aircraft, dialogs, sounds) used by FlightGear.&lt;br /&gt;
|-&lt;br /&gt;
| {{fgaddon source|text=fgaddon}}&lt;br /&gt;
| SVN repository that holds all official aircraft (except the [[Cessna 172P]] default plane and the [[UFO]]).&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| {{fgrun source|text=fgrun}}&lt;br /&gt;
| The [[FGRun]] launcher for FlightGear.&lt;br /&gt;
| As of May 2016, in the process of being replaced by the [[Qt5 Launcher|Qt5 launcher]].&lt;br /&gt;
|-&lt;br /&gt;
| Windows-3rd-party&lt;br /&gt;
| Prebuilt libraries needed to make FlightGear run on Windows.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| {{fgmeta source|text=fgmeta}}&lt;br /&gt;
| FlightGear &amp;quot;meta&amp;quot; repository containing build and setup scripts for the whole project.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| fgcom&lt;br /&gt;
| [[FGCom 3.0|FGCom]], a voice-over-IP application used by [[multiplayer]] controllers to provide [[Air traffic control|ATC services]].&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| {{getstart source|text=getstart}}&lt;br /&gt;
| Sources for the ''Getting Started'' manual included with the simulator.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| {{openradar source|text=openradar}}&lt;br /&gt;
| The [[OpenRadar]] application used by multiplayer controllers.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| {{sceneryweb source|text=sceneryweb}}&lt;br /&gt;
| Source code and configuration files for the [http://mapserver.flightgear.org/ Mapserver], the [https://scenery.flightgear.org/ scenery portal] and the [[TerraGear scenery build server]].&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| {{terragear source|text=terragear}}&lt;br /&gt;
| The [[TerraGear]] scenery building toolkit.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| terrafs&lt;br /&gt;
| A Linux tool to mount the TerraSync scenery as a remote file system.&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| MacLauncher&lt;br /&gt;
| Old FlightGear launcher for Mac.&lt;br /&gt;
| Deprecated by the [[Qt5 Launcher|Qt5 launcher]].&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Related content ==&lt;br /&gt;
* [[FlightGear Git: splitting FGData]], an initiative to split the aircraft out of the FGData repository, in order to decrease its size and thus improve access to the average user/developer.&lt;br /&gt;
&lt;br /&gt;
{{Building}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Core developer documentation]]&lt;br /&gt;
[[Category:FlightGear]]&lt;br /&gt;
[[Category:Git]]&lt;br /&gt;
&lt;br /&gt;
[[fr:FlightGear et Git]]&lt;/div&gt;</summary>
		<author><name>Elgaton</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Development_workflow&amp;diff=98215</id>
		<title>Development workflow</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Development_workflow&amp;diff=98215"/>
		<updated>2016-05-13T23:15:02Z</updated>

		<summary type="html">&lt;p&gt;Elgaton: Temporary first version&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WIP}}&lt;br /&gt;
{{Git}}&lt;br /&gt;
This page is meant to be a high-level introduction to the '''development workflow''' of FlightGear, that is, the process developers follow to contribute their work to the project.&lt;br /&gt;
&lt;br /&gt;
== The big picture ==&lt;br /&gt;
&lt;br /&gt;
- Code, mailing lists, bug tracker hosted at SourceForge&lt;br /&gt;
- Commit access: repos not public (see policy)&lt;br /&gt;
&lt;br /&gt;
== Life of a patch ==&lt;br /&gt;
- get the repo + fork&lt;br /&gt;
- edit (on main for aircraft, on branch for&lt;br /&gt;
- get feedback for important edits&lt;br /&gt;
- submit a patch (or direct commit if commit access)&lt;br /&gt;
- patch applied&lt;br /&gt;
- check build server and monitor forum+ML&lt;br /&gt;
&lt;br /&gt;
== Tips ==&lt;br /&gt;
Ask on ML&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
=The Big Picture=&lt;br /&gt;
&lt;br /&gt;
The [[FlightGear]] sources are hosted at SourceForge: https://sourceforge.net/p/flightgear/flightgear/ci/next/tree/&lt;br /&gt;
&lt;br /&gt;
As a safety precaution, the commit access to those repositories is not public and hence development work has to be somewhat ''staged''.&lt;br /&gt;
&lt;br /&gt;
Once this staging is done, there are two major possible ways for the done work to find its way back into the official sources:&lt;br /&gt;
&lt;br /&gt;
# A person with commit access ''OK's'' the work and commits it, using her or his account.&lt;br /&gt;
# A [[GIT Merge Request|merge request]] has been filed and somebody with the proper access performs the merge.&lt;br /&gt;
&lt;br /&gt;
Fortunately the ''staging'' necessary for both approaches is essentially the same&lt;br /&gt;
&lt;br /&gt;
=Using a Personal Gitorious Repository=&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' This is essentially my tale. AndersG guided me through the process and I wanted to record/report it somewhere. [[User:Hcc23|Hcc23]] 13:59, 19 May 2011 (EDT)&lt;br /&gt;
&lt;br /&gt;
# Create (or login to) a Gitorious account at &amp;lt;nowiki&amp;gt;https://www.gitorious.org/login&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
## If you have a Google account (e.g. Gmail), you can use that to login:&lt;br /&gt;
## Click ''Or log in with OpenID''&lt;br /&gt;
## Enter &amp;lt;tt&amp;gt;https://profiles.google.com/yourGoogleLoginName&amp;lt;/tt&amp;gt;, replacing &amp;lt;tt&amp;gt;yourGoogleLoginName&amp;lt;/tt&amp;gt; with your Google login (i.e. whatever you have in front of @googlemail.com or @gmail.com).&lt;br /&gt;
&lt;br /&gt;
[[File:Gitorious_cloning_button.png|thumb|400px|The '''Clone repository''' button on &amp;lt;nowiki&amp;gt;https://gitorious.org/fg&amp;lt;/nowiki&amp;gt; copies (clones) a Gitorious repository into ones private Gitorious account.]]&lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Elgaton</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Howto:Animated_jetways_(Type_1)&amp;diff=98200</id>
		<title>Howto:Animated jetways (Type 1)</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Howto:Animated_jetways_(Type_1)&amp;diff=98200"/>
		<updated>2016-05-13T18:32:04Z</updated>

		<summary type="html">&lt;p&gt;Elgaton: Dequoting and restyling per FGW:MOS&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Animated jetways''' are dynamic {{Wikipedia|jetway}} models that connect to your aircraft when you are pulled up at a gate. [[FlightGear]] boasts the most advanced animated jetways in the flight simulator market, beating those of Microsoft Flight Simulator and X-Plane in features — a testament to the flexibility of FlightGear. This article describes how to obtain and use the jetways and interface them with aircraft and scenery.&lt;br /&gt;
&lt;br /&gt;
== Compatible airports and aircraft ==&lt;br /&gt;
This section lists the airports having animated jetways, as well as the aircraft and AI aircraft supporting them, as of September 2015.&lt;br /&gt;
&lt;br /&gt;
The compatible airports are:&lt;br /&gt;
* [[London Gatwick Airport]] (EGKK)*&lt;br /&gt;
* [[Amsterdam Airport Schiphol]] (EHAM)&lt;br /&gt;
* Denver International Airport (KDEN)*&lt;br /&gt;
* Las Vegas McCarran International Airport (KLAS)*&lt;br /&gt;
* [[San Francisco International Airport]] (KSFO)&lt;br /&gt;
* Ted Stevens Anchorage International Airport (PANC)*&lt;br /&gt;
''&amp;lt;nowiki&amp;gt;*&amp;lt;/nowiki&amp;gt; indicates the jetways for this airport were auto-converted and do not have gate numbers.''&lt;br /&gt;
&lt;br /&gt;
The aircraft supporting animated jetways are:&lt;br /&gt;
* [[Boeing 717]]&lt;br /&gt;
* [[Boeing 747-8i]]&lt;br /&gt;
* [[Boeing 757-200]] and -300&lt;br /&gt;
* [[Boeing 767-300]]/ER&lt;br /&gt;
* [[Boeing 777-200ER]]&lt;br /&gt;
* [[Bombardier CRJ700]]&lt;br /&gt;
&lt;br /&gt;
The [[Interactive traffic|AI aircraft]] supporting animated jetways are:&lt;br /&gt;
* [[Airbus A319]]&lt;br /&gt;
* [[Airbus A320]]&lt;br /&gt;
* [[Airbus A321]]&lt;br /&gt;
* [[Boeing 737]]&lt;br /&gt;
* [[Boeing 747-400]]&lt;br /&gt;
* [[McDonnell Douglas MD-80]]&lt;br /&gt;
&lt;br /&gt;
The {{fgdata file|Models/Airport/Jetway/generic.xml|t=generic jetway model}} in FGData is broken, but there is [http://scenemodels.flightgear.org/app.php?c=Models&amp;amp;a=view&amp;amp;id=2211 a repaired version in the TerraSync scenery repository].&lt;br /&gt;
&lt;br /&gt;
== Obtaining and installing ==&lt;br /&gt;
FlightGear 2.4.0 and later include the animated jetway system. Nothing extra has to be installed.&lt;br /&gt;
&lt;br /&gt;
== Using the jetways ==&lt;br /&gt;
# Start FlightGear in any compatible aircraft.&lt;br /&gt;
# Fly (or spawn) to any airport equipped with animated jetways. You can tell if a jetway is animated by pressing {{key press|Ctrl|C}}; if the polygons are highlighted in yellow, then it is animated.&lt;br /&gt;
{{note|Ensure you have the latest scenery from [[TerraSync]] so you do not get conflicts between animated and static jetways.}}&lt;br /&gt;
&amp;lt;ol start=&amp;quot;3&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Taxi up to an animated jetway and park near it, then click it. If your aircraft is supported and parked well enough, the jetway will extend, rotate, and connect.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adding support in aircraft ==&lt;br /&gt;
# Open up the main model of your aircraft in your favorite 3D modeling software (such as [[Blender]]).&lt;br /&gt;
# Move the model around to account for any offsets you have in the main model file, then get the coordinates of the door.&lt;br /&gt;
[[File:Animated-jetway-tutorial.jpg]]&lt;br /&gt;
&amp;lt;ol start=&amp;quot;3&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Add the following code in your aircraft's -set.xml (remember to merge the tags properly):&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight language=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;sim&amp;gt;&lt;br /&gt;
 &amp;lt;model&amp;gt;&lt;br /&gt;
  &amp;lt;door&amp;gt;&lt;br /&gt;
   &amp;lt;position-x-m type=&amp;quot;float&amp;quot;&amp;gt;X-M&amp;lt;/position-x-m&amp;gt;&lt;br /&gt;
   &amp;lt;position-y-m type=&amp;quot;float&amp;quot;&amp;gt;Y-M&amp;lt;/position-y-m&amp;gt;&lt;br /&gt;
   &amp;lt;position-z-m type=&amp;quot;float&amp;quot;&amp;gt;Z-M&amp;lt;/position-z-m&amp;gt;&lt;br /&gt;
   &amp;lt;jetway-hood-deg type=&amp;quot;float&amp;quot;&amp;gt;HOOD-DEG&amp;lt;/jetway-hood-deg&amp;gt;&lt;br /&gt;
  &amp;lt;/door&amp;gt;&lt;br /&gt;
 &amp;lt;/model&amp;gt;&lt;br /&gt;
&amp;lt;/sim&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
: where &amp;lt;tt&amp;gt;X-M&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;Y-M&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;Z-M&amp;lt;/tt&amp;gt; are the X/Y/Z coordinates of the door in meters and &amp;lt;tt&amp;gt;HOOD-DEG&amp;lt;/tt&amp;gt; is the jetway hood rotation amount. To specify more doors, just add more door elements.&lt;br /&gt;
&amp;lt;ol start=&amp;quot;4&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Add the following code into your XML model file to enable the jetways to connect to your aircraft over the [[multiplayer]] network:&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight language=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;nasal&amp;gt;&lt;br /&gt;
  &amp;lt;load&amp;gt;&lt;br /&gt;
   var model = cmdarg();&lt;br /&gt;
   model.getNode(&amp;quot;door[0]/position-x-m&amp;quot;, 1).setValue(X-M);&lt;br /&gt;
   model.getNode(&amp;quot;door[0]/position-y-m&amp;quot;, 1).setValue(Y-M);&lt;br /&gt;
   model.getNode(&amp;quot;door[0]/position-z-m&amp;quot;, 1).setValue(Z-M);&lt;br /&gt;
   model.getNode(&amp;quot;door[0]/jetway-hood-deg&amp;quot;, 1).setValue(HOOD-DEG);&lt;br /&gt;
  &amp;lt;/load&amp;gt;&lt;br /&gt;
 &amp;lt;/nasal&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
: Again, replace &amp;lt;tt&amp;gt;X-M&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;Y-M&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;Z-M&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;HOOD-DEG&amp;lt;/tt&amp;gt; with their respective values. To add more doors, duplicate the last four lines of [[Nasal]] code and replace &amp;lt;tt&amp;gt;[0]&amp;lt;/tt&amp;gt; with &amp;lt;tt&amp;gt;[1]&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;[2]&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Adding support in AI aircraft ===&lt;br /&gt;
Follow the steps for regular aircraft above, but only add in the Nasal code.&lt;br /&gt;
&lt;br /&gt;
== Adding support in scenery ==&lt;br /&gt;
=== Placing jetways ===&lt;br /&gt;
# Launch FlightGear in your favorite aircraft, such as the [[Bluebird]].&lt;br /&gt;
{{note|You ''cannot'' use the [[UFO]] because its scenery editing function will interfere with the jetway editor.}}&lt;br /&gt;
&amp;lt;ol start=&amp;quot;2&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Go to {{menu item|AI|Jetway Settings}} and tick the '''Enable jetway editor''' checkbox, then click the {{button|Open Editor}} button.&lt;br /&gt;
[[File:Animated-jetway-editor.jpg]]&lt;br /&gt;
&amp;lt;li&amp;gt;With the editor enabled, click anywhere on the ground to place an animated jetway, which will flash to indicate it is selected. The jetway editor is similar to the UFO scenery model editor. You can {{key press|Alt}}+click on the terrain to move the current selected jetway. {{key press|Ctrl}}+click selects the jetway closest to the click position (the new jetway will flash to indicate it is selected). {{key press|Shift}}+click deselects the current jetway.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: The dialog is used to adjust the selected jetway. The top sliders adjust position and orientation and the bottom ones adjust the jetway itself. The offsets that the bottom sliders control can be used to model jetways that are in obscure configurations. The dropdown menus at the very bottom of the dialog control various properties of the jetway, such as the model, gate number, airline sign and door number. The following models are available:&lt;br /&gt;
:* Generic&lt;br /&gt;
:* Glass&lt;br /&gt;
:* [[EHAM]] gate&lt;br /&gt;
:* [[EHAM]] 747 gate&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol start=&amp;quot;4&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;When you are finished editing your airport jetway layout, click the {{button|Export}} button. A jetway definition file will be created and written to &amp;lt;tt&amp;gt;$FG_HOME/Export/ICAO.xml&amp;lt;/tt&amp;gt;, where &amp;lt;tt&amp;gt;ICAO&amp;lt;/tt&amp;gt; is the ICAO code of the nearest airport. (The exact location of this file is printed to the console window.) This file should be [[FlightGear Scenery Database#Contribute|submitted to TerraSync]].&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Auto-converting static/obsolete jetways ===&lt;br /&gt;
{{WIP}}&lt;br /&gt;
&lt;br /&gt;
== Future development ==&lt;br /&gt;
Ryan A Young, the original developer of the animated jetway code, is planning to rewrite it as a C++ subsystem. This would bring several advantages:&lt;br /&gt;
* some hacks in the current [[Nasal]] code would be removed, and the system would be faster and more reliable;&lt;br /&gt;
* the model files could be streamlined and the jetways could be automatically placed on the ground, irrespective of the employed scenery;&lt;br /&gt;
* performance could be improved by letting the user decide how many jetways would be rendered;&lt;br /&gt;
* they could be integrated with AI traffic.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
| url    = http://sourceforge.net/p/flightgear/mailman/message/34725917/&lt;br /&gt;
| title  = &amp;lt;nowiki&amp;gt;[Flightgear-devel] Animated jet bridges redux&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| author = &amp;lt;nowiki&amp;gt;Ryan A Young&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| date   = Dec 29th, 2015&lt;br /&gt;
}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Related content ==&lt;br /&gt;
* [[Ramp Marshall]]&lt;br /&gt;
* {{forumref|title=The animated jetway project|t=8728|f=5}}&lt;br /&gt;
&lt;br /&gt;
{{Appendix}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Scenery]]&lt;br /&gt;
[[Category:Scenery enhancement]]&lt;/div&gt;</summary>
		<author><name>Elgaton</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Template:Forum_link&amp;diff=98199</id>
		<title>Template:Forum link</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Template:Forum_link&amp;diff=98199"/>
		<updated>2016-05-13T18:09:10Z</updated>

		<summary type="html">&lt;p&gt;Elgaton: Fix query parameters present even if the arguments were not passed; make style more in line with Template:Wikipedia for uniformity&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;span class=&amp;quot;plainlinks&amp;quot;&amp;gt;[https://forum.flightgear.org/viewtopic.php?&amp;lt;!--&lt;br /&gt;
--&amp;gt;{{#if:{{{f|}}}|f={{{f}}}&amp;lt;!-- Add an ampersand if t, p or hilit are present afterwards&lt;br /&gt;
--&amp;gt;{{#if:{{{t|}}}|&amp;amp;|{{#if:{{{p|}}}|&amp;amp;|{{#if:{{{hilit|}}}|&amp;amp;|}}}}}}&amp;lt;!--&lt;br /&gt;
--&amp;gt;|}}{{#if:{{{t|}}}|t={{{t}}}&amp;lt;!-- Add an ampersand if p or hilit are present afterwards&lt;br /&gt;
--&amp;gt;{{#if:{{{p|}}}|&amp;amp;|{{#if:{{{hilit|}}}|&amp;amp;|}}}}&amp;lt;!--&lt;br /&gt;
--&amp;gt;|}}{{#if:{{{p|}}}|p={{{p}}}&amp;lt;!-- Add an ampersand if hilit is present afterwards&lt;br /&gt;
--&amp;gt;{{#if:{{{hilit|}}}|&amp;amp;|}}&amp;lt;!--&lt;br /&gt;
--&amp;gt;|}}{{#if:{{{hilit|}}}|hilit={{{hilit}}}|}}{{#if:{{{label|}}}|#{{{label}}}|}} {{#if:{{{title|}}}|''{{{title}}}'' on the forum|Forum link}}]&amp;lt;/span&amp;gt;{{#if: {{{noicon|}}} | | &amp;amp;#32;[[File:FlightGear icon 15px.png|This is a link to the FlightGear forum|link=Template:Forumref]] }}&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{Informative template|1=&lt;br /&gt;
__NOTOC__&lt;br /&gt;
== Goal ==&lt;br /&gt;
A template to standardize forum links.&lt;br /&gt;
&lt;br /&gt;
== Usage ==&lt;br /&gt;
 {{obr}}'''forumref'''{{!}}title={{!}}''t=''{{!}}''p=''{{!}}''label=''{{!}}''hilit=''{{!}}''f=''{{!}}''noicon=''{{cbr}}&lt;br /&gt;
&lt;br /&gt;
; title: Topic title&lt;br /&gt;
&lt;br /&gt;
; t: Thread number to be passed to phpBB's viewtopic.php (optional)&lt;br /&gt;
&lt;br /&gt;
; p: Post number to be passed to phpBB's viewtopic.php (optional)&lt;br /&gt;
&lt;br /&gt;
; label: HTML label, used for jumping to posts (optional)&lt;br /&gt;
&lt;br /&gt;
; hilit: Words on the forum posts to be highlighted (optional)&lt;br /&gt;
&lt;br /&gt;
; f: Forum number to be passed to phpBB's viewtopic.php (optional)&lt;br /&gt;
&lt;br /&gt;
; noicon: If true, the little FlightGear icon ([[File:FlightGear icon 15px.png]]) will not be shown.&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;{{forumref|title=FlightGear Newsletter|t=7794}}&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{forumref|title=FlightGear Newsletter|t=7794}}&lt;br /&gt;
&lt;br /&gt;
== Related template ==&lt;br /&gt;
* {{tl|forum}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Link templates]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Elgaton</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=File:FlightGear_icon_15px.png&amp;diff=98194</id>
		<title>File:FlightGear icon 15px.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=File:FlightGear_icon_15px.png&amp;diff=98194"/>
		<updated>2016-05-13T17:00:31Z</updated>

		<summary type="html">&lt;p&gt;Elgaton: Fixed file information&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=={{int:filedesc}}==&lt;br /&gt;
{{Information&lt;br /&gt;
|description={{en|1=Resized version of [[:File:FlightGear_logo.png]] for use in link templates.}}{{it|1=Versione ridimensionata di [[:File:FlightGear_logo.png]] per l'utilizzo all'interno dei modelli per i link.}}&lt;br /&gt;
|date=2016-05-13&lt;br /&gt;
|source=Resized version of [[:File:FlightGear_logo.png]]&lt;br /&gt;
|author=Original by [[User:Gijs]], edited by [[User:Elgaton]]&lt;br /&gt;
|permission=&lt;br /&gt;
|other versions=[[:File:FlightGear_logo.png]]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=={{int:license-header}}==&lt;br /&gt;
{{Template:GPL}}&lt;br /&gt;
&lt;br /&gt;
[[Category:FlightGear logotypes]]&lt;/div&gt;</summary>
		<author><name>Elgaton</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=File:FlightGear_icon_15px.png&amp;diff=98193</id>
		<title>File:FlightGear icon 15px.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=File:FlightGear_icon_15px.png&amp;diff=98193"/>
		<updated>2016-05-13T16:57:23Z</updated>

		<summary type="html">&lt;p&gt;Elgaton: User created page with UploadWizard&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=={{int:filedesc}}==&lt;br /&gt;
{{Information&lt;br /&gt;
|description={{en|1=Resized version of [[File:FlightGear_logo.png]] for use in link templates.}}{{it|1=Versione ridimensionata di [[File:FlightGear_logo.png]] per l'utilizzo all'interno dei modelli per i link.}}&lt;br /&gt;
|date=2016-05-13&lt;br /&gt;
|source=Resized version of [[File:FlightGear_logo.png]]&lt;br /&gt;
|author=[[User:Gijs]]&lt;br /&gt;
|permission=&lt;br /&gt;
|other versions=&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=={{int:license-header}}==&lt;br /&gt;
{{subst:Custom license marker added by UW}}&lt;br /&gt;
{{Template:GPL}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:FlightGear logotypes]]&lt;/div&gt;</summary>
		<author><name>Elgaton</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Howto:Animated_jetways_(Type_1)&amp;diff=98175</id>
		<title>Howto:Animated jetways (Type 1)</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Howto:Animated_jetways_(Type_1)&amp;diff=98175"/>
		<updated>2016-05-13T14:19:26Z</updated>

		<summary type="html">&lt;p&gt;Elgaton: First set of restyling modifications&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Animated jetways''' are dynamic {{Wikipedia|jetway}} models that connect to your aircraft when you are pulled up at a gate. [[FlightGear]] boasts the most advanced animated jetways in the flight simulator market, beating those of Microsoft Flight Simulator and X-Plane in features — a testament to the flexibility of FlightGear. This article describes how to obtain and use the jetways and interface them with aircraft and scenery.&lt;br /&gt;
&lt;br /&gt;
== Current state ==&lt;br /&gt;
As of September 2015, only the following airports have animated jetways.&lt;br /&gt;
* [[London Gatwick Airport]] (EGKK)*&lt;br /&gt;
* [[Amsterdam Airport Schiphol]] (EHAM)&lt;br /&gt;
* Denver International Airport (KDEN)*&lt;br /&gt;
* Las Vegas McCarran International Airport (KLAS)*&lt;br /&gt;
* [[San Francisco International Airport]] (KSFO)&lt;br /&gt;
* Ted Stevens Anchorage International Airport (PANC)*&lt;br /&gt;
''&amp;lt;nowiki&amp;gt;*&amp;lt;/nowiki&amp;gt; indicates the jetways for this airport were auto-converted and do not have gate numbers.''&lt;br /&gt;
&lt;br /&gt;
The {{fgdata file|Models/Airport/Jetway/generic.xml|t=generic jetway model}} in FGData is broken, but there is [http://scenemodels.flightgear.org/app.php?c=Models&amp;amp;a=view&amp;amp;id=2211 a repaired version in the TerraSync scenery repository].&lt;br /&gt;
&lt;br /&gt;
== Obtaining and installing ==&lt;br /&gt;
FlightGear 2.4.0 and later include the animated jetway system. Nothing extra has to be installed.&lt;br /&gt;
&lt;br /&gt;
== Using the jetways ==&lt;br /&gt;
# Start FlightGear in any animated jetway-compatible aircraft. As of May 2016, these include the following:&lt;br /&gt;
#* [[Boeing 717]]&lt;br /&gt;
#* [[Boeing 747-8i]]&lt;br /&gt;
#* [[Boeing 757-200]] and -300&lt;br /&gt;
#* [[Boeing 767-300]]/ER&lt;br /&gt;
#* [[Boeing 777-200ER]]&lt;br /&gt;
#* [[Bombardier CRJ700]]&lt;br /&gt;
# Fly (or spawn) to any airport equipped with animated jetways. You can tell if a jetway is animated by pressing {{key press|Ctrl|C}}; if the polygons are highlighted in yellow, then it is animated.&lt;br /&gt;
{{note|Ensure you have the latest scenery from [[TerraSync]] so you do not get conflicts between animated and static jetways.}}&lt;br /&gt;
&amp;lt;ol start=&amp;quot;3&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Taxi up to an animated jetway and park near it, then click it. If your aircraft is supported and parked well enough, the jetway will extend, rotate, and connect.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adding support in aircraft ==&lt;br /&gt;
# Open up the main model of your aircraft in your favorite 3D modeling software (such as [[Blender]]).&lt;br /&gt;
# Move the model around to account for any offsets you have in the main model file, then get the coordinates of the door.&lt;br /&gt;
[[File:Animated-jetway-tutorial.jpg]]&lt;br /&gt;
# Add the following code in your aircraft's -set.xml (remember to merge the tags properly):&lt;br /&gt;
&amp;lt;syntaxhighlight language=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;sim&amp;gt;&lt;br /&gt;
 &amp;lt;model&amp;gt;&lt;br /&gt;
  &amp;lt;door&amp;gt;&lt;br /&gt;
   &amp;lt;position-x-m type=&amp;quot;float&amp;quot;&amp;gt;X-M&amp;lt;/position-x-m&amp;gt;&lt;br /&gt;
   &amp;lt;position-y-m type=&amp;quot;float&amp;quot;&amp;gt;Y-M&amp;lt;/position-y-m&amp;gt;&lt;br /&gt;
   &amp;lt;position-z-m type=&amp;quot;float&amp;quot;&amp;gt;Z-M&amp;lt;/position-z-m&amp;gt;&lt;br /&gt;
   &amp;lt;jetway-hood-deg type=&amp;quot;float&amp;quot;&amp;gt;HOOD-DEG&amp;lt;/jetway-hood-deg&amp;gt;&lt;br /&gt;
  &amp;lt;/door&amp;gt;&lt;br /&gt;
 &amp;lt;/model&amp;gt;&lt;br /&gt;
&amp;lt;/sim&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
: where &amp;lt;tt&amp;gt;X-M&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;Y-M&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;Z-M&amp;lt;/tt&amp;gt; are the X/Y/Z coordinates of the door in meters and &amp;lt;tt&amp;gt;HOOD-DEG&amp;lt;/tt&amp;gt; is the jetway hood rotation amount. To specify more doors, just add more door elements.&lt;br /&gt;
&amp;lt;ol start=&amp;quot;4&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Add the following code into your XML model file to enable the jetways to connect to your aircraft over the [[multiplayer]] network:&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight language=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;nasal&amp;gt;&lt;br /&gt;
  &amp;lt;load&amp;gt;&lt;br /&gt;
   var model = cmdarg();&lt;br /&gt;
   model.getNode(&amp;quot;door[0]/position-x-m&amp;quot;, 1).setValue(X-M);&lt;br /&gt;
   model.getNode(&amp;quot;door[0]/position-y-m&amp;quot;, 1).setValue(Y-M);&lt;br /&gt;
   model.getNode(&amp;quot;door[0]/position-z-m&amp;quot;, 1).setValue(Z-M);&lt;br /&gt;
   model.getNode(&amp;quot;door[0]/jetway-hood-deg&amp;quot;, 1).setValue(HOOD-DEG);&lt;br /&gt;
  &amp;lt;/load&amp;gt;&lt;br /&gt;
 &amp;lt;/nasal&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
: Again, replace &amp;lt;tt&amp;gt;X-M&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;Y-M&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;Z-M&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;HOOD-DEG&amp;lt;/tt&amp;gt; with their respective values. To add more doors, duplicate the last four lines of [[Nasal]] code and replace &amp;lt;tt&amp;gt;[0]&amp;lt;/tt&amp;gt; with &amp;lt;tt&amp;gt;[1]&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;[2]&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Adding support in AI aircraft ===&lt;br /&gt;
Follow the steps for regular aircraft above, but only add in the Nasal code.&lt;br /&gt;
&lt;br /&gt;
=== jetway-enabled AI Aircraft (9/2015) ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
AI/Aircraft/A319/A319-main.xml&lt;br /&gt;
AI/Aircraft/A320/A320-main.xml&lt;br /&gt;
AI/Aircraft/737/737-main.xml&lt;br /&gt;
AI/Aircraft/MD80/MD80-main.xml&lt;br /&gt;
AI/Aircraft/A321/A321-main.xml&lt;br /&gt;
AI/Aircraft/747-400/747-400-main.xml&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adding support in scenery ==&lt;br /&gt;
&lt;br /&gt;
=== Placing jetways ===&lt;br /&gt;
&lt;br /&gt;
Launch FlightGear in your favorite aircraft. The author uses the [[Bluebird]]. You ''cannot'' use the [[UFO]] because its scenery-editing function will interfere with the jetway editor. Go to AI &amp;gt; Jetway Settings and tick the &amp;quot;Enable jetway editor&amp;quot; checkbox. Then click the &amp;quot;Open Editor&amp;quot; button.&lt;br /&gt;
&lt;br /&gt;
[[File:Animated-jetway-editor.jpg]]&lt;br /&gt;
&lt;br /&gt;
With the editor enabled, click anywhere on the ground to place an animated jetway, which will flash to indicate it is selected. The jetway editor is similar to the UFO's scenery model editor. You can Alt-click on the terrain to move the current selected jetway. Ctrl-click selects the jetway closest to the click position (the new jetway will flash to indicate it's selected). Shift-click deselects the current jetway.&lt;br /&gt;
&lt;br /&gt;
The dialog is used to adjust the selected jetway. The top sliders adjust position and orientation, and the bottom ones adjust the jetway itself. The offsets that the bottom sliders control can be used to model jetways that are in obscure configurations. The drop-down menus at the very bottom of the dialog control various properties of the jetway, such as the model, gate number, airline sign, and door number. At the moment, the following models are available:&lt;br /&gt;
&lt;br /&gt;
* Generic&lt;br /&gt;
* Glass&lt;br /&gt;
* [[EHAM]] gate&lt;br /&gt;
* [[EHAM]] 747 gate&lt;br /&gt;
&lt;br /&gt;
When you are finished editing your airport jetway layout, click the &amp;quot;Export&amp;quot; button. A jetway definition file will be created and written to &amp;lt;tt&amp;gt;$FG_HOME/Export/ICAO.xml&amp;lt;/tt&amp;gt;, where &amp;lt;tt&amp;gt;ICAO&amp;lt;/tt&amp;gt; is the ICAO code of the nearest airport. (The exact location of this file is printed to the console window.) This file should be submitted to Terrasync (see [[FlightGear Scenery Database#Contribute]]).&lt;br /&gt;
&lt;br /&gt;
=== Auto-converting static/obsolete jetways ===&lt;br /&gt;
&lt;br /&gt;
{{WIP}}&lt;br /&gt;
&lt;br /&gt;
== Future Development ==&lt;br /&gt;
{{FGCquote&lt;br /&gt;
|1= I don't know if anyone remembers the Nasal-based animated jetway code I wrote a few years ago, but I'd like to rewrite it as a clean-sheet C++ subsystem. I want to eliminate the truly atrocious Nasal hacks I used in the initial implementation and make the whole thing faster and more reliable. My objectives as of now are, 1) Implement a new FGJetwayManager subsystem to replace the existing code in jetways.nas. (I have not yet decided what to do with jetways_edit.nas - it might be fixed up instead of outright replaced.) 2) Streamline the jetway model files in fgdata. I want to do away with the generic.airline.&amp;lt;XYZ&amp;gt;.xml files because they're unnecessary clutter. The C++ code can deal with these cases. 3) As for the jetway definition files themselves (&amp;lt;airport&amp;gt;.jetways.xml), the only change I'd like to make is deprecating the &amp;quot;elevation-m&amp;quot; property for each jetway, which is currently relative to the surrounding scenery, including buildings and AI craft (due to the Nasal API). Instead, I propose fixing all jetways to the ground. Rationale: The current method is unreliable (see sunken jetways at KSFO) and I can't imagine a situation when you would need a floating jetway. 4) Performance optimiations - much of this would come from plain superior code, but I also plan to introduce a user preference for &amp;quot;jetway density.&amp;quot; That is, you can choose to spawn between 0 to 100% of all jetways defined for an airport. This allows the user to reduce the overhead from rendering and animating all those jetway objects (which is probably the biggest bottleneck besides the current Nasal implementation). This is what FSX does. 5) Potential idea - integration with AI traffic. So that when AI airliners park at their gates, jetways will extend to meet them. The current Nasal code makes an attempt at this, but it's very hacky and unreliable. While I think this is a cool idea, I don't want to interfere with anyone's work on the AI subsystem. I would greatly appreciate any ideas and comments on my proposal, as well as some pointers and tips on getting started with core development. :-)&lt;br /&gt;
|2= {{cite web&lt;br /&gt;
  | url    = http://sourceforge.net/p/flightgear/mailman/message/34725917/&lt;br /&gt;
  | title  = &amp;lt;nowiki&amp;gt;[Flightgear-devel] Animated jet bridges redux&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  | author = &amp;lt;nowiki&amp;gt;Ryan A Young&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  | date   = Dec 29th, 2015&lt;br /&gt;
  }}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Related content ==&lt;br /&gt;
=== FlightGear wiki ===&lt;br /&gt;
* [[Ramp Marshall]]&lt;br /&gt;
&lt;br /&gt;
=== Forum topics ===&lt;br /&gt;
* [http://forum.flightgear.org/viewtopic.php?f=5&amp;amp;t=8728 The animated jetway project]&lt;br /&gt;
&lt;br /&gt;
[[Category:Scenery]]&lt;br /&gt;
[[Category:Scenery enhancement]]&lt;/div&gt;</summary>
		<author><name>Elgaton</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=FlightGear_wiki:Village_pump&amp;diff=98174</id>
		<title>FlightGear wiki:Village pump</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=FlightGear_wiki:Village_pump&amp;diff=98174"/>
		<updated>2016-05-13T14:19:01Z</updated>

		<summary type="html">&lt;p&gt;Elgaton: /* Reorganizing the Git articles */ Response&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Archives|[[/Archive 2012|2012]]|[[/Archive 2013|2013]]|[[/Archive 2014|2014]]|[[/Archive 2015|2015]]}}&lt;br /&gt;
{{shortcut|FGW:VP}}&lt;br /&gt;
Welcome to the '''Village Pump'''. This page is used to discuss the technical issues, operations and guidelines of the [[FlightGear wiki]].&lt;br /&gt;
&lt;br /&gt;
Please &amp;lt;span class=&amp;quot;plainlinks&amp;quot;&amp;gt;[{{fullurl:{{FULLPAGENAME}}|action=edit&amp;amp;section=new}} add new topics]&amp;lt;/span&amp;gt; to the '''bottom''' of this page.&lt;br /&gt;
&lt;br /&gt;
Old discussion should be moved to a [[FlightGear wiki:Village pump/Archive YEAR]]. These discussions can then be moved to a relevant talk page if appropriate.&lt;br /&gt;
&lt;br /&gt;
== Welcome template? ==&lt;br /&gt;
I have been thinking about suggesting a welcome template, for example named {{obr}}welcome{{cbr}}, to place on top of (at least) new users user discussion pages.&lt;br /&gt;
&lt;br /&gt;
It should welcome the (new) user&lt;br /&gt;
&lt;br /&gt;
In addition, it should probably mention and/or link to pages mentioning:&lt;br /&gt;
* The introduction page/tutorial (Hmm, I do not think I did finish that one. See [[Help talk:Tutorial]] ([http://wiki.flightgear.org/index.php?title=Help_talk:Tutorial&amp;amp;oldid=70843 perm])).&lt;br /&gt;
* Help pages&lt;br /&gt;
* How to use categories (in particular not like #tags, ;-) but also that image and article categories should be separate, but link to each other)&lt;br /&gt;
* The portals&lt;br /&gt;
* The style manual&lt;br /&gt;
* Discussion pages and where to discuss what:&lt;br /&gt;
** How to use discussion pages&lt;br /&gt;
** The wiki in general:  The village pump (this page)&lt;br /&gt;
** Wiki articles:  Article discussion pages&lt;br /&gt;
** Wiki user actions:  User discussion pages&lt;br /&gt;
&lt;br /&gt;
Maybe it should also mention that FGAddon aircraft, effects, other features etc. (except for their articles) and their bugs should be discussed on the forum, unless developers say otherwise, and that core features should be discussed on the developer mailing list and core bugs on the bug tracker.&lt;br /&gt;
&lt;br /&gt;
—[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 20:31, 30 January 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
: I think this is a great idea.  A nice concise summary with links to help a new user navigate the FlightGear jungle would be a great addition.  It should however remain very short with simple sentences - while being complete - as many users are not native speakers.  So maybe there should be translations of the template with manually added links at the bottom for easy access to all the translations?&lt;br /&gt;
&lt;br /&gt;
: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 03:35, 12 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: Regarding an introduction article, I have come to the conclusion that a complete but long article is probably not as helpful as short but specific help pages.  In essence the latter would be easier to navigate and absorb.  I have therefore started to slowly split up some of the help pages and have added one more section to [[Help:Contents]].&lt;br /&gt;
:: I think that a welcome phrase, a link to that page and the [[FlightGear wiki:Manual of Style|style manual]] might actually suffice for a welcome template for now.  It is at least better than what we currently have (i.e. more or less nothing).&lt;br /&gt;
:: —[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 14:47, 4 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: I now consider&lt;br /&gt;
::* A Welcome message&lt;br /&gt;
::* A link to this page&lt;br /&gt;
::* A link to the help pages&lt;br /&gt;
::* A link to the manual of style&lt;br /&gt;
::* Some final welcoming words&lt;br /&gt;
&lt;br /&gt;
:: A welcome template should probably also very briefly mention a pet peeve of mine: the categories.&lt;br /&gt;
:: Many (if not most) image uploaders seem to treat them like tags, but if say all screenshots of aircraft (probably &amp;gt;2000) would end up at [[:Category:Aircraft]] (instead of under a subcategory to [[:Category:Screenshots of aircraft]]), of what use would that page be when looking for a specific one?  If people would like to be able to search for an aircraft, a concise but comprehensive image description is very hard to beat.&lt;br /&gt;
:: How do I convey all that in a way that is, short, to the point and easy to absorb (and act by)? And where is the best place?&lt;br /&gt;
:: —[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 02:46, 8 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: An early draft is now at [[User:Johan G/Template:Welcome to the wiki]]&lt;br /&gt;
:: —[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 02:52, 18 April 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
::: Some comments on the draft:&lt;br /&gt;
::: * I'm not fully sure about using a prominent box - I think it stands out a bit too much. Wikipedia {{wikipedia|Template:Welcome|uses a simple thread on the Talk page}}; as an alternative, we could use lighter colors.&lt;br /&gt;
::: * I've also expanded the text a bit. My proposal would be (I've put it in a box, but I'm for the &amp;quot;thread&amp;quot; solution):&lt;br /&gt;
&amp;lt;div style=&amp;quot;background: #fff; border: 1px #585858 solid; padding: 12px; margin: 12px&amp;quot;&amp;gt;&lt;br /&gt;
[[Image:Example.png|left]] '''Welcome to the FlightGear wiki, {{#if: {{{name|}}} | {{{name}}} | {{BASEPAGENAME}}}}'''! We hope you will enjoy your stay!&lt;br /&gt;
&lt;br /&gt;
See [[Help:Contents#Reading|Reading]] to learn how wikis work. You can also [[Special:CategoryTree/Root category|browse the existing page categories]].&lt;br /&gt;
&lt;br /&gt;
Should you wish to create or edit some articles, ''do so''! Here are some resources to get you started:&lt;br /&gt;
* [[Help:Contents#Editing|How to edit pages]]&lt;br /&gt;
* [[Help:Discussion pages|Discussion pages]], where we discuss and agree on potential improvements&lt;br /&gt;
* [[FlightGear wiki:Manual of Style|The Manual of Style]], a set of guidelines to help editors maintain a consistent style and formatting (please follow them)&lt;br /&gt;
* [[Help:Contents|Wiki help page]]&lt;br /&gt;
&lt;br /&gt;
If you have any questions, just start a topic on the [[FlightGear wiki:Village pump|''Discuss!'' page]]. Again, welcome!&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
::: ...where the image on the left is an appropriately chosen icon.&lt;br /&gt;
::: Finally, we could use the {{mediawiki|Extension:NewUserMessage|NewUserMessage extension}} to have the wiki software automatically post the message to the new user's talk page.&lt;br /&gt;
::: ---- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 17:30, 1 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Permanently removing spam bots ==&lt;br /&gt;
For permanently removing spam bots, has the [https://www.mediawiki.org/wiki/Extension:UserMerge UserMerge] Mediawiki extension been considered?  I use that regularly on [http://wiki.nmr-relax.com my own wiki], though there we have also reverted to communicating to the person via email before manually granting access (probably not an option here), as all of the Mediawiki captcha methods were recently cracked.&lt;br /&gt;
&lt;br /&gt;
[[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 03:15, 12 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
: Oh, for the extension, we simply have a user called 'Spam bot' in a blocked state, and merge the spam bot accounts into this one, deleting the old account.&lt;br /&gt;
: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 03:20, 12 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: I'd use the [https://www.mediawiki.org/wiki/Extension:AbuseFilter abuse filter extension] instead (much more powerful and automated) - other users have also proposed different remedies, see [http://forum.flightgear.org/viewtopic.php?f=42&amp;amp;t=28734 this forum thread]. Anyway, Gijs is going to upgrade MediaWiki shortly and review the current anti-spam measures.&lt;br /&gt;
:: -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 06:26, 13 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
::: A lot of the spam bots are using their name as advertising nowadays, so the [https://www.mediawiki.org/wiki/Extension:UserMerge UserMerge] extension is the only one I know which will allow a user and associated name to be permanently deleted.&lt;br /&gt;
&lt;br /&gt;
::: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 12:04, 14 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:::: The problem now is that they're also adding the information to the page title, so that it will still show up in the deletion logs [http://wiki.flightgear.org/Special:Log/delete] in other words, there's still some SEO juice associated with deleted entries ... Another idea would be to allow admins to temporarily disable wiki registrations/article creation, e.g. if more than 2 admins agree, this could be done to protect the wiki from spam attacks.&lt;br /&gt;
&lt;br /&gt;
::::: Hooray, you should sign your posts ;)  The bots don't target the deletion logs, as that's a little pointless.  It's a Special:* page, and the default Mediawiki robots.txt file tells all search engines to not index these pages.  User pages, page histories, etc. are however normally indexed.&lt;br /&gt;
&lt;br /&gt;
::::: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 14:36, 19 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: The point was not what the bots are targeting, but what shows up in the logs - i.e. SEO-wise - Gijs' article blacklist stuff should help with that hopefully. PS: I could not find the signature button on the mobile device I am using, and I am not too good at remembering the correct number of tildes ;-) [[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 15:04, 19 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
== WIP vs. Under construction ==&lt;br /&gt;
I have been beginning to miss the under construction template[http://wiki.flightgear.org/index.php?title=Template:Under_Construction&amp;amp;direction=prev&amp;amp;oldid=46229] more and more (though I could it definitively could be improved).&lt;br /&gt;
&lt;br /&gt;
I have begun to appreciate the need to differentiate between letting readers that a page is to be considered a yet to be finished construction site (though we in a way have that through the {{tl|incomplete}} template) and letting the reader (and other editors) that a page will receive a large amount of work for some hours or even days, usually the use for {{tl|WIP}}.&lt;br /&gt;
&lt;br /&gt;
In summary i miss templates giving a clear distinction between conditions akin to &amp;quot;Under construction&amp;quot; and &amp;quot;Caution - Wet floors&amp;quot;, rather than &amp;quot;being worked on&amp;quot; and &amp;quot;could need more work&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
—[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 10:11, 17 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
== [[Fr/Pilote automatique]] ==&lt;br /&gt;
Bonjour,&lt;br /&gt;
&lt;br /&gt;
Je viens de créer la page de traduction en français de l'article original en anglais [[Autopilot]]. Vu mes faibles compétences en matière de pilotage, vu que je n'ai pas sur ma version téléchargée d'avion avec un pilote automatique, la traduction doit souffrir quelques approximations, si ce n'est des contresens plus ennuyeux. Si quelques bonnes âmes plus qualifiées pouvaient me faire la grâce d'une relecture... merci d'avance.&lt;br /&gt;
&lt;br /&gt;
Cordialement, et Hop ! --[[User:F-WTSS|F-WTSS]] ([[User talk:F-WTSS|talk]]) 15:30, 18 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
== MediaWiki updated to 1.26.2 ==&lt;br /&gt;
I've updated MediaWiki to the latest stable release (1.26.2) today. I've still got to update some of the extensions, so there may be regressions for now. Please report bugs if you find any. For a list of changes, see https://www.mediawiki.org/wiki/Release_notes/1.26&lt;br /&gt;
&lt;br /&gt;
[[User:Gijs|Gijs]] ([[User talk:Gijs|talk]]) 10:47, 19 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
: Cheers!  I was hoping that it would solve the uneditable Chinese, Russian, and other non-latin character-based pages (Polish strangely as well), but unfortunately [[FlightGear_wiki:Village_pump/Archive_2015#UTF-8_language_pages_cannot_be_edited|that issue remains]].&lt;br /&gt;
&lt;br /&gt;
: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 10:54, 19 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: Hm, looks that will require quite some attention indeed. I'm afraid that'll has to wait for now.&lt;br /&gt;
:: [[User:Gijs|Gijs]] ([[User talk:Gijs|talk]]) 12:29, 19 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
=== Nasal Syntaxhighlighting ===&lt;br /&gt;
: Thanks for your efforts, btw: Nasal syntax highlighting is gone again.&lt;br /&gt;
: {{unsigned|17:22, 19 February 2016‎|Hooray}}&lt;br /&gt;
&lt;br /&gt;
:: Unfortunately this time it isn't me forgetting to copy a file. The SyntaxHighlight extension no longer uses GeSHi, but has switched to Pygments. This means our Nasal mapping no longer works and has to be re-written. If anyone is interested, be my guest. See http://pygments.org/docs/lexerdevelopment/&lt;br /&gt;
:: [[User:Gijs|Gijs]] ([[User talk:Gijs|talk]]) 12:29, 19 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
::: Hi Gijs,&lt;br /&gt;
::: I'm interested in making a Pygments Nasal lexer, but unfortunately I won't be able to work on it until the end of March at the earliest.&lt;br /&gt;
::: [[User:Red_Leader|&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;'''''Red Leader'''''&amp;lt;/span&amp;gt;]] ([[User_talk:Red_Leader|Talk]], [[Special:Contributions/Red_Leader|contribs]]) 16:59, 23 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:::: Unless Gijs is facing any problems, I don't think it's necessarily needed, see my comment/suggestion in this revision: [http://wiki.flightgear.org/index.php?title=FlightGear_wiki:Village_pump&amp;amp;oldid=93166] [[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 17:20, 23 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:::Hi Gijs,&lt;br /&gt;
:::Here's the code for a Nasal lexer. Be warned, it's thoroughly untested, but has the following features:&lt;br /&gt;
:::* Full support for all three string types (backtick, single quote, and double quote), including escapes and formatting strings (e.g., for {{func link|sprintf}}).&lt;br /&gt;
:::* All kinds of numbers, including numbers in scientific notation and octal and hex numbers.&lt;br /&gt;
:::* All global functions and variables as of FG v2016.1.1.&lt;br /&gt;
:::* Some of the commonly-used &amp;lt;code&amp;gt;props.Node&amp;lt;/code&amp;gt; methods.&lt;br /&gt;
:::* All the other things that can be expected (keywords, punctuation, etc.).&lt;br /&gt;
:::I have also created a lexer based on the XML lexer for XML with embedded Nasal, which I thought would be useful.&lt;br /&gt;
:::Regards,&lt;br /&gt;
:::[[User:Red_Leader|&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;'''''Red Leader'''''&amp;lt;/span&amp;gt;]] ([[User_talk:Red_Leader|Talk]], [[Special:Contributions/Red_Leader|contribs]]) 16:35, 2 April 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:::http://pygments.org/docs/lexerdevelopment/#adding-and-testing-a-new-lexer&lt;br /&gt;
:::&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
	Lexer for Nasal.&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
from pygments.lexer import RegexLexer, words, include, inherit, bygroups, using&lt;br /&gt;
from pygments.token import Text, Keyword, Name, String, Number, Operator, Punctuation, Comment&lt;br /&gt;
from pygments.lexers.html import XmlLexer&lt;br /&gt;
&lt;br /&gt;
__all__ = ['NasalLexer', 'XMLNasalLexer']&lt;br /&gt;
&lt;br /&gt;
class NasalLexer(RegexLexer):&lt;br /&gt;
&lt;br /&gt;
	name = 'Nasal'&lt;br /&gt;
	aliases = ['nasal']&lt;br /&gt;
	filenames = ['*.nas']&lt;br /&gt;
&lt;br /&gt;
	tokens = {&lt;br /&gt;
		'formatters': [&lt;br /&gt;
			(r'%[-#0 +]*(?:[0-9]+)?(?:\.[0-9]+)?[dis%couxXeEfFgG]', String.Interpol),&lt;br /&gt;
		],&lt;br /&gt;
		'backtick': [&lt;br /&gt;
			(r'`', String.Backtick, '#pop'),&lt;br /&gt;
			(r'[^`\\]+', String.Backtick),&lt;br /&gt;
			(r'\\n|\\r|\\t|\\`|\\\\|\\x[0-9a-fA-F]{2}', String.Escape),&lt;br /&gt;
		],&lt;br /&gt;
		'sqstring': [&lt;br /&gt;
			(r&amp;quot;'&amp;quot;, String.Single, '#pop'),&lt;br /&gt;
			(r&amp;quot;[^'\\%]+&amp;quot;, String.Single),&lt;br /&gt;
			(r&amp;quot;\\'&amp;quot;, String.Escape),&lt;br /&gt;
			include('formatters'),&lt;br /&gt;
		],&lt;br /&gt;
		'dqstring': [&lt;br /&gt;
			(r'&amp;quot;', String.Double, '#pop'),&lt;br /&gt;
			(r'[^&amp;quot;\\%]+', String.Double),&lt;br /&gt;
			(r'\\n|\\r|\\t|\\&amp;quot;|\\\\|\\x[0-9a-fA-F]{2}', String.Escape),&lt;br /&gt;
			include('formatters'),&lt;br /&gt;
		],&lt;br /&gt;
		'root': [&lt;br /&gt;
			(r'\s+', Text),&lt;br /&gt;
			(r'#.*?$'m, Comment.Single),&lt;br /&gt;
			(r':|\?|[!=&amp;lt;&amp;gt;+\-*\/~&amp;amp;|^]=?', Operator),&lt;br /&gt;
			(words(('or', 'and'), suffix=r'\b'), Operator.Word),&lt;br /&gt;
			(r'[{(\[})\]\.;,]', Punctuation),&lt;br /&gt;
			(words(('for', 'foreach', 'forindex', 'while', 'break', 'return', 'continue', 'if', 'else', 'elsif'), suffix=r'\b'), Keyword),&lt;br /&gt;
			(words(('var', 'func'), suffix=r'\b'), Keyword.Declaration),&lt;br /&gt;
			(words(('nil'), suffix=r'\b'), Keyword.Constant),&lt;br /&gt;
			(words(('me', 'arg'), suffix=r'\b'), Name.Builtin.Pseudo),&lt;br /&gt;
			(words(('new', 'del', 'getNode', 'getParent', 'getChild', 'getChildren', 'removeChild', 'removeChildren', 'removeAllChildren', 'getName', 'getIndex', 'getType', 'getAttribute', 'setAttribute', 'getValue', 'setValue', 'setIntValue', 'setBoolValue', 'setDoubleValue', 'unalias', 'alias', 'getPath', 'getBoolValue', 'remove', 'setValues', 'getValues', 'initNode'), suffix=r'\b'), Keyword.Pseudo),&lt;br /&gt;
			(r'0o[0-7]+', Number.Oct),&lt;br /&gt;
			(r'0x[0-9a-fA-F]+', Number.Hex),&lt;br /&gt;
			(r'\d*(?:\.\d*)?[eE][+-]?\d+', Number.Float),&lt;br /&gt;
			(r'\d*\.\d*', Number.Float),&lt;br /&gt;
			(r'\b[0-9]+\b', Number.Integer),&lt;br /&gt;
			(words(('D2R', 'R2D', 'FT2M', 'M2FT', 'IN2M', 'M2IN', 'NM2M', 'M2NM', 'KT2MPS', 'MPS2KT', 'FPS2KT', 'KT2FPS', 'LB2KG', 'KG2LB', 'GAL2L', 'L2GAL'), suffix=r'\b'), Name.Variable.Global),&lt;br /&gt;
			(words(('abort', 'abs', 'addcommand', 'airportinfo', 'airwaysRoute', 'assert', 'carttogeod', 'cmdarg', 'courseAndDistance', 'createViaTo', 'createDiscontinuity', 'createWP', 'createWPFrom', 'defined', 'directory', 'fgcommand', 'findAirportsByICAO', 'findAirportsWithinRange', 'findFixesByID', 'findNavaidByFrequency', 'findNavaidsByFrequency', 'findNavaidsByID', 'findNavaidsWithinRange', 'finddata', 'flightplan', 'geodinfo', 'geodtocart', 'getprop', 'greatCircleMove', 'interpolate', 'isa', 'logprint', 'magvar', 'maketimer', 'md5', 'navinfo', 'parse_markdown', 'parsexml', 'print', 'printf', 'printlog', 'rand', 'registerFlightPlanDelegate', 'removecommand', 'removelistener', 'resolvepath', 'setlistener', 'setprop', 'settimer', 'srand', 'systime', 'thisfunc', 'tileIndex', 'tilePath', 'values'), suffix=r'\b'), Name.Builtin),&lt;br /&gt;
			(words(('append', 'bind', 'call', 'caller', 'chr', 'closure', 'cmp', 'compile', 'contains', 'delete', 'die', 'find', 'ghosttype', 'id', 'int', 'keys', 'left', 'num', 'pop', 'right', 'setsize', 'size', 'sort', 'split', 'sprintf', 'streq', 'substr', 'subvec', 'typeof'), suffix=r'\b'), Name.Builtin),&lt;br /&gt;
			(words(('_createCondition', '_fgcommand', '_interpolate', '_setlistener'), suffix=r'\b'), Keyword.Reserved),&lt;br /&gt;
			(r'`', String.Backtick, 'backtick'),&lt;br /&gt;
			(r&amp;quot;'&amp;quot;, String.Single, 'sqstring'),&lt;br /&gt;
			(r'&amp;quot;', String.Double 'dqstring'),&lt;br /&gt;
			(r'\b_\w*?\b', Keyword.Reserved),&lt;br /&gt;
			#(r'\b\w*?\b', Name),&lt;br /&gt;
		]&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
class XMLNasalLexer(XmlLexer):&lt;br /&gt;
	&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
	For Nasal code embedded in XML files.&lt;br /&gt;
	&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	name = 'XML-Nasal'&lt;br /&gt;
	aliases = ['xml-nasal', 'xml-ns']&lt;br /&gt;
&lt;br /&gt;
	tokens = {&lt;br /&gt;
		'root': [&lt;br /&gt;
			(r'(&amp;lt;(?:load|unload|script)&amp;gt;)(&amp;lt;!\[CDATA\[)?(.*?)(]]&amp;gt;)?(&amp;lt;/(?:load|unload|script)&amp;gt;)', bygroups(Name.Tag, Comment.Preproc, using(NasalLexer), Comment.Preproc, Name.Tag),&lt;br /&gt;
			inherit,&lt;br /&gt;
		],&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:: We can use the ECMAScript/JavaScript lexer[http://pygments.org/docs/lexers/#lexers-for-javascript-and-related-languages] for now, my suggestion would be to copy that over to a file so that we can work on a custom Nasal lexer (Syntax  is almost identical, with a few different keywords, and many others being irrelevant). What is missing/different can be obtained from other lexers that are similar, e.g. [http://pygments.org/docs/lexers/#lexers-for-other-c-like-languages] [[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 15:45, 19 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: Okay, here's the better/quick&amp;amp;easy way: We have Nasal support for some fairly popular editors, like [http://wiki.flightgear.org/Howto:Syntax_highlighting_for_Nasal#Vim|vim](originally created by Melchior&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/flightgear/ci/next/tree/scripts/syntax/nasal.vim&amp;lt;/ref&amp;gt;), listed at [[Howto:Syntax_highlighting_for_Nasal]] - there are various free converters available that will read such a syntaxhighlighting file and convert it to a pygments class, e.g. see: https://github.com/honza/vim2pygments [[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 16:00, 19 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
==== References ====&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== The repository link templates ==&lt;br /&gt;
=== Complete overhaul of the repository link templates ===&lt;br /&gt;
&lt;br /&gt;
I have now performed a complete overhaul of the repository link templates (see {{tl|repo link/doc related}}).  This was motivated by the incomplete state of these templates, the lack of standardisation, the lack of SourceForge git repository support for {{tl|repo link}}, web-interface only support, etc.  I have used a lot of recursive transclusion for standardisation, so that there is a single point for updating for any FlightGear infrastructure changes.  This is the master {{tl|repo link}} template.  All the other templates are subtemplates which recursively transclude from this master template.  I have also created a number of documentation templates for simplifying template maintenance (see {{tl|repo link/doc related‎}}, {{tl|repo link/doc specific file git‎‎}}, {{tl|repo link/doc git clone‎‎}}, and {{tl|repo link/doc commit}}).  The changes were constrained to maintain backwards compatibility as much as possible.  However I would like to break this to allow the following templates to be updated to transclude from the master {{tl|repo link}} template:&lt;br /&gt;
&lt;br /&gt;
* {{tl|flightgear file}},&lt;br /&gt;
* {{tl|simgear file}},&lt;br /&gt;
* {{tl|fgdata file}},&lt;br /&gt;
* {{tl|fgaddon file}}.&lt;br /&gt;
&lt;br /&gt;
If no one objects, I would like to completely break these and expand and rename the parameter set to match the other &amp;lt;nowiki&amp;gt;{{* file}}&amp;lt;/nowiki&amp;gt; repository templates (e.g. {{tl|terragear file}}).  My overhaul currently does not include Hooray's ideas for non command line usages, i.e. different GUIs, but it enables it to be easily added via the master template and the addition of a single parameter to any subtemplates.&lt;br /&gt;
&lt;br /&gt;
[[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 15:05, 25 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
: I don't have any objections myself, I appreciate all the work you are putting into this, and would like to thank you for helping us clean up all that mess by doing such unglamorous work ;-) I also appreciate that your changes would facilitate adding a non-CLI mode to the corresponding templates. However, I would suggest to wait for Gijs' feedback, because he's ultimately the most likely person to veto something around here ;-) [[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 17:31, 25 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: Johan seems to be the one who did a lot of the initial work on these &amp;lt;nowiki&amp;gt;{{* file}}&amp;lt;/nowiki&amp;gt; templates, and Red Leader with the {{tl|repo link}} template.  And they were involved in the general discussions ([[http://wiki.flightgear.org/index.php?title=FlightGear_wiki:Village_pump&amp;amp;oldid=87148#Repository_link_templates perm]).  But I know Gijs was also involved in the design.&lt;br /&gt;
&lt;br /&gt;
:: For the non-CLI mode, that will need -a lot- more planning.  For example a definitive list of all these modes would be useful.  Should this use an optional Mediawiki pop up extension showing a link to a general page that describes the action for all different GUIs, CLI, etc.?  Should we have a switch box so that the reader can switch in-text between CLI, and the numerous GUIs?  Are we going to have a large set of screenshots for each GUI?  If so, I would strongly recommend the [https://www.mediawiki.org/wiki/Extension:Labeled_Section_Transclusion labelled section transclusion extension] for creating a single page for one GUI with everything for that GUI, as a tutorial.  Here is [http://wiki.nmr-relax.com/Relax_4.0.1 an external example where I have used this], to fragment the base release page to create [http://wiki.nmr-relax.com/Relax_release_descriptions this meta page], as well as many other meta pages.&lt;br /&gt;
&lt;br /&gt;
:: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 03:14, 26 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
I am also thinking of changing the name of the &amp;lt;nowiki&amp;gt;{{* file}}&amp;lt;/nowiki&amp;gt; templates, as I hope to make the scope of the templates far more general.  The name &amp;lt;nowiki&amp;gt;{{* source}}&amp;lt;/nowiki&amp;gt; or &amp;lt;nowiki&amp;gt;{{* repo}}&amp;lt;/nowiki&amp;gt; might be better.  For example these will allow the repository commit, tree view, log view (and maybe rss feed), with or without a file/directory path.  And I would like to generalise this to handle both the SF web-interface and non-web net protocols (git://, ssh://, svn://, etc.).  It will allow for CLI instructions to be built up and embedded in &amp;lt;nowiki&amp;gt;{{#tag:source|&amp;lt;content&amp;gt;|lang=sh}}&amp;lt;/nowiki&amp;gt; tags.  And I will defer all infrastructure decisions in the subtemplates to the single point of {{tl|project infrastructure}}, so that if there are changes in the future, then only this single template needs to be updated to update the entire wiki.&lt;br /&gt;
&lt;br /&gt;
[[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 03:22, 26 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
: The {{tl|project infrastructure}} template as a single point provider of various project infrastructure names and URL pairs seem like a great idea.  If it work out well it will really lessen the maintenance by having less places needing updates, while allowing the various repository templates to be simple to use, in essence by having comprehensible names and no boiler plate parameters for their users.&lt;br /&gt;
: —[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 15:15, 27 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
==== Repository link update ====&lt;br /&gt;
For those following, I have massively expanded the capabilities of the {{tl|repo link}} template:&lt;br /&gt;
* The SourceForge URLs are now comprehensive.&lt;br /&gt;
* Full support for the new query-based URLs for the Gitorious archives.&lt;br /&gt;
* Functional GitLab URLs.&lt;br /&gt;
* Generic repository support (used to create the {{tl|openscenegraph co}} template).&lt;br /&gt;
* Detailed documentation and extensive examples for checking the implementation (if you find any non-supported links, please add these as examples).&lt;br /&gt;
* Isolation of the '''cmd''' parameter from the CLI options &amp;amp;mdash; this is to enable future support for non-CLI instructions based on the value of '''cmd'''.&lt;br /&gt;
&lt;br /&gt;
I have also completed a large set of subtemplates of {{tl|repo link}}, see the list at {{tl|repo link/doc related}}.  This includes a full set of &amp;lt;nowiki&amp;gt;{{* source}}&amp;lt;/nowiki&amp;gt; templates.  I have left the original &amp;lt;nowiki&amp;gt;{{* file}}&amp;lt;/nowiki&amp;gt; templates, rather than renaming and modifying them, so these are now redundant.  All of the &amp;lt;nowiki&amp;gt;{{* source}}&amp;lt;/nowiki&amp;gt;, &amp;lt;nowiki&amp;gt;{{* commit}}&amp;lt;/nowiki&amp;gt;, &amp;lt;nowiki&amp;gt;{{* clone}}&amp;lt;/nowiki&amp;gt;, and &amp;lt;nowiki&amp;gt;{{* co}}&amp;lt;/nowiki&amp;gt; templates transclude from the master {{tl|repo link}} template to do all of the work.&lt;br /&gt;
&lt;br /&gt;
One important template is {{tl|gitorious source}}.  The support for the new query-based URLs for the Gitorious archives is now quite comprehensive in {{tl|repo link}}.  Therefore I have converted almost every single FlightGear wiki link to https://gitorious.org to use {{tl|gitorious source}} instead.  This fixes a lot of broken links and broken git instructions.  I have reduced the number of hits for gitorious.org on the wiki (searching just for &amp;quot;gitorious&amp;quot;) to 22 hits.  This includes 2 very outdated articles ([[FlightGear Git: aircraft authors]], [[Fr/FlightGear et Git]]), 15 locked newsletters, 1 with no longer existent Gitorious merge request links, and 4 base URL links for Hangars.  This way we can maintain the Gitorious web interface links and git command instructions in a functional state by simply updating the single source of {{tl|repo link}}.&lt;br /&gt;
&lt;br /&gt;
[[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 11:38, 29 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
: I just remembered [[Special:LinkSearch]], so make that 184 broken gitorious.org links remaining.  Lots more work to do :)&lt;br /&gt;
&lt;br /&gt;
: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 14:46, 29 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
For some of these templates, e.g. {{tl|repo link/doc usage}}, I'm trying to implement some logic for automatic whitespace padding for documentation formatting, but the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;{{#len:string}}&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; function is not enabled.  According to {{mediawiki|Wikitext_parser/Core_parser_functions#.23len}} and {{mediawiki|Extension:StringFunctions}}, the option &amp;lt;code&amp;gt;$wgPFEnableStringFunctions = true;&amp;lt;/code&amp;gt; should be set (in &amp;lt;code&amp;gt;LocalSettings.php&amp;lt;/code&amp;gt;).  Unless there is a reason for not using this, I was wondering if someone could enable this?  Cheers!&lt;br /&gt;
&lt;br /&gt;
[[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 09:53, 8 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
=== Archived newsletters and dead links? ===&lt;br /&gt;
&lt;br /&gt;
Do we have a policy for the dead links in the FlightGear newsletters?  It is obviously good to preserve the historic state.  But there are many Gitorious links that could be made functional again using the {{tl|gitorious source}} template to point to the historic Gitorious archives (including the official FlightGear repositories, rather than using {{tl|fgdata source}}, for example).  The https://gitorious.org links have been converted from URL/path based to query based, so absolutely all of the old links are broken.  I am steadily converting all Gitorious links to use the [[Template:repo link/doc related|{{obr}}repo link{{cbr}} family of templates]], with the exception of the newsletters.&lt;br /&gt;
&lt;br /&gt;
[[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 04:52, 8 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
: I think it could be a good idea to try update old links in those newsletters.  I sometimes look back at things and tend to think that I probably are not the only one doing that.&lt;br /&gt;
: I wonder if the rotten links should be replaced or stricken, but I think they could just as well be replaced.  The key thing is that they go to the same resource or content, not weather they have been updated or not (also, the change will be visible in the revision history after all).&lt;br /&gt;
: —[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 07:11, 8 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: I should add that I'm using [http://wiki.flightgear.org/index.php?title=Special:LinkSearch&amp;amp;limit=500&amp;amp;offset=0&amp;amp;target=http%3A%2F%2Fgitorious.org &amp;lt;nowiki&amp;gt;Special:LinkSearch for http://gitorious.org&amp;lt;/nowiki&amp;gt;] and [http://wiki.flightgear.org/index.php?title=Special:LinkSearch&amp;amp;limit=500&amp;amp;offset=0&amp;amp;target=https%3A%2F%2Fgitorious.org &amp;lt;nowiki&amp;gt;Special:LinkSearch for https://gitorious.org&amp;lt;/nowiki&amp;gt;].  And I am also not touching the &amp;lt;code&amp;gt;User*&amp;lt;/code&amp;gt; pages, &amp;lt;code&amp;gt;*talk*&amp;lt;/code&amp;gt; pages, or pages tagged as out of date or up for deletion.  For the newsletters I might look at these later when the broken Gitorious links are fixed in the rest of the wiki but, as these are locked, someone else might have make the switch to {{tl|gitorious source}}, {{tl|gitorious url}}, {{tl|gitorious clone}}, and {{tl|gitorious merge request}}.&lt;br /&gt;
&lt;br /&gt;
:: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 02:53, 9 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
::: I will temporarily add a table here for the templates in the newsletters and will slowly fix them one by one together with any other admin.&lt;br /&gt;
{{navbox&lt;br /&gt;
| title = Click &amp;quot;show&amp;quot; to show --&amp;gt;&lt;br /&gt;
| state = collapsed&lt;br /&gt;
| navbar = plain&lt;br /&gt;
| list1 =&lt;br /&gt;
http:...&lt;br /&gt;
{{{!}} class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Fixed !! Newsletter !! Gitorious URL !! Notes&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter May 2010]]&lt;br /&gt;
{{!}} http://gitorious.org/fg&lt;br /&gt;
{{!}} No equivalent link for the Gitorious archive - project pages are dead.  Maybe just use http://gitorious.org/?&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter May 2010]]&lt;br /&gt;
{{!}} http://gitorious.org/fg&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter September 2010]]&lt;br /&gt;
{{!}} http://gitorious.org/fg/flightgear/commit/5c6fe952598053fa63631fc0161d666f22a50f51&lt;br /&gt;
{{!}} Functional link, equivalent to {{gitorious url|fg|flightgear|commit=5c6fe952598053fa63631fc0161d666f22a50f51}}.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter September 2010]]&lt;br /&gt;
{{!}} http://gitorious.org/fg/flightgear/commit/5c6fe952598053fa63631fc0161d666f22a50f51&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter January 2011]]&lt;br /&gt;
{{!}} http://gitorious.org/jsbsim/jsbsim&lt;br /&gt;
{{!}} Functional link.  Switched to {{gitorious url|jsbsim|jsbsim}} to future-protect the link.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter January 2011]]&lt;br /&gt;
{{!}} http://gitorious.org/jsbsim/jsbsim&lt;br /&gt;
{{!}} Functional link.  Switched to {{gitorious url|jsbsim|jsbsim}} to future-protect the link.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter February 2011]]&lt;br /&gt;
{{!}} http://gitorious.org/headtrack&lt;br /&gt;
&lt;br /&gt;
http://gitorious.org/arduinocockpit&lt;br /&gt;
{{!}} Project pages are dead, switched to {{gitorious url|headtrack|headtrack}}&lt;br /&gt;
&lt;br /&gt;
{{gitorious url|arduinocockpit|arduinocockpit}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter February 2011]]&lt;br /&gt;
{{!}} http://gitorious.org/arduinocockpi&lt;br /&gt;
&lt;br /&gt;
http://gitorious.org/headtrack&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter March 2011]]&lt;br /&gt;
{{!}} http://gitorious.org/lockheed-l10-electra&lt;br /&gt;
{{!}} Missing project - i.e. {{gitlab source|user=emilianh|repo=Lockheed-L10-Electra|text=migrated to GitLab}}.  Switched to {{gitlab source|user=emilianh|repo=Lockheed-L10-Electra}}.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter March 2011]]&lt;br /&gt;
{{!}} http://gitorious.org/lockheed-l10-electra&lt;br /&gt;
{{!}} Switched to {{gitlab source|user=emilianh|repo=Lockheed-L10-Electra}}.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter November 2011]]&lt;br /&gt;
{{!}} http://gitorious.org/flightgear-aircraft&lt;br /&gt;
{{!}} Switched to {{gitorious source}} and rephrased text slightly to help readers find the repositories.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter October 2012]]&lt;br /&gt;
{{!}} http://gitorious.org/anders-hangar/mtb_20m/trees/master&lt;br /&gt;
{{!}} Switch to {{gitorious url|proj=anders-hangar|repo=mtb_20m}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter March 2013]]&lt;br /&gt;
{{!}} http://gitorious.org/fg/flightgear/blobs/next/scripts/java/FGClient/src/FGFSDemo.java&lt;br /&gt;
{{!}} Switched to {{gitorious url|proj=fg|repo=flightgear|path=scripts/java/FGClient/src/FGFSDemo.java}}.  This points to the old Gitorious repository to protect against path changes in the future.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter September 2013]]&lt;br /&gt;
{{!}} http://gitorious.org/boeing/707&lt;br /&gt;
{{!}} Switched to {{gitorious source|proj=boeing|repo=707}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter September 2013]]&lt;br /&gt;
{{!}} http://gitorious.org/boeing/707&lt;br /&gt;
{{!}} Switched to {{gitorious source|proj=boeing|repo=707}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter November 2013]]&lt;br /&gt;
{{!}} http://gitorious.org/fg/fgrun&lt;br /&gt;
{{!}} Switch to {{gitorious url|proj=fg|repo=fgrun}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter November 2013]]&lt;br /&gt;
{{!}} http://gitorious.org/fg/fgrun&lt;br /&gt;
{{!}} Switch to {{gitorious url|proj=fg|repo=fgrun}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter July 2014]]&lt;br /&gt;
{{!}} http://gitorious.org/nasal-support/nasal-npp&lt;br /&gt;
{{!}} Switched to {{gitorious url|nasal-support|nasal-npp}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter April 2015]]&lt;br /&gt;
{{!}} http://gitorious.org&lt;br /&gt;
{{!}} Switched to {{tl|gitorious source}} without parameters for the Gitorious base URL, to future-protect it.&lt;br /&gt;
{{!}}}&lt;br /&gt;
&lt;br /&gt;
https:...&lt;br /&gt;
{{{!}} class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Fixed !! Newsletter !! Gitorious URL !! Notes&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter April 2011]]&lt;br /&gt;
{{!}} https://gitorious.org/papillon81/flightgear-custom-scenery/&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/dvanmosselbeen/flightgear-custom-scenery&lt;br /&gt;
{{!}} Switched to {{gitorious source|dvanmosselbeen|flightgear-custom-scenery}} and {{gitorious source|papillon81|flightgear-custom-scenery}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter April 2011]]&lt;br /&gt;
{{!}} https://gitorious.org/dvanmosselbeen/flightgear-custom-scenery&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/papillon81/flightgear-custom-scenery/&lt;br /&gt;
{{!}} Switched to {{gitorious source|dvanmosselbeen|flightgear-custom-scenery}} and {{gitorious source|papillon81|flightgear-custom-scenery}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter July 2011]]&lt;br /&gt;
{{!}} https://gitorious.org/dvanmosselbeen/flightgear-custom-scenery&lt;br /&gt;
{{!}} Switched to {{gitorious source|dvanmosselbeen|flightgear-custom-scenery}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter July 2011]]&lt;br /&gt;
{{!}} https://gitorious.org/dvanmosselbeen/flightgear-custom-scenery&lt;br /&gt;
{{!}} Switched to {{gitorious source|dvanmosselbeen|flightgear-custom-scenery}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter December 2011]]&lt;br /&gt;
{{!}} https://gitorious.org/dvanmosselbeen/flightgear-custom-scenery&lt;br /&gt;
{{!}} Switched to {{gitorious source|dvanmosselbeen|flightgear-custom-scenery}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Fr/Nouvelles du projet FlightGear - décembre 2011]]&lt;br /&gt;
{{!}} https://gitorious.org/dvanmosselbeen/flightgear-custom-scenery&lt;br /&gt;
{{!}} Switched to {{gitorious source|dvanmosselbeen|flightgear-custom-scenery}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter April 2012]]&lt;br /&gt;
{{!}} https://gitorious.org/fg/fgdata/blobs/master/Aircraft/Instruments-3d/garmin196/README&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/fgdata/blobs/master/Aircraft/Instruments-3d/garmin196/doc/doc-en.htm&lt;br /&gt;
{{!}} Switched to {{fgdata source|path=Aircraft/Instruments-3d/garmin196/README|full=1}} and {{fgdata source|path=Aircraft/Instruments-3d/garmin196/doc/doc-en.htm|full=1}} to point to the current FGData locations and removed the name &amp;quot;Gitorious&amp;quot; to make the text of the Garmin 196 GPS section still relevant&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter August 2012]]&lt;br /&gt;
{{!}} https://gitorious.org/mil-mi-6&lt;br /&gt;
{{!}} Switched to {{gitorious url|proj=mil-mi-6|repo=mi6dev}}, and changed from the non-existent project page to the main repository.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter October 2012]]&lt;br /&gt;
{{!}} https://gitorious.org/fgradar&lt;br /&gt;
{{!}} Switched from the project page to the direct repository {{gitorious url|fgradar|fgradar}}.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter March 2013]]&lt;br /&gt;
{{!}} https://gitorious.org/fg/flightgear/commit/913727239d6776c0508d206f395e16c265413ec3&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/flightgear/commit/eba03b5e469824ee8f1494723fcddbbc56155a08&lt;br /&gt;
{{!}} Switched to {{flightgear url|commit=913727239d6776c0508d206f395e16c265413ec3}} and {{flightgear url|commit=eba03b5e469824ee8f1494723fcddbbc56155a08}}.  This deliberately points to the current repository.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter April 2013]]&lt;br /&gt;
{{!}} https://gitorious.org/fg-radi/osm2city&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/scenery-france-850&lt;br /&gt;
{{!}} Switched to the new GitLab repository {{gitlab source|proj=fg-radi|repo=osm2city|full=1}}&lt;br /&gt;
&lt;br /&gt;
and removed the no longer existent scenery-france-850 repository, replacing it with &amp;quot;&amp;lt;s&amp;gt;Scenery repository (Gitorious)&amp;lt;/s&amp;gt;&amp;quot;.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter October 2013]]&lt;br /&gt;
{{!}} https://gitorious.org/fg/galvedros-fgdata&lt;br /&gt;
{{!}} Switch to {{gitorious url|proj=fg|repo=galvedros-fgdata}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter October 2013]]&lt;br /&gt;
{{!}} https://gitorious.org/fg/galvedros-fgdata&lt;br /&gt;
{{!}} Switch to {{gitorious url|proj=fg|repo=galvedros-fgdata}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter November 2013]]&lt;br /&gt;
{{!}} https://gitorious.org/ec130/&lt;br /&gt;
{{!}} Switched from the project page to the direct repository {{gitorious source|ec130|ec130}}.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter November 2013]]&lt;br /&gt;
{{!}} https://gitorious.org/ec130/&lt;br /&gt;
{{!}} Switched from the project page to the direct repository {{gitorious source|ec130|ec130}}.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter February 2014]]&lt;br /&gt;
{{!}} https://gitorious.org/fg/philosophers-fgdata/source/022bef27f05d4837d720f63c6507b47466ff2a59:Nasal/console/repl.nas#L436&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/philosophers-fgdata/source/nasal-console:Nasal/console&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/fgdata/commit/eaaf816b772649d5b0826a1d0bdd166dbc5b968f&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/flightgear/commit/34ed79e5f88ffdfc5e651a1fe3e639cb8f4d3353&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/flightgear/commit/5eee5e42ae4f5cf56283b3bf5a3be46efc2b51c4&lt;br /&gt;
&lt;br /&gt;
https://www.gitorious.org/fg/flightgear/merge_requests/26&lt;br /&gt;
{{!}} Switched to {{gitorious source|proj=fg|repo=philosophers-fgdata|branch=nasal-console|path=Nasal/console/repl.nas|line=708}}&lt;br /&gt;
&lt;br /&gt;
{{gitorious url|proj=fg|repo=philosophers-fgdata|branch=nasal-console|path=Nasal/console|view=tree}}&lt;br /&gt;
&lt;br /&gt;
{{fgdata-old url|commit=eaaf816b772649d5b0826a1d0bdd166dbc5b968f}}&lt;br /&gt;
&lt;br /&gt;
{{flightgear commit|34ed79e5f88ffdfc5e651a1fe3e639cb8f4d3353}}&lt;br /&gt;
&lt;br /&gt;
{{gitorious merge request|mr=54}}&lt;br /&gt;
&lt;br /&gt;
{{gitorious merge request|mr=26}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter February 2014]]&lt;br /&gt;
{{!}} https://gitorious.org/fg/philosophers-fgdata/source/022bef27f05d4837d720f63c6507b47466ff2a59:Nasal/console/repl.nas#L436&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/philosophers-fgdata/source/nasal-console:Nasal/console&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/fgdata/commit/eaaf816b772649d5b0826a1d0bdd166dbc5b968f&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/flightgear/commit/34ed79e5f88ffdfc5e651a1fe3e639cb8f4d3353&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/flightgear/commit/5eee5e42ae4f5cf56283b3bf5a3be46efc2b51c4&lt;br /&gt;
&lt;br /&gt;
https://www.gitorious.org/fg/flightgear/merge_requests/26&lt;br /&gt;
{{!}} Changes match the English article.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter April 2014]]&lt;br /&gt;
{{!}} https://gitorious.org/fg/fgdata/flightgear?p=fg/fgdata:flightgear.git;a=blob;f=keyboard.xml&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/fgdata?p=fg:fgdata.git;a=commit;h=f8c56dcc52ffd3d6dfca1d39dc4a72b6b3478368&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/hoorays-flightgear?p=fg:hoorays-flightgear.git;a=shortlog;h=refs/heads/topics/cppbind-fgprotocol&lt;br /&gt;
{{!}} This first link was the broken {{tl|git link}} template (see the table below).  The other two links are not in the article?!&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter June 2014]]&lt;br /&gt;
{{!}} https://gitorious.org/eddp-custom-scenery/eddp-custom-scenery/&lt;br /&gt;
{{!}} Switched to {{tl|gitorious clone}} to provide functional '''git clone''' instructions.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter November 2014]]&lt;br /&gt;
{{!}} https://gitorious.org/fg/hoorays-fgdata/source/2857d8fc9fcfe2bb162a9eb9d3dcca4d41b3a876:Nasal/ai/aim9/aim9.fdm#L9&lt;br /&gt;
{{!}} Switch to {{gitorious url|proj=fg|repo=hoorays-fgdata|commit=2857d8fc9fcfe2bb162a9eb9d3dcca4d41b3a876|path=Nasal/ai/aim9/aim9.fdm|line=9}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter January 2015]]&lt;br /&gt;
{{!}} https://gitorious.org/fg/canvas-hackers-fgdata/source/f59c42134a5a77e343981dcff8278c3e2f094e87&lt;br /&gt;
{{!}} Switch to {{gitorious url|proj=fg|repo=canvas-hackers-fgdata|commit=f59c42134a5a77e343981dcff8278c3e2f094e87|view=summary}}&lt;br /&gt;
{{!}}}&lt;br /&gt;
&lt;br /&gt;
Broken templates:...&lt;br /&gt;
{{{!}} class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Fixed !! Newsletter !! Template !! Notes&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter April 2014]]&lt;br /&gt;
{{!}} {{tlx|Git link|gitorious|fg/fgdata|master|keyboard.xml|pre=$FG_ROOT/}}&lt;br /&gt;
{{!}} Switched to {{fgdata source|path=keyboard.xml|pre=$FG_ROOT}} to fix the Gitorious link created by the broken and depreciated {{tl|git link}} template.&lt;br /&gt;
{{!}}}&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
::: —[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 12:06, 9 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:::: I've added a '''notes''' column to help a little.&lt;br /&gt;
&lt;br /&gt;
:::: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 12:30, 9 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
=== Elimination of the dead Gitorious links ===&lt;br /&gt;
Thanks largely to the diversity and flexibility of the [[:Category:Repository link templates|{{obr}}repo link{{cbr}} family of templates]], I have now managed to eliminate almost every last dead Gitorious link in the FlightGear wiki!  The locked Newsletter articles, user pages, and talk pages are the only exceptions.  The page counts from the (Main) namespace are:&lt;br /&gt;
* [http://wiki.flightgear.org/index.php?target=http%3A%2F%2Fgitorious.org&amp;amp;namespace=0&amp;amp;title=Special%3ALinkSearch &amp;lt;nowiki&amp;gt;Special:LinkSearch for http://gitorious.org&amp;lt;/nowiki&amp;gt;] &amp;amp;mdash; 37.  Of these, 17 are for the front page with the news of the Gitorious to SourceForge migration, and the rest are Newsletters.&lt;br /&gt;
* [http://wiki.flightgear.org/index.php?title=Special:LinkSearch&amp;amp;limit=500&amp;amp;offset=0&amp;amp;target=https%3A%2F%2Fgitorious.org&amp;amp;namespace=0 &amp;lt;nowiki&amp;gt;Special:LinkSearch for https://gitorious.org&amp;lt;/nowiki&amp;gt;] &amp;amp;mdash; 166.  Most of these links are valid and created by the {{obr}}gitorious *{{cbr}} subtemplates of {{tl|repo link}}.  The remaining broken links are all in the locked Newsletters.&lt;br /&gt;
The Howto:* pages are not in the (Main) wiki namespace, but I've knocked those out too.&lt;br /&gt;
&lt;br /&gt;
[[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 13:54, 10 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
: thanks for doing all this unglamorous work - I am sorry that Gijs was apparently too busy to follow up on my suggestion to either provide you with admin access around here, or at least to help you run a Python script to do all this work in an automated, rather than manual, fashion. Hopefully, things will work out better next time. Again, thank you. Like I said, I think you should definitely be given admin access on the wiki, especially given your recent contributions - and I would gladly have my wiki status downgraded accordingly. In fact, if I was able to directly promote accounts accordingly, I would have done so months ago - however, it seems that Gijs is the only one to have those privileges, and he mentioned off-list that he's kinda busy with RL/exams etc, so it is to be expected that he's going to become a bottleneck more often - hopefully, this will be recongized as an actual issue, so that there will be more people able to promote new wiki admins. Sorry that things didn't work out better this time, and thanks so much for doing all this stuff manually. -[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 14:49, 10 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: No problems!  As for automating this, that would not have been possible.  If you look at the changes, you'll see that each one is different &amp;lt;sup&amp;gt;[http://wiki.flightgear.org/index.php?title=Special:RecentChanges&amp;amp;to=20160310210655&amp;amp;limit=500]&amp;lt;/sup&amp;gt;.  I had to check each one, and update the link as required.&lt;br /&gt;
&lt;br /&gt;
:: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 16:08, 10 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
::: There's three of us actually (Curt, Simon and myself), no need to wait on me. See http://wiki.flightgear.org/index.php?title=Special%3AListUsers&amp;amp;username=&amp;amp;group=bureaucrat&amp;amp;limit=100 (Sek is inactive nowadays) ;-)&lt;br /&gt;
::: Please note that forum pms are really not the best way to contact me. I very much prefer email over forum pms as it's a lot easier to filter out the huge amounts of nonsense I'm receiving from stuff requiring actual attention.&lt;br /&gt;
::: Anyhow I've just  promoted Bugman so he can edit locked articles.&lt;br /&gt;
::: [[User:Gijs|Gijs]] ([[User talk:Gijs|talk]]) 05:06, 11 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:::: Thank you.  I'll try to preserve the original intent of the Newsletters while fixing the broken links (maybe even preserving any original URLs as Mediawiki link text, while pointing to the new URL).  I will use the {{obr}}gitorious *{{cbr}} templates to point to the historical sources, and will probably use this for all of the Gitorious URLs so that we have full control over any future URL breakages via the single location of {{tl|repo link}}.  For example, if they change the gitorious.org domain name to a https://archive.org subdomain (i.e. gitorious.archive.org).&lt;br /&gt;
&lt;br /&gt;
:::: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 06:40, 11 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
=== Regex parsing of template parameters? ===&lt;br /&gt;
&lt;br /&gt;
For the {{tl|repo link}} template, I am currently trying to work out what to do for git branches and tags on the SourceForge infrastructure.  The problem is that the presence of the character &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt; within a branch or tag name requires the text &amp;lt;code&amp;gt;/~&amp;lt;/code&amp;gt; to be appended to that name in the URL, for example:&lt;br /&gt;
&lt;br /&gt;
* Tag &amp;lt;code&amp;gt;version/2016.1.1&amp;lt;/code&amp;gt;:  https://sourceforge.net/p/flightgear/simgear/ci/version/2016.1.1/~/tree/simgear/ephemeris/ephemeris.cxx&lt;br /&gt;
* Branch &amp;lt;code&amp;gt;release/2016.1&amp;lt;/code&amp;gt;:  https://sourceforge.net/p/flightgear/simgear/ci/release/2016.1/~/tree/simgear/ephemeris/ephemeris.cxx&lt;br /&gt;
&lt;br /&gt;
I haven't found out a way to use regex to parse the &amp;lt;code&amp;gt;tag&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;branch&amp;lt;/code&amp;gt; template parameters to automate this, hence I am thinking of just giving the instruction for the template user to append this text to the &amp;lt;code&amp;gt;tag&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;branch&amp;lt;/code&amp;gt; parameter text themselves.  However this is not ideal - a change of this behaviour on the SourceForge side requires end pages with SourceForge URLs to be updated, rather than just updating {{tl|repo link}}.  I was wondering about possibility of installing the extension:&lt;br /&gt;
&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Extension:RegexParserFunctions Extension:RegexParserFunctions]&lt;br /&gt;
&lt;br /&gt;
Though I'm not 100% sure if that will work.  Or does someone else know an alternative?  Cheers!&lt;br /&gt;
&lt;br /&gt;
[[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 12:09, 22 April 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
: not a solution, just a potential workaround would be checking for the most common prefix strings used in tags/branches (e.g. version, release, topic, topics) and explicitly rewrite the URL accordingly to append the /~ suffix -[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 12:59, 22 April 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:: That might be a solution.  But I don't know how to do that without regex ;)  We really only have #ifeq statements, but that has to match the whole string.&lt;br /&gt;
&lt;br /&gt;
:: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 13:44, 22 April 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Discussion about quotes on the wiki ==&lt;br /&gt;
{{usr|Hooray}} have started a page now at [[FlightGear wiki:Quoting Guidelines]] ([http://wiki.flightgear.org/index.php?title=FlightGear_wiki:Quoting_Guidelines&amp;amp;oldid=96104 perm]) for a discussion regarding guidelines for the use of quotes on the wiki.  Join the discussion.&lt;br /&gt;
&lt;br /&gt;
—[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 18:17, 21 March 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In slight relation to this I have tried to make the wiki more consistently use the most common spelling and case, &amp;quot;Instant-Cquotes&amp;quot; and have changed the automatic categorization accordingly.  All articles using the {{tl|FGCquote}} template can now be found in [[:Category:Articles containing Instant-Cquotes]] (currently some ~250 articles).&lt;br /&gt;
&lt;br /&gt;
—[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 08:21, 23 March 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Reorganizing the Git articles ==&lt;br /&gt;
I've noticed that the [[Category:Git|Git articles]] suffer from duplication and are in part obsolete (especially with regard to the instructions for running Git on Windows). Thus, I propose the following reorganization:&lt;br /&gt;
* [[Development workflow]]: reorganization to explain how the patch submission process is organized from a high-level point of view (forking the repository from SourceForge, developing, pushing the commits to the personal fork, submitting a merge request/sending a patch to the mailing list);&lt;br /&gt;
* [[FlightGear Git]]: leave as is;&lt;br /&gt;
* '''Installing and configuring Git''' - new article about installing Git and configuring it (setting the username/e-mail address); merge the contents of [[FlightGear Git on Windows]] and [[Resources WRT running git on Win32]] here;&lt;br /&gt;
* [[FlightGear Git for laymen]] - make it follow [[FGW:MOS]], merge the contents of [[Howto:Start using git]] here;&lt;br /&gt;
* [[FlightGear Git: core developers]] and [[FlightGear Git: data developers]] - I'm uncertain about what I should do with them: the only piece information that would not be written in other articles is the list of alternative methods for cloning FGData;&lt;br /&gt;
* [[FlightGear Git: gitiquette]] and [[FlightGear Git: tips]] - make them follow [[FGW:MOS]].&lt;br /&gt;
Any comments? -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 06:11, 13 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
: This is sorely needed!  For [[FlightGear Git: core developers]] and [[FlightGear Git: data developers]], maybe these can be merged into something like [[FlightGear Git: working with the repositories]]?  The only real difference is the URL, but that is a minor difference with the [[:Category:Repository link templates]].  This could be generalised into a set of instructions for working with all git repositories for the core infrastructure, including forking and merge requests, with a current focus on the SourceForge web and non-web interfaces.&lt;br /&gt;
&lt;br /&gt;
: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 08:17, 13 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:: Yes, I was thinking about a similar solution as well. -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 10:16, 13 May 2016 (EDT)&lt;/div&gt;</summary>
		<author><name>Elgaton</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Mailing_lists&amp;diff=98172</id>
		<title>Mailing lists</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Mailing_lists&amp;diff=98172"/>
		<updated>2016-05-13T10:15:37Z</updated>

		<summary type="html">&lt;p&gt;Elgaton: /* How to subscribe to a mailing list */ Completed missing sentence&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Mailing lists''' are used for some of the FlightGear community's communications, in particular among the core developers who are working on the flight simulator itself.&lt;br /&gt;
&lt;br /&gt;
Some questions are better asked on the mailing list instead of the forum, especially those related to core development or project infrastructure, but you do not strictly have to be a core developer to subscribe and/or post to the mailing lists.&lt;br /&gt;
&lt;br /&gt;
== The mailing lists ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! List&lt;br /&gt;
! Contents&lt;br /&gt;
&amp;lt;!-- ! Status --&amp;gt;&lt;br /&gt;
! Archive&lt;br /&gt;
! Subscribe&lt;br /&gt;
! E-mail address&lt;br /&gt;
! Remarks&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
| rowspan=&amp;quot;1&amp;quot; style=&amp;quot;background: #33cf83; color: black; vertical-align: middle; text-align: center;&amp;quot; | Active&lt;br /&gt;
| rowspan=&amp;quot;1&amp;quot; style=&amp;quot;background: #ffe344; color: black; vertical-align: middle; text-align: center;&amp;quot; | Quiet&lt;br /&gt;
| rowspan=&amp;quot;1&amp;quot; style=&amp;quot;background: #ff6e67; color: black; vertical-align: middle; text-align: center;&amp;quot; | Inactive&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| flightgear-announce&lt;br /&gt;
| FlightGear announcements &lt;br /&gt;
| {{Mailing list archive|flightgear-announce}}&lt;br /&gt;
| {{Mailing list subscription link|flightgear-announce}}&lt;br /&gt;
| {{Mailing list e-mail address|flightgear-announce}}&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;1&amp;quot; style=&amp;quot;background: #ff6e67; color: black; vertical-align: middle;&amp;quot; | flightgear-bugs&lt;br /&gt;
| Bug tracker messages&lt;br /&gt;
| {{Mailing list archive|flightgear-bugs}}&lt;br /&gt;
| {{Mailing list subscription link|flightgear-bugs}}&lt;br /&gt;
| {{Mailing list e-mail address|flightgear-bugs}}&lt;br /&gt;
| Apparently dismissed&lt;br /&gt;
|-&lt;br /&gt;
| flightgear-builds&lt;br /&gt;
| Chatter from the FlightGear build servers &lt;br /&gt;
| {{Mailing list archive|flightgear-builds}}&lt;br /&gt;
| {{Mailing list subscription link|flightgear-builds}}&lt;br /&gt;
| {{Mailing list e-mail address|flightgear-builds}}&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| flightgear-commitlogs&lt;br /&gt;
| Source code change commit logs&lt;br /&gt;
| {{Mailing list archive|flightgear-commitlogs}}&lt;br /&gt;
| {{Mailing list subscription link|flightgear-commitlogs}}&lt;br /&gt;
| {{Mailing list e-mail address|flightgear-commitlogs}}&lt;br /&gt;
| As of May 2016, commit logs over 160 KB need to be approved manually by the list moderator; therefore, their delivery might be delayed.&amp;lt;ref&amp;gt;{{cite web |url=http://sourceforge.net/p/flightgear/mailman/message/33913347/&lt;br /&gt;
|title=&amp;lt;nowiki&amp;gt;Re: [Flightgear-devel] [Flightgear-commitlogs] [FGData] FlightGear data - next generation branch next updated. 7b595eca19e1bfb83ae330c02f2eeec5e9c9da58&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|author=&amp;lt;nowiki&amp;gt;Curtis Olson&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|date=&amp;lt;nowiki&amp;gt;2015-04-19&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
}}&amp;lt;/ref&amp;gt; In the future, bigger logs might not be sent anymore to the list in their entirety, to keep messages short and readable.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
|url=http://sourceforge.net/p/flightgear/mailman/message/33913630/&lt;br /&gt;
|title=&amp;lt;nowiki&amp;gt;Re: [Flightgear-devel] [Flightgear-commitlogs] [FGData] FlightGear data - next generation branch next updated. 7b595eca19e1bfb83ae330c02f2eeec5e9c9da58&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|author=&amp;lt;nowiki&amp;gt;Edward d'Auvergne&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|date=&amp;lt;nowiki&amp;gt;2015-04-19&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
}}&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;{{cite web |url=http://sourceforge.net/p/flightgear/mailman/message/33913846/&lt;br /&gt;
|title=&amp;lt;nowiki&amp;gt;Re: [Flightgear-devel] [Flightgear-commitlogs] [FGData] FlightGear data - next generation branch next updated. 7b595eca19e1bfb83ae330c02f2eeec5e9c9da58&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|author=&amp;lt;nowiki&amp;gt;Curtis Olson&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|date=&amp;lt;nowiki&amp;gt;2015-04-19&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;1&amp;quot; style=&amp;quot;background: #ff6e67; color: black; vertical-align: middle;&amp;quot; | flightgear-cvslogs&lt;br /&gt;
| CVS commit logs&lt;br /&gt;
| {{Mailing list archive|flightgear-cvslogs}}&lt;br /&gt;
| {{Mailing list subscription link|flightgear-cvslogs}}&lt;br /&gt;
| {{Mailing list e-mail address|flightgear-cvslogs}}&lt;br /&gt;
| Apparently dismissed&lt;br /&gt;
|-&lt;br /&gt;
| flightgear-devel&lt;br /&gt;
| FlightGear developer discussions&lt;br /&gt;
| {{Mailing list archive|flightgear-devel}}&lt;br /&gt;
| {{Mailing list subscription link|flightgear-devel}}&lt;br /&gt;
| {{Mailing list e-mail address|flightgear-devel}}&lt;br /&gt;
| Most active list&lt;br /&gt;
|-&lt;br /&gt;
| flightgear-fgaddon-commitlogs&lt;br /&gt;
| Commit logs for the [[FGAddon]] repository (content developers) &lt;br /&gt;
| {{Mailing list archive|flightgear-fgaddon-commitlogs}}&lt;br /&gt;
| {{Mailing list subscription link|flightgear-fgaddon-commitlogs}}&lt;br /&gt;
| {{Mailing list e-mail address|flightgear-fgaddon-commitlogs}}&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| flightgear-flightmodel&lt;br /&gt;
| Flight model discussions &lt;br /&gt;
| {{Mailing list archive|flightgear-flightmodel}}&lt;br /&gt;
| {{Mailing list subscription link|flightgear-flightmodel}}&lt;br /&gt;
| {{Mailing list e-mail address|flightgear-flightmodel}}&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| flightgear-newsletter&lt;br /&gt;
| [[FlightGear Newsletter|Newsletter]] announcements and discussions &lt;br /&gt;
| {{Mailing list archive|flightgear-newsletter}}&lt;br /&gt;
| {{Mailing list subscription link|flightgear-newsletter}}&lt;br /&gt;
| {{Mailing list e-mail address|flightgear-newsletter}}&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| flightgear-scenery&lt;br /&gt;
| Discussion of scenery development: code, tools, GIS data, models, etc. &lt;br /&gt;
| {{Mailing list archive|flightgear-scenery}}&lt;br /&gt;
| {{Mailing list subscription link|flightgear-scenery}}&lt;br /&gt;
| {{Mailing list e-mail address|flightgear-scenery}}&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| flightgear-users&lt;br /&gt;
| FlightGear user discussions&lt;br /&gt;
| {{Mailing list archive|flightgear-users}}&lt;br /&gt;
| {{Mailing list subscription link|flightgear-users}}&lt;br /&gt;
| {{Mailing list e-mail address|flightgear-users}}&lt;br /&gt;
| Mostly replaced by [http://forum.flightgear.org the forum]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== How to subscribe to a mailing list ==&lt;br /&gt;
To sign up for one of the above mailing lists, follow these steps:&lt;br /&gt;
&lt;br /&gt;
# Click a '''Subscribe''' link in the list above to get to the mailing list subscription form.&lt;br /&gt;
# Enter your e-mail address in the '''Your email address:''' box. You can optionally also:&lt;br /&gt;
#* give your name;&lt;br /&gt;
#* choose to receive e-mails ''batched in a daily digest'' (merged in a single message) or not;&lt;br /&gt;
#* choose a password you can use to edit your subscription options in the future. If you do not enter a password, one will be automatically generated for you.&lt;br /&gt;
{{warning|Do not use a valuable password as it will be occasionally sent to you via e-mail (this means that someone snooping on your messages might be able to get it).}}&lt;br /&gt;
&amp;lt;ol start=&amp;quot;3&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Click the {{button|Subscribe}} button.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;You will be sent a confirmation e-mail (usually it is delivered within ten seconds, but it can take up to a few minutes; if you do not see it, check your Spam folder). Click on the confirmation link in the message.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;SourceForge will display you a confirmation page where you can change some settings chosen in step 2. Click on {{button|Subscribe to list ''list name''}} to complete the process.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Posting to mailing lists ==&lt;br /&gt;
To protect list subscribers from spam, you are allowed to post there only after you have subscribed, and to send e-mails from the address you are subscribed with.&amp;lt;ref name=&amp;quot;MLPolicy&amp;quot;&amp;gt;{{cite web&lt;br /&gt;
|url    = https://forum.flightgear.org/viewtopic.php?p=244916&lt;br /&gt;
|title  = &amp;lt;nowiki&amp;gt;Re: Why is my post rejected from devel list?&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|author = &amp;lt;nowiki&amp;gt;curt&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|date   = May 31st, 2015&lt;br /&gt;
|added  = May 5th, 2016&lt;br /&gt;
|script_version = 0.32&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/ref&amp;gt; For the same reason, first posts are subject to moderator approval to catch the cases where people sign up for the sole purpose of posting spam.&amp;lt;ref name=&amp;quot;MLPolicy&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When posting to the lists, discuss your problem laying it out in as much detail you can and show that you are interested in the problem. If you are willing to work on it will also help, even if it is not related to coding itself. If your discussion is more than just asking for features to be added you have a better chance of getting help and you may find people there who can give you pointers on how to approach your problem. Also, be civil - avoid bringing conflicts or noise.&lt;br /&gt;
&lt;br /&gt;
Keep in mind that getting a response from the lists is usually slower than the forum and that responses may take several days. Should it take more than a week, you might want to probe the interest by responding to your own message; sometimes, there might be no reply as there is none.&lt;br /&gt;
&lt;br /&gt;
== Report bugs to the issue tracker ==&lt;br /&gt;
Bugs should preferably be {{create ticket|reported to the issue tracker}} instead of posting them to a mailing list.&lt;br /&gt;
&lt;br /&gt;
You may have to {{register to sf|register a SourceForge account}} first.&lt;br /&gt;
&lt;br /&gt;
== External links ==&lt;br /&gt;
* [http://www.flightgear.org/mail.html FlightGear mailing list details]&lt;br /&gt;
* [http://sourceforge.net/p/flightgear/mailman/ List of all project mailing lists on SourceForge]&lt;br /&gt;
&lt;br /&gt;
{{appendix}}&lt;br /&gt;
&lt;br /&gt;
[[Category:FlightGear]]&lt;br /&gt;
[[Category:Community]]&lt;/div&gt;</summary>
		<author><name>Elgaton</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=Talk:Mailing_lists&amp;diff=98171</id>
		<title>Talk:Mailing lists</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=Talk:Mailing_lists&amp;diff=98171"/>
		<updated>2016-05-13T10:14:40Z</updated>

		<summary type="html">&lt;p&gt;Elgaton: Moved additional info to main page as references&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Template for mailing list URLs ==&lt;br /&gt;
we should set up a template for the rows in the table, so that we can easily reuse/localize everything elsewhere (as per the git/repo link templates)&lt;br /&gt;
* address&lt;br /&gt;
* archives&lt;br /&gt;
* subscribe&lt;br /&gt;
* comments&lt;br /&gt;
* description (localized) &lt;br /&gt;
* status&lt;br /&gt;
&lt;br /&gt;
--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 10:58, 20 April 2015 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Bug reports on mailing lists? ==&lt;br /&gt;
Is not that bad advice?  Should not bug reports be redirected to the {{tickets|issue tracker}} in order to lessen unproductive/disruptive noise, in particular on the developer mailing list?&lt;br /&gt;
&lt;br /&gt;
—[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 16:50, 10 May 2015 (EDT)&lt;/div&gt;</summary>
		<author><name>Elgaton</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=FlightGear_wiki:Village_pump&amp;diff=98170</id>
		<title>FlightGear wiki:Village pump</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=FlightGear_wiki:Village_pump&amp;diff=98170"/>
		<updated>2016-05-13T10:11:59Z</updated>

		<summary type="html">&lt;p&gt;Elgaton: Git articles reorganization&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Archives|[[/Archive 2012|2012]]|[[/Archive 2013|2013]]|[[/Archive 2014|2014]]|[[/Archive 2015|2015]]}}&lt;br /&gt;
{{shortcut|FGW:VP}}&lt;br /&gt;
Welcome to the '''Village Pump'''. This page is used to discuss the technical issues, operations and guidelines of the [[FlightGear wiki]].&lt;br /&gt;
&lt;br /&gt;
Please &amp;lt;span class=&amp;quot;plainlinks&amp;quot;&amp;gt;[{{fullurl:{{FULLPAGENAME}}|action=edit&amp;amp;section=new}} add new topics]&amp;lt;/span&amp;gt; to the '''bottom''' of this page.&lt;br /&gt;
&lt;br /&gt;
Old discussion should be moved to a [[FlightGear wiki:Village pump/Archive YEAR]]. These discussions can then be moved to a relevant talk page if appropriate.&lt;br /&gt;
&lt;br /&gt;
== Welcome template? ==&lt;br /&gt;
I have been thinking about suggesting a welcome template, for example named {{obr}}welcome{{cbr}}, to place on top of (at least) new users user discussion pages.&lt;br /&gt;
&lt;br /&gt;
It should welcome the (new) user&lt;br /&gt;
&lt;br /&gt;
In addition, it should probably mention and/or link to pages mentioning:&lt;br /&gt;
* The introduction page/tutorial (Hmm, I do not think I did finish that one. See [[Help talk:Tutorial]] ([http://wiki.flightgear.org/index.php?title=Help_talk:Tutorial&amp;amp;oldid=70843 perm])).&lt;br /&gt;
* Help pages&lt;br /&gt;
* How to use categories (in particular not like #tags, ;-) but also that image and article categories should be separate, but link to each other)&lt;br /&gt;
* The portals&lt;br /&gt;
* The style manual&lt;br /&gt;
* Discussion pages and where to discuss what:&lt;br /&gt;
** How to use discussion pages&lt;br /&gt;
** The wiki in general:  The village pump (this page)&lt;br /&gt;
** Wiki articles:  Article discussion pages&lt;br /&gt;
** Wiki user actions:  User discussion pages&lt;br /&gt;
&lt;br /&gt;
Maybe it should also mention that FGAddon aircraft, effects, other features etc. (except for their articles) and their bugs should be discussed on the forum, unless developers say otherwise, and that core features should be discussed on the developer mailing list and core bugs on the bug tracker.&lt;br /&gt;
&lt;br /&gt;
—[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 20:31, 30 January 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
: I think this is a great idea.  A nice concise summary with links to help a new user navigate the FlightGear jungle would be a great addition.  It should however remain very short with simple sentences - while being complete - as many users are not native speakers.  So maybe there should be translations of the template with manually added links at the bottom for easy access to all the translations?&lt;br /&gt;
&lt;br /&gt;
: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 03:35, 12 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: Regarding an introduction article, I have come to the conclusion that a complete but long article is probably not as helpful as short but specific help pages.  In essence the latter would be easier to navigate and absorb.  I have therefore started to slowly split up some of the help pages and have added one more section to [[Help:Contents]].&lt;br /&gt;
:: I think that a welcome phrase, a link to that page and the [[FlightGear wiki:Manual of Style|style manual]] might actually suffice for a welcome template for now.  It is at least better than what we currently have (i.e. more or less nothing).&lt;br /&gt;
:: —[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 14:47, 4 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: I now consider&lt;br /&gt;
::* A Welcome message&lt;br /&gt;
::* A link to this page&lt;br /&gt;
::* A link to the help pages&lt;br /&gt;
::* A link to the manual of style&lt;br /&gt;
::* Some final welcoming words&lt;br /&gt;
&lt;br /&gt;
:: A welcome template should probably also very briefly mention a pet peeve of mine: the categories.&lt;br /&gt;
:: Many (if not most) image uploaders seem to treat them like tags, but if say all screenshots of aircraft (probably &amp;gt;2000) would end up at [[:Category:Aircraft]] (instead of under a subcategory to [[:Category:Screenshots of aircraft]]), of what use would that page be when looking for a specific one?  If people would like to be able to search for an aircraft, a concise but comprehensive image description is very hard to beat.&lt;br /&gt;
:: How do I convey all that in a way that is, short, to the point and easy to absorb (and act by)? And where is the best place?&lt;br /&gt;
:: —[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 02:46, 8 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: An early draft is now at [[User:Johan G/Template:Welcome to the wiki]]&lt;br /&gt;
:: —[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 02:52, 18 April 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
::: Some comments on the draft:&lt;br /&gt;
::: * I'm not fully sure about using a prominent box - I think it stands out a bit too much. Wikipedia {{wikipedia|Template:Welcome|uses a simple thread on the Talk page}}; as an alternative, we could use lighter colors.&lt;br /&gt;
::: * I've also expanded the text a bit. My proposal would be (I've put it in a box, but I'm for the &amp;quot;thread&amp;quot; solution):&lt;br /&gt;
&amp;lt;div style=&amp;quot;background: #fff; border: 1px #585858 solid; padding: 12px; margin: 12px&amp;quot;&amp;gt;&lt;br /&gt;
[[Image:Example.png|left]] '''Welcome to the FlightGear wiki, {{#if: {{{name|}}} | {{{name}}} | {{BASEPAGENAME}}}}'''! We hope you will enjoy your stay!&lt;br /&gt;
&lt;br /&gt;
See [[Help:Contents#Reading|Reading]] to learn how wikis work. You can also [[Special:CategoryTree/Root category|browse the existing page categories]].&lt;br /&gt;
&lt;br /&gt;
Should you wish to create or edit some articles, ''do so''! Here are some resources to get you started:&lt;br /&gt;
* [[Help:Contents#Editing|How to edit pages]]&lt;br /&gt;
* [[Help:Discussion pages|Discussion pages]], where we discuss and agree on potential improvements&lt;br /&gt;
* [[FlightGear wiki:Manual of Style|The Manual of Style]], a set of guidelines to help editors maintain a consistent style and formatting (please follow them)&lt;br /&gt;
* [[Help:Contents|Wiki help page]]&lt;br /&gt;
&lt;br /&gt;
If you have any questions, just start a topic on the [[FlightGear wiki:Village pump|''Discuss!'' page]]. Again, welcome!&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
::: ...where the image on the left is an appropriately chosen icon.&lt;br /&gt;
::: Finally, we could use the {{mediawiki|Extension:NewUserMessage|NewUserMessage extension}} to have the wiki software automatically post the message to the new user's talk page.&lt;br /&gt;
::: ---- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 17:30, 1 May 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Permanently removing spam bots ==&lt;br /&gt;
For permanently removing spam bots, has the [https://www.mediawiki.org/wiki/Extension:UserMerge UserMerge] Mediawiki extension been considered?  I use that regularly on [http://wiki.nmr-relax.com my own wiki], though there we have also reverted to communicating to the person via email before manually granting access (probably not an option here), as all of the Mediawiki captcha methods were recently cracked.&lt;br /&gt;
&lt;br /&gt;
[[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 03:15, 12 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
: Oh, for the extension, we simply have a user called 'Spam bot' in a blocked state, and merge the spam bot accounts into this one, deleting the old account.&lt;br /&gt;
: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 03:20, 12 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: I'd use the [https://www.mediawiki.org/wiki/Extension:AbuseFilter abuse filter extension] instead (much more powerful and automated) - other users have also proposed different remedies, see [http://forum.flightgear.org/viewtopic.php?f=42&amp;amp;t=28734 this forum thread]. Anyway, Gijs is going to upgrade MediaWiki shortly and review the current anti-spam measures.&lt;br /&gt;
:: -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 06:26, 13 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
::: A lot of the spam bots are using their name as advertising nowadays, so the [https://www.mediawiki.org/wiki/Extension:UserMerge UserMerge] extension is the only one I know which will allow a user and associated name to be permanently deleted.&lt;br /&gt;
&lt;br /&gt;
::: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 12:04, 14 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:::: The problem now is that they're also adding the information to the page title, so that it will still show up in the deletion logs [http://wiki.flightgear.org/Special:Log/delete] in other words, there's still some SEO juice associated with deleted entries ... Another idea would be to allow admins to temporarily disable wiki registrations/article creation, e.g. if more than 2 admins agree, this could be done to protect the wiki from spam attacks.&lt;br /&gt;
&lt;br /&gt;
::::: Hooray, you should sign your posts ;)  The bots don't target the deletion logs, as that's a little pointless.  It's a Special:* page, and the default Mediawiki robots.txt file tells all search engines to not index these pages.  User pages, page histories, etc. are however normally indexed.&lt;br /&gt;
&lt;br /&gt;
::::: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 14:36, 19 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: The point was not what the bots are targeting, but what shows up in the logs - i.e. SEO-wise - Gijs' article blacklist stuff should help with that hopefully. PS: I could not find the signature button on the mobile device I am using, and I am not too good at remembering the correct number of tildes ;-) [[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 15:04, 19 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
== WIP vs. Under construction ==&lt;br /&gt;
I have been beginning to miss the under construction template[http://wiki.flightgear.org/index.php?title=Template:Under_Construction&amp;amp;direction=prev&amp;amp;oldid=46229] more and more (though I could it definitively could be improved).&lt;br /&gt;
&lt;br /&gt;
I have begun to appreciate the need to differentiate between letting readers that a page is to be considered a yet to be finished construction site (though we in a way have that through the {{tl|incomplete}} template) and letting the reader (and other editors) that a page will receive a large amount of work for some hours or even days, usually the use for {{tl|WIP}}.&lt;br /&gt;
&lt;br /&gt;
In summary i miss templates giving a clear distinction between conditions akin to &amp;quot;Under construction&amp;quot; and &amp;quot;Caution - Wet floors&amp;quot;, rather than &amp;quot;being worked on&amp;quot; and &amp;quot;could need more work&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
—[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 10:11, 17 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
== [[Fr/Pilote automatique]] ==&lt;br /&gt;
Bonjour,&lt;br /&gt;
&lt;br /&gt;
Je viens de créer la page de traduction en français de l'article original en anglais [[Autopilot]]. Vu mes faibles compétences en matière de pilotage, vu que je n'ai pas sur ma version téléchargée d'avion avec un pilote automatique, la traduction doit souffrir quelques approximations, si ce n'est des contresens plus ennuyeux. Si quelques bonnes âmes plus qualifiées pouvaient me faire la grâce d'une relecture... merci d'avance.&lt;br /&gt;
&lt;br /&gt;
Cordialement, et Hop ! --[[User:F-WTSS|F-WTSS]] ([[User talk:F-WTSS|talk]]) 15:30, 18 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
== MediaWiki updated to 1.26.2 ==&lt;br /&gt;
I've updated MediaWiki to the latest stable release (1.26.2) today. I've still got to update some of the extensions, so there may be regressions for now. Please report bugs if you find any. For a list of changes, see https://www.mediawiki.org/wiki/Release_notes/1.26&lt;br /&gt;
&lt;br /&gt;
[[User:Gijs|Gijs]] ([[User talk:Gijs|talk]]) 10:47, 19 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
: Cheers!  I was hoping that it would solve the uneditable Chinese, Russian, and other non-latin character-based pages (Polish strangely as well), but unfortunately [[FlightGear_wiki:Village_pump/Archive_2015#UTF-8_language_pages_cannot_be_edited|that issue remains]].&lt;br /&gt;
&lt;br /&gt;
: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 10:54, 19 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: Hm, looks that will require quite some attention indeed. I'm afraid that'll has to wait for now.&lt;br /&gt;
:: [[User:Gijs|Gijs]] ([[User talk:Gijs|talk]]) 12:29, 19 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
=== Nasal Syntaxhighlighting ===&lt;br /&gt;
: Thanks for your efforts, btw: Nasal syntax highlighting is gone again.&lt;br /&gt;
: {{unsigned|17:22, 19 February 2016‎|Hooray}}&lt;br /&gt;
&lt;br /&gt;
:: Unfortunately this time it isn't me forgetting to copy a file. The SyntaxHighlight extension no longer uses GeSHi, but has switched to Pygments. This means our Nasal mapping no longer works and has to be re-written. If anyone is interested, be my guest. See http://pygments.org/docs/lexerdevelopment/&lt;br /&gt;
:: [[User:Gijs|Gijs]] ([[User talk:Gijs|talk]]) 12:29, 19 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
::: Hi Gijs,&lt;br /&gt;
::: I'm interested in making a Pygments Nasal lexer, but unfortunately I won't be able to work on it until the end of March at the earliest.&lt;br /&gt;
::: [[User:Red_Leader|&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;'''''Red Leader'''''&amp;lt;/span&amp;gt;]] ([[User_talk:Red_Leader|Talk]], [[Special:Contributions/Red_Leader|contribs]]) 16:59, 23 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:::: Unless Gijs is facing any problems, I don't think it's necessarily needed, see my comment/suggestion in this revision: [http://wiki.flightgear.org/index.php?title=FlightGear_wiki:Village_pump&amp;amp;oldid=93166] [[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 17:20, 23 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:::Hi Gijs,&lt;br /&gt;
:::Here's the code for a Nasal lexer. Be warned, it's thoroughly untested, but has the following features:&lt;br /&gt;
:::* Full support for all three string types (backtick, single quote, and double quote), including escapes and formatting strings (e.g., for {{func link|sprintf}}).&lt;br /&gt;
:::* All kinds of numbers, including numbers in scientific notation and octal and hex numbers.&lt;br /&gt;
:::* All global functions and variables as of FG v2016.1.1.&lt;br /&gt;
:::* Some of the commonly-used &amp;lt;code&amp;gt;props.Node&amp;lt;/code&amp;gt; methods.&lt;br /&gt;
:::* All the other things that can be expected (keywords, punctuation, etc.).&lt;br /&gt;
:::I have also created a lexer based on the XML lexer for XML with embedded Nasal, which I thought would be useful.&lt;br /&gt;
:::Regards,&lt;br /&gt;
:::[[User:Red_Leader|&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;'''''Red Leader'''''&amp;lt;/span&amp;gt;]] ([[User_talk:Red_Leader|Talk]], [[Special:Contributions/Red_Leader|contribs]]) 16:35, 2 April 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:::http://pygments.org/docs/lexerdevelopment/#adding-and-testing-a-new-lexer&lt;br /&gt;
:::&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
	Lexer for Nasal.&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
from pygments.lexer import RegexLexer, words, include, inherit, bygroups, using&lt;br /&gt;
from pygments.token import Text, Keyword, Name, String, Number, Operator, Punctuation, Comment&lt;br /&gt;
from pygments.lexers.html import XmlLexer&lt;br /&gt;
&lt;br /&gt;
__all__ = ['NasalLexer', 'XMLNasalLexer']&lt;br /&gt;
&lt;br /&gt;
class NasalLexer(RegexLexer):&lt;br /&gt;
&lt;br /&gt;
	name = 'Nasal'&lt;br /&gt;
	aliases = ['nasal']&lt;br /&gt;
	filenames = ['*.nas']&lt;br /&gt;
&lt;br /&gt;
	tokens = {&lt;br /&gt;
		'formatters': [&lt;br /&gt;
			(r'%[-#0 +]*(?:[0-9]+)?(?:\.[0-9]+)?[dis%couxXeEfFgG]', String.Interpol),&lt;br /&gt;
		],&lt;br /&gt;
		'backtick': [&lt;br /&gt;
			(r'`', String.Backtick, '#pop'),&lt;br /&gt;
			(r'[^`\\]+', String.Backtick),&lt;br /&gt;
			(r'\\n|\\r|\\t|\\`|\\\\|\\x[0-9a-fA-F]{2}', String.Escape),&lt;br /&gt;
		],&lt;br /&gt;
		'sqstring': [&lt;br /&gt;
			(r&amp;quot;'&amp;quot;, String.Single, '#pop'),&lt;br /&gt;
			(r&amp;quot;[^'\\%]+&amp;quot;, String.Single),&lt;br /&gt;
			(r&amp;quot;\\'&amp;quot;, String.Escape),&lt;br /&gt;
			include('formatters'),&lt;br /&gt;
		],&lt;br /&gt;
		'dqstring': [&lt;br /&gt;
			(r'&amp;quot;', String.Double, '#pop'),&lt;br /&gt;
			(r'[^&amp;quot;\\%]+', String.Double),&lt;br /&gt;
			(r'\\n|\\r|\\t|\\&amp;quot;|\\\\|\\x[0-9a-fA-F]{2}', String.Escape),&lt;br /&gt;
			include('formatters'),&lt;br /&gt;
		],&lt;br /&gt;
		'root': [&lt;br /&gt;
			(r'\s+', Text),&lt;br /&gt;
			(r'#.*?$'m, Comment.Single),&lt;br /&gt;
			(r':|\?|[!=&amp;lt;&amp;gt;+\-*\/~&amp;amp;|^]=?', Operator),&lt;br /&gt;
			(words(('or', 'and'), suffix=r'\b'), Operator.Word),&lt;br /&gt;
			(r'[{(\[})\]\.;,]', Punctuation),&lt;br /&gt;
			(words(('for', 'foreach', 'forindex', 'while', 'break', 'return', 'continue', 'if', 'else', 'elsif'), suffix=r'\b'), Keyword),&lt;br /&gt;
			(words(('var', 'func'), suffix=r'\b'), Keyword.Declaration),&lt;br /&gt;
			(words(('nil'), suffix=r'\b'), Keyword.Constant),&lt;br /&gt;
			(words(('me', 'arg'), suffix=r'\b'), Name.Builtin.Pseudo),&lt;br /&gt;
			(words(('new', 'del', 'getNode', 'getParent', 'getChild', 'getChildren', 'removeChild', 'removeChildren', 'removeAllChildren', 'getName', 'getIndex', 'getType', 'getAttribute', 'setAttribute', 'getValue', 'setValue', 'setIntValue', 'setBoolValue', 'setDoubleValue', 'unalias', 'alias', 'getPath', 'getBoolValue', 'remove', 'setValues', 'getValues', 'initNode'), suffix=r'\b'), Keyword.Pseudo),&lt;br /&gt;
			(r'0o[0-7]+', Number.Oct),&lt;br /&gt;
			(r'0x[0-9a-fA-F]+', Number.Hex),&lt;br /&gt;
			(r'\d*(?:\.\d*)?[eE][+-]?\d+', Number.Float),&lt;br /&gt;
			(r'\d*\.\d*', Number.Float),&lt;br /&gt;
			(r'\b[0-9]+\b', Number.Integer),&lt;br /&gt;
			(words(('D2R', 'R2D', 'FT2M', 'M2FT', 'IN2M', 'M2IN', 'NM2M', 'M2NM', 'KT2MPS', 'MPS2KT', 'FPS2KT', 'KT2FPS', 'LB2KG', 'KG2LB', 'GAL2L', 'L2GAL'), suffix=r'\b'), Name.Variable.Global),&lt;br /&gt;
			(words(('abort', 'abs', 'addcommand', 'airportinfo', 'airwaysRoute', 'assert', 'carttogeod', 'cmdarg', 'courseAndDistance', 'createViaTo', 'createDiscontinuity', 'createWP', 'createWPFrom', 'defined', 'directory', 'fgcommand', 'findAirportsByICAO', 'findAirportsWithinRange', 'findFixesByID', 'findNavaidByFrequency', 'findNavaidsByFrequency', 'findNavaidsByID', 'findNavaidsWithinRange', 'finddata', 'flightplan', 'geodinfo', 'geodtocart', 'getprop', 'greatCircleMove', 'interpolate', 'isa', 'logprint', 'magvar', 'maketimer', 'md5', 'navinfo', 'parse_markdown', 'parsexml', 'print', 'printf', 'printlog', 'rand', 'registerFlightPlanDelegate', 'removecommand', 'removelistener', 'resolvepath', 'setlistener', 'setprop', 'settimer', 'srand', 'systime', 'thisfunc', 'tileIndex', 'tilePath', 'values'), suffix=r'\b'), Name.Builtin),&lt;br /&gt;
			(words(('append', 'bind', 'call', 'caller', 'chr', 'closure', 'cmp', 'compile', 'contains', 'delete', 'die', 'find', 'ghosttype', 'id', 'int', 'keys', 'left', 'num', 'pop', 'right', 'setsize', 'size', 'sort', 'split', 'sprintf', 'streq', 'substr', 'subvec', 'typeof'), suffix=r'\b'), Name.Builtin),&lt;br /&gt;
			(words(('_createCondition', '_fgcommand', '_interpolate', '_setlistener'), suffix=r'\b'), Keyword.Reserved),&lt;br /&gt;
			(r'`', String.Backtick, 'backtick'),&lt;br /&gt;
			(r&amp;quot;'&amp;quot;, String.Single, 'sqstring'),&lt;br /&gt;
			(r'&amp;quot;', String.Double 'dqstring'),&lt;br /&gt;
			(r'\b_\w*?\b', Keyword.Reserved),&lt;br /&gt;
			#(r'\b\w*?\b', Name),&lt;br /&gt;
		]&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
class XMLNasalLexer(XmlLexer):&lt;br /&gt;
	&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
	For Nasal code embedded in XML files.&lt;br /&gt;
	&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	name = 'XML-Nasal'&lt;br /&gt;
	aliases = ['xml-nasal', 'xml-ns']&lt;br /&gt;
&lt;br /&gt;
	tokens = {&lt;br /&gt;
		'root': [&lt;br /&gt;
			(r'(&amp;lt;(?:load|unload|script)&amp;gt;)(&amp;lt;!\[CDATA\[)?(.*?)(]]&amp;gt;)?(&amp;lt;/(?:load|unload|script)&amp;gt;)', bygroups(Name.Tag, Comment.Preproc, using(NasalLexer), Comment.Preproc, Name.Tag),&lt;br /&gt;
			inherit,&lt;br /&gt;
		],&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:: We can use the ECMAScript/JavaScript lexer[http://pygments.org/docs/lexers/#lexers-for-javascript-and-related-languages] for now, my suggestion would be to copy that over to a file so that we can work on a custom Nasal lexer (Syntax  is almost identical, with a few different keywords, and many others being irrelevant). What is missing/different can be obtained from other lexers that are similar, e.g. [http://pygments.org/docs/lexers/#lexers-for-other-c-like-languages] [[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 15:45, 19 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: Okay, here's the better/quick&amp;amp;easy way: We have Nasal support for some fairly popular editors, like [http://wiki.flightgear.org/Howto:Syntax_highlighting_for_Nasal#Vim|vim](originally created by Melchior&amp;lt;ref&amp;gt;https://sourceforge.net/p/flightgear/flightgear/ci/next/tree/scripts/syntax/nasal.vim&amp;lt;/ref&amp;gt;), listed at [[Howto:Syntax_highlighting_for_Nasal]] - there are various free converters available that will read such a syntaxhighlighting file and convert it to a pygments class, e.g. see: https://github.com/honza/vim2pygments [[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 16:00, 19 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
==== References ====&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== The repository link templates ==&lt;br /&gt;
=== Complete overhaul of the repository link templates ===&lt;br /&gt;
&lt;br /&gt;
I have now performed a complete overhaul of the repository link templates (see {{tl|repo link/doc related}}).  This was motivated by the incomplete state of these templates, the lack of standardisation, the lack of SourceForge git repository support for {{tl|repo link}}, web-interface only support, etc.  I have used a lot of recursive transclusion for standardisation, so that there is a single point for updating for any FlightGear infrastructure changes.  This is the master {{tl|repo link}} template.  All the other templates are subtemplates which recursively transclude from this master template.  I have also created a number of documentation templates for simplifying template maintenance (see {{tl|repo link/doc related‎}}, {{tl|repo link/doc specific file git‎‎}}, {{tl|repo link/doc git clone‎‎}}, and {{tl|repo link/doc commit}}).  The changes were constrained to maintain backwards compatibility as much as possible.  However I would like to break this to allow the following templates to be updated to transclude from the master {{tl|repo link}} template:&lt;br /&gt;
&lt;br /&gt;
* {{tl|flightgear file}},&lt;br /&gt;
* {{tl|simgear file}},&lt;br /&gt;
* {{tl|fgdata file}},&lt;br /&gt;
* {{tl|fgaddon file}}.&lt;br /&gt;
&lt;br /&gt;
If no one objects, I would like to completely break these and expand and rename the parameter set to match the other &amp;lt;nowiki&amp;gt;{{* file}}&amp;lt;/nowiki&amp;gt; repository templates (e.g. {{tl|terragear file}}).  My overhaul currently does not include Hooray's ideas for non command line usages, i.e. different GUIs, but it enables it to be easily added via the master template and the addition of a single parameter to any subtemplates.&lt;br /&gt;
&lt;br /&gt;
[[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 15:05, 25 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
: I don't have any objections myself, I appreciate all the work you are putting into this, and would like to thank you for helping us clean up all that mess by doing such unglamorous work ;-) I also appreciate that your changes would facilitate adding a non-CLI mode to the corresponding templates. However, I would suggest to wait for Gijs' feedback, because he's ultimately the most likely person to veto something around here ;-) [[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 17:31, 25 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: Johan seems to be the one who did a lot of the initial work on these &amp;lt;nowiki&amp;gt;{{* file}}&amp;lt;/nowiki&amp;gt; templates, and Red Leader with the {{tl|repo link}} template.  And they were involved in the general discussions ([[http://wiki.flightgear.org/index.php?title=FlightGear_wiki:Village_pump&amp;amp;oldid=87148#Repository_link_templates perm]).  But I know Gijs was also involved in the design.&lt;br /&gt;
&lt;br /&gt;
:: For the non-CLI mode, that will need -a lot- more planning.  For example a definitive list of all these modes would be useful.  Should this use an optional Mediawiki pop up extension showing a link to a general page that describes the action for all different GUIs, CLI, etc.?  Should we have a switch box so that the reader can switch in-text between CLI, and the numerous GUIs?  Are we going to have a large set of screenshots for each GUI?  If so, I would strongly recommend the [https://www.mediawiki.org/wiki/Extension:Labeled_Section_Transclusion labelled section transclusion extension] for creating a single page for one GUI with everything for that GUI, as a tutorial.  Here is [http://wiki.nmr-relax.com/Relax_4.0.1 an external example where I have used this], to fragment the base release page to create [http://wiki.nmr-relax.com/Relax_release_descriptions this meta page], as well as many other meta pages.&lt;br /&gt;
&lt;br /&gt;
:: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 03:14, 26 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
I am also thinking of changing the name of the &amp;lt;nowiki&amp;gt;{{* file}}&amp;lt;/nowiki&amp;gt; templates, as I hope to make the scope of the templates far more general.  The name &amp;lt;nowiki&amp;gt;{{* source}}&amp;lt;/nowiki&amp;gt; or &amp;lt;nowiki&amp;gt;{{* repo}}&amp;lt;/nowiki&amp;gt; might be better.  For example these will allow the repository commit, tree view, log view (and maybe rss feed), with or without a file/directory path.  And I would like to generalise this to handle both the SF web-interface and non-web net protocols (git://, ssh://, svn://, etc.).  It will allow for CLI instructions to be built up and embedded in &amp;lt;nowiki&amp;gt;{{#tag:source|&amp;lt;content&amp;gt;|lang=sh}}&amp;lt;/nowiki&amp;gt; tags.  And I will defer all infrastructure decisions in the subtemplates to the single point of {{tl|project infrastructure}}, so that if there are changes in the future, then only this single template needs to be updated to update the entire wiki.&lt;br /&gt;
&lt;br /&gt;
[[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 03:22, 26 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
: The {{tl|project infrastructure}} template as a single point provider of various project infrastructure names and URL pairs seem like a great idea.  If it work out well it will really lessen the maintenance by having less places needing updates, while allowing the various repository templates to be simple to use, in essence by having comprehensible names and no boiler plate parameters for their users.&lt;br /&gt;
: —[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 15:15, 27 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
==== Repository link update ====&lt;br /&gt;
For those following, I have massively expanded the capabilities of the {{tl|repo link}} template:&lt;br /&gt;
* The SourceForge URLs are now comprehensive.&lt;br /&gt;
* Full support for the new query-based URLs for the Gitorious archives.&lt;br /&gt;
* Functional GitLab URLs.&lt;br /&gt;
* Generic repository support (used to create the {{tl|openscenegraph co}} template).&lt;br /&gt;
* Detailed documentation and extensive examples for checking the implementation (if you find any non-supported links, please add these as examples).&lt;br /&gt;
* Isolation of the '''cmd''' parameter from the CLI options &amp;amp;mdash; this is to enable future support for non-CLI instructions based on the value of '''cmd'''.&lt;br /&gt;
&lt;br /&gt;
I have also completed a large set of subtemplates of {{tl|repo link}}, see the list at {{tl|repo link/doc related}}.  This includes a full set of &amp;lt;nowiki&amp;gt;{{* source}}&amp;lt;/nowiki&amp;gt; templates.  I have left the original &amp;lt;nowiki&amp;gt;{{* file}}&amp;lt;/nowiki&amp;gt; templates, rather than renaming and modifying them, so these are now redundant.  All of the &amp;lt;nowiki&amp;gt;{{* source}}&amp;lt;/nowiki&amp;gt;, &amp;lt;nowiki&amp;gt;{{* commit}}&amp;lt;/nowiki&amp;gt;, &amp;lt;nowiki&amp;gt;{{* clone}}&amp;lt;/nowiki&amp;gt;, and &amp;lt;nowiki&amp;gt;{{* co}}&amp;lt;/nowiki&amp;gt; templates transclude from the master {{tl|repo link}} template to do all of the work.&lt;br /&gt;
&lt;br /&gt;
One important template is {{tl|gitorious source}}.  The support for the new query-based URLs for the Gitorious archives is now quite comprehensive in {{tl|repo link}}.  Therefore I have converted almost every single FlightGear wiki link to https://gitorious.org to use {{tl|gitorious source}} instead.  This fixes a lot of broken links and broken git instructions.  I have reduced the number of hits for gitorious.org on the wiki (searching just for &amp;quot;gitorious&amp;quot;) to 22 hits.  This includes 2 very outdated articles ([[FlightGear Git: aircraft authors]], [[Fr/FlightGear et Git]]), 15 locked newsletters, 1 with no longer existent Gitorious merge request links, and 4 base URL links for Hangars.  This way we can maintain the Gitorious web interface links and git command instructions in a functional state by simply updating the single source of {{tl|repo link}}.&lt;br /&gt;
&lt;br /&gt;
[[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 11:38, 29 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
: I just remembered [[Special:LinkSearch]], so make that 184 broken gitorious.org links remaining.  Lots more work to do :)&lt;br /&gt;
&lt;br /&gt;
: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 14:46, 29 February 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
For some of these templates, e.g. {{tl|repo link/doc usage}}, I'm trying to implement some logic for automatic whitespace padding for documentation formatting, but the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;{{#len:string}}&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; function is not enabled.  According to {{mediawiki|Wikitext_parser/Core_parser_functions#.23len}} and {{mediawiki|Extension:StringFunctions}}, the option &amp;lt;code&amp;gt;$wgPFEnableStringFunctions = true;&amp;lt;/code&amp;gt; should be set (in &amp;lt;code&amp;gt;LocalSettings.php&amp;lt;/code&amp;gt;).  Unless there is a reason for not using this, I was wondering if someone could enable this?  Cheers!&lt;br /&gt;
&lt;br /&gt;
[[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 09:53, 8 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
=== Archived newsletters and dead links? ===&lt;br /&gt;
&lt;br /&gt;
Do we have a policy for the dead links in the FlightGear newsletters?  It is obviously good to preserve the historic state.  But there are many Gitorious links that could be made functional again using the {{tl|gitorious source}} template to point to the historic Gitorious archives (including the official FlightGear repositories, rather than using {{tl|fgdata source}}, for example).  The https://gitorious.org links have been converted from URL/path based to query based, so absolutely all of the old links are broken.  I am steadily converting all Gitorious links to use the [[Template:repo link/doc related|{{obr}}repo link{{cbr}} family of templates]], with the exception of the newsletters.&lt;br /&gt;
&lt;br /&gt;
[[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 04:52, 8 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
: I think it could be a good idea to try update old links in those newsletters.  I sometimes look back at things and tend to think that I probably are not the only one doing that.&lt;br /&gt;
: I wonder if the rotten links should be replaced or stricken, but I think they could just as well be replaced.  The key thing is that they go to the same resource or content, not weather they have been updated or not (also, the change will be visible in the revision history after all).&lt;br /&gt;
: —[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 07:11, 8 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: I should add that I'm using [http://wiki.flightgear.org/index.php?title=Special:LinkSearch&amp;amp;limit=500&amp;amp;offset=0&amp;amp;target=http%3A%2F%2Fgitorious.org &amp;lt;nowiki&amp;gt;Special:LinkSearch for http://gitorious.org&amp;lt;/nowiki&amp;gt;] and [http://wiki.flightgear.org/index.php?title=Special:LinkSearch&amp;amp;limit=500&amp;amp;offset=0&amp;amp;target=https%3A%2F%2Fgitorious.org &amp;lt;nowiki&amp;gt;Special:LinkSearch for https://gitorious.org&amp;lt;/nowiki&amp;gt;].  And I am also not touching the &amp;lt;code&amp;gt;User*&amp;lt;/code&amp;gt; pages, &amp;lt;code&amp;gt;*talk*&amp;lt;/code&amp;gt; pages, or pages tagged as out of date or up for deletion.  For the newsletters I might look at these later when the broken Gitorious links are fixed in the rest of the wiki but, as these are locked, someone else might have make the switch to {{tl|gitorious source}}, {{tl|gitorious url}}, {{tl|gitorious clone}}, and {{tl|gitorious merge request}}.&lt;br /&gt;
&lt;br /&gt;
:: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 02:53, 9 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
::: I will temporarily add a table here for the templates in the newsletters and will slowly fix them one by one together with any other admin.&lt;br /&gt;
{{navbox&lt;br /&gt;
| title = Click &amp;quot;show&amp;quot; to show --&amp;gt;&lt;br /&gt;
| state = collapsed&lt;br /&gt;
| navbar = plain&lt;br /&gt;
| list1 =&lt;br /&gt;
http:...&lt;br /&gt;
{{{!}} class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Fixed !! Newsletter !! Gitorious URL !! Notes&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter May 2010]]&lt;br /&gt;
{{!}} http://gitorious.org/fg&lt;br /&gt;
{{!}} No equivalent link for the Gitorious archive - project pages are dead.  Maybe just use http://gitorious.org/?&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter May 2010]]&lt;br /&gt;
{{!}} http://gitorious.org/fg&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter September 2010]]&lt;br /&gt;
{{!}} http://gitorious.org/fg/flightgear/commit/5c6fe952598053fa63631fc0161d666f22a50f51&lt;br /&gt;
{{!}} Functional link, equivalent to {{gitorious url|fg|flightgear|commit=5c6fe952598053fa63631fc0161d666f22a50f51}}.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter September 2010]]&lt;br /&gt;
{{!}} http://gitorious.org/fg/flightgear/commit/5c6fe952598053fa63631fc0161d666f22a50f51&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter January 2011]]&lt;br /&gt;
{{!}} http://gitorious.org/jsbsim/jsbsim&lt;br /&gt;
{{!}} Functional link.  Switched to {{gitorious url|jsbsim|jsbsim}} to future-protect the link.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter January 2011]]&lt;br /&gt;
{{!}} http://gitorious.org/jsbsim/jsbsim&lt;br /&gt;
{{!}} Functional link.  Switched to {{gitorious url|jsbsim|jsbsim}} to future-protect the link.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter February 2011]]&lt;br /&gt;
{{!}} http://gitorious.org/headtrack&lt;br /&gt;
&lt;br /&gt;
http://gitorious.org/arduinocockpit&lt;br /&gt;
{{!}} Project pages are dead, switched to {{gitorious url|headtrack|headtrack}}&lt;br /&gt;
&lt;br /&gt;
{{gitorious url|arduinocockpit|arduinocockpit}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter February 2011]]&lt;br /&gt;
{{!}} http://gitorious.org/arduinocockpi&lt;br /&gt;
&lt;br /&gt;
http://gitorious.org/headtrack&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter March 2011]]&lt;br /&gt;
{{!}} http://gitorious.org/lockheed-l10-electra&lt;br /&gt;
{{!}} Missing project - i.e. {{gitlab source|user=emilianh|repo=Lockheed-L10-Electra|text=migrated to GitLab}}.  Switched to {{gitlab source|user=emilianh|repo=Lockheed-L10-Electra}}.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter March 2011]]&lt;br /&gt;
{{!}} http://gitorious.org/lockheed-l10-electra&lt;br /&gt;
{{!}} Switched to {{gitlab source|user=emilianh|repo=Lockheed-L10-Electra}}.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter November 2011]]&lt;br /&gt;
{{!}} http://gitorious.org/flightgear-aircraft&lt;br /&gt;
{{!}} Switched to {{gitorious source}} and rephrased text slightly to help readers find the repositories.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter October 2012]]&lt;br /&gt;
{{!}} http://gitorious.org/anders-hangar/mtb_20m/trees/master&lt;br /&gt;
{{!}} Switch to {{gitorious url|proj=anders-hangar|repo=mtb_20m}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter March 2013]]&lt;br /&gt;
{{!}} http://gitorious.org/fg/flightgear/blobs/next/scripts/java/FGClient/src/FGFSDemo.java&lt;br /&gt;
{{!}} Switched to {{gitorious url|proj=fg|repo=flightgear|path=scripts/java/FGClient/src/FGFSDemo.java}}.  This points to the old Gitorious repository to protect against path changes in the future.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter September 2013]]&lt;br /&gt;
{{!}} http://gitorious.org/boeing/707&lt;br /&gt;
{{!}} Switched to {{gitorious source|proj=boeing|repo=707}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter September 2013]]&lt;br /&gt;
{{!}} http://gitorious.org/boeing/707&lt;br /&gt;
{{!}} Switched to {{gitorious source|proj=boeing|repo=707}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter November 2013]]&lt;br /&gt;
{{!}} http://gitorious.org/fg/fgrun&lt;br /&gt;
{{!}} Switch to {{gitorious url|proj=fg|repo=fgrun}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter November 2013]]&lt;br /&gt;
{{!}} http://gitorious.org/fg/fgrun&lt;br /&gt;
{{!}} Switch to {{gitorious url|proj=fg|repo=fgrun}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter July 2014]]&lt;br /&gt;
{{!}} http://gitorious.org/nasal-support/nasal-npp&lt;br /&gt;
{{!}} Switched to {{gitorious url|nasal-support|nasal-npp}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter April 2015]]&lt;br /&gt;
{{!}} http://gitorious.org&lt;br /&gt;
{{!}} Switched to {{tl|gitorious source}} without parameters for the Gitorious base URL, to future-protect it.&lt;br /&gt;
{{!}}}&lt;br /&gt;
&lt;br /&gt;
https:...&lt;br /&gt;
{{{!}} class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Fixed !! Newsletter !! Gitorious URL !! Notes&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter April 2011]]&lt;br /&gt;
{{!}} https://gitorious.org/papillon81/flightgear-custom-scenery/&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/dvanmosselbeen/flightgear-custom-scenery&lt;br /&gt;
{{!}} Switched to {{gitorious source|dvanmosselbeen|flightgear-custom-scenery}} and {{gitorious source|papillon81|flightgear-custom-scenery}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter April 2011]]&lt;br /&gt;
{{!}} https://gitorious.org/dvanmosselbeen/flightgear-custom-scenery&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/papillon81/flightgear-custom-scenery/&lt;br /&gt;
{{!}} Switched to {{gitorious source|dvanmosselbeen|flightgear-custom-scenery}} and {{gitorious source|papillon81|flightgear-custom-scenery}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter July 2011]]&lt;br /&gt;
{{!}} https://gitorious.org/dvanmosselbeen/flightgear-custom-scenery&lt;br /&gt;
{{!}} Switched to {{gitorious source|dvanmosselbeen|flightgear-custom-scenery}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter July 2011]]&lt;br /&gt;
{{!}} https://gitorious.org/dvanmosselbeen/flightgear-custom-scenery&lt;br /&gt;
{{!}} Switched to {{gitorious source|dvanmosselbeen|flightgear-custom-scenery}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter December 2011]]&lt;br /&gt;
{{!}} https://gitorious.org/dvanmosselbeen/flightgear-custom-scenery&lt;br /&gt;
{{!}} Switched to {{gitorious source|dvanmosselbeen|flightgear-custom-scenery}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Fr/Nouvelles du projet FlightGear - décembre 2011]]&lt;br /&gt;
{{!}} https://gitorious.org/dvanmosselbeen/flightgear-custom-scenery&lt;br /&gt;
{{!}} Switched to {{gitorious source|dvanmosselbeen|flightgear-custom-scenery}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter April 2012]]&lt;br /&gt;
{{!}} https://gitorious.org/fg/fgdata/blobs/master/Aircraft/Instruments-3d/garmin196/README&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/fgdata/blobs/master/Aircraft/Instruments-3d/garmin196/doc/doc-en.htm&lt;br /&gt;
{{!}} Switched to {{fgdata source|path=Aircraft/Instruments-3d/garmin196/README|full=1}} and {{fgdata source|path=Aircraft/Instruments-3d/garmin196/doc/doc-en.htm|full=1}} to point to the current FGData locations and removed the name &amp;quot;Gitorious&amp;quot; to make the text of the Garmin 196 GPS section still relevant&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter August 2012]]&lt;br /&gt;
{{!}} https://gitorious.org/mil-mi-6&lt;br /&gt;
{{!}} Switched to {{gitorious url|proj=mil-mi-6|repo=mi6dev}}, and changed from the non-existent project page to the main repository.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter October 2012]]&lt;br /&gt;
{{!}} https://gitorious.org/fgradar&lt;br /&gt;
{{!}} Switched from the project page to the direct repository {{gitorious url|fgradar|fgradar}}.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter March 2013]]&lt;br /&gt;
{{!}} https://gitorious.org/fg/flightgear/commit/913727239d6776c0508d206f395e16c265413ec3&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/flightgear/commit/eba03b5e469824ee8f1494723fcddbbc56155a08&lt;br /&gt;
{{!}} Switched to {{flightgear url|commit=913727239d6776c0508d206f395e16c265413ec3}} and {{flightgear url|commit=eba03b5e469824ee8f1494723fcddbbc56155a08}}.  This deliberately points to the current repository.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter April 2013]]&lt;br /&gt;
{{!}} https://gitorious.org/fg-radi/osm2city&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/scenery-france-850&lt;br /&gt;
{{!}} Switched to the new GitLab repository {{gitlab source|proj=fg-radi|repo=osm2city|full=1}}&lt;br /&gt;
&lt;br /&gt;
and removed the no longer existent scenery-france-850 repository, replacing it with &amp;quot;&amp;lt;s&amp;gt;Scenery repository (Gitorious)&amp;lt;/s&amp;gt;&amp;quot;.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter October 2013]]&lt;br /&gt;
{{!}} https://gitorious.org/fg/galvedros-fgdata&lt;br /&gt;
{{!}} Switch to {{gitorious url|proj=fg|repo=galvedros-fgdata}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter October 2013]]&lt;br /&gt;
{{!}} https://gitorious.org/fg/galvedros-fgdata&lt;br /&gt;
{{!}} Switch to {{gitorious url|proj=fg|repo=galvedros-fgdata}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter November 2013]]&lt;br /&gt;
{{!}} https://gitorious.org/ec130/&lt;br /&gt;
{{!}} Switched from the project page to the direct repository {{gitorious source|ec130|ec130}}.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter November 2013]]&lt;br /&gt;
{{!}} https://gitorious.org/ec130/&lt;br /&gt;
{{!}} Switched from the project page to the direct repository {{gitorious source|ec130|ec130}}.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter February 2014]]&lt;br /&gt;
{{!}} https://gitorious.org/fg/philosophers-fgdata/source/022bef27f05d4837d720f63c6507b47466ff2a59:Nasal/console/repl.nas#L436&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/philosophers-fgdata/source/nasal-console:Nasal/console&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/fgdata/commit/eaaf816b772649d5b0826a1d0bdd166dbc5b968f&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/flightgear/commit/34ed79e5f88ffdfc5e651a1fe3e639cb8f4d3353&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/flightgear/commit/5eee5e42ae4f5cf56283b3bf5a3be46efc2b51c4&lt;br /&gt;
&lt;br /&gt;
https://www.gitorious.org/fg/flightgear/merge_requests/26&lt;br /&gt;
{{!}} Switched to {{gitorious source|proj=fg|repo=philosophers-fgdata|branch=nasal-console|path=Nasal/console/repl.nas|line=708}}&lt;br /&gt;
&lt;br /&gt;
{{gitorious url|proj=fg|repo=philosophers-fgdata|branch=nasal-console|path=Nasal/console|view=tree}}&lt;br /&gt;
&lt;br /&gt;
{{fgdata-old url|commit=eaaf816b772649d5b0826a1d0bdd166dbc5b968f}}&lt;br /&gt;
&lt;br /&gt;
{{flightgear commit|34ed79e5f88ffdfc5e651a1fe3e639cb8f4d3353}}&lt;br /&gt;
&lt;br /&gt;
{{gitorious merge request|mr=54}}&lt;br /&gt;
&lt;br /&gt;
{{gitorious merge request|mr=26}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[Es/FlightGear Newsletter February 2014]]&lt;br /&gt;
{{!}} https://gitorious.org/fg/philosophers-fgdata/source/022bef27f05d4837d720f63c6507b47466ff2a59:Nasal/console/repl.nas#L436&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/philosophers-fgdata/source/nasal-console:Nasal/console&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/fgdata/commit/eaaf816b772649d5b0826a1d0bdd166dbc5b968f&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/flightgear/commit/34ed79e5f88ffdfc5e651a1fe3e639cb8f4d3353&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/flightgear/commit/5eee5e42ae4f5cf56283b3bf5a3be46efc2b51c4&lt;br /&gt;
&lt;br /&gt;
https://www.gitorious.org/fg/flightgear/merge_requests/26&lt;br /&gt;
{{!}} Changes match the English article.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter April 2014]]&lt;br /&gt;
{{!}} https://gitorious.org/fg/fgdata/flightgear?p=fg/fgdata:flightgear.git;a=blob;f=keyboard.xml&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/fgdata?p=fg:fgdata.git;a=commit;h=f8c56dcc52ffd3d6dfca1d39dc4a72b6b3478368&lt;br /&gt;
&lt;br /&gt;
https://gitorious.org/fg/hoorays-flightgear?p=fg:hoorays-flightgear.git;a=shortlog;h=refs/heads/topics/cppbind-fgprotocol&lt;br /&gt;
{{!}} This first link was the broken {{tl|git link}} template (see the table below).  The other two links are not in the article?!&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter June 2014]]&lt;br /&gt;
{{!}} https://gitorious.org/eddp-custom-scenery/eddp-custom-scenery/&lt;br /&gt;
{{!}} Switched to {{tl|gitorious clone}} to provide functional '''git clone''' instructions.&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter November 2014]]&lt;br /&gt;
{{!}} https://gitorious.org/fg/hoorays-fgdata/source/2857d8fc9fcfe2bb162a9eb9d3dcca4d41b3a876:Nasal/ai/aim9/aim9.fdm#L9&lt;br /&gt;
{{!}} Switch to {{gitorious url|proj=fg|repo=hoorays-fgdata|commit=2857d8fc9fcfe2bb162a9eb9d3dcca4d41b3a876|path=Nasal/ai/aim9/aim9.fdm|line=9}}&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter January 2015]]&lt;br /&gt;
{{!}} https://gitorious.org/fg/canvas-hackers-fgdata/source/f59c42134a5a77e343981dcff8278c3e2f094e87&lt;br /&gt;
{{!}} Switch to {{gitorious url|proj=fg|repo=canvas-hackers-fgdata|commit=f59c42134a5a77e343981dcff8278c3e2f094e87|view=summary}}&lt;br /&gt;
{{!}}}&lt;br /&gt;
&lt;br /&gt;
Broken templates:...&lt;br /&gt;
{{{!}} class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Fixed !! Newsletter !! Template !! Notes&lt;br /&gt;
{{!-}}&lt;br /&gt;
{{!}} {{tick}}&lt;br /&gt;
{{!}} [[FlightGear Newsletter April 2014]]&lt;br /&gt;
{{!}} {{tlx|Git link|gitorious|fg/fgdata|master|keyboard.xml|pre=$FG_ROOT/}}&lt;br /&gt;
{{!}} Switched to {{fgdata source|path=keyboard.xml|pre=$FG_ROOT}} to fix the Gitorious link created by the broken and depreciated {{tl|git link}} template.&lt;br /&gt;
{{!}}}&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
::: —[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 12:06, 9 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:::: I've added a '''notes''' column to help a little.&lt;br /&gt;
&lt;br /&gt;
:::: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 12:30, 9 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
=== Elimination of the dead Gitorious links ===&lt;br /&gt;
Thanks largely to the diversity and flexibility of the [[:Category:Repository link templates|{{obr}}repo link{{cbr}} family of templates]], I have now managed to eliminate almost every last dead Gitorious link in the FlightGear wiki!  The locked Newsletter articles, user pages, and talk pages are the only exceptions.  The page counts from the (Main) namespace are:&lt;br /&gt;
* [http://wiki.flightgear.org/index.php?target=http%3A%2F%2Fgitorious.org&amp;amp;namespace=0&amp;amp;title=Special%3ALinkSearch &amp;lt;nowiki&amp;gt;Special:LinkSearch for http://gitorious.org&amp;lt;/nowiki&amp;gt;] &amp;amp;mdash; 37.  Of these, 17 are for the front page with the news of the Gitorious to SourceForge migration, and the rest are Newsletters.&lt;br /&gt;
* [http://wiki.flightgear.org/index.php?title=Special:LinkSearch&amp;amp;limit=500&amp;amp;offset=0&amp;amp;target=https%3A%2F%2Fgitorious.org&amp;amp;namespace=0 &amp;lt;nowiki&amp;gt;Special:LinkSearch for https://gitorious.org&amp;lt;/nowiki&amp;gt;] &amp;amp;mdash; 166.  Most of these links are valid and created by the {{obr}}gitorious *{{cbr}} subtemplates of {{tl|repo link}}.  The remaining broken links are all in the locked Newsletters.&lt;br /&gt;
The Howto:* pages are not in the (Main) wiki namespace, but I've knocked those out too.&lt;br /&gt;
&lt;br /&gt;
[[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 13:54, 10 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
: thanks for doing all this unglamorous work - I am sorry that Gijs was apparently too busy to follow up on my suggestion to either provide you with admin access around here, or at least to help you run a Python script to do all this work in an automated, rather than manual, fashion. Hopefully, things will work out better next time. Again, thank you. Like I said, I think you should definitely be given admin access on the wiki, especially given your recent contributions - and I would gladly have my wiki status downgraded accordingly. In fact, if I was able to directly promote accounts accordingly, I would have done so months ago - however, it seems that Gijs is the only one to have those privileges, and he mentioned off-list that he's kinda busy with RL/exams etc, so it is to be expected that he's going to become a bottleneck more often - hopefully, this will be recongized as an actual issue, so that there will be more people able to promote new wiki admins. Sorry that things didn't work out better this time, and thanks so much for doing all this stuff manually. -[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 14:49, 10 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:: No problems!  As for automating this, that would not have been possible.  If you look at the changes, you'll see that each one is different &amp;lt;sup&amp;gt;[http://wiki.flightgear.org/index.php?title=Special:RecentChanges&amp;amp;to=20160310210655&amp;amp;limit=500]&amp;lt;/sup&amp;gt;.  I had to check each one, and update the link as required.&lt;br /&gt;
&lt;br /&gt;
:: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 16:08, 10 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
::: There's three of us actually (Curt, Simon and myself), no need to wait on me. See http://wiki.flightgear.org/index.php?title=Special%3AListUsers&amp;amp;username=&amp;amp;group=bureaucrat&amp;amp;limit=100 (Sek is inactive nowadays) ;-)&lt;br /&gt;
::: Please note that forum pms are really not the best way to contact me. I very much prefer email over forum pms as it's a lot easier to filter out the huge amounts of nonsense I'm receiving from stuff requiring actual attention.&lt;br /&gt;
::: Anyhow I've just  promoted Bugman so he can edit locked articles.&lt;br /&gt;
::: [[User:Gijs|Gijs]] ([[User talk:Gijs|talk]]) 05:06, 11 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
:::: Thank you.  I'll try to preserve the original intent of the Newsletters while fixing the broken links (maybe even preserving any original URLs as Mediawiki link text, while pointing to the new URL).  I will use the {{obr}}gitorious *{{cbr}} templates to point to the historical sources, and will probably use this for all of the Gitorious URLs so that we have full control over any future URL breakages via the single location of {{tl|repo link}}.  For example, if they change the gitorious.org domain name to a https://archive.org subdomain (i.e. gitorious.archive.org).&lt;br /&gt;
&lt;br /&gt;
:::: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 06:40, 11 March 2016 (EST)&lt;br /&gt;
&lt;br /&gt;
=== Regex parsing of template parameters? ===&lt;br /&gt;
&lt;br /&gt;
For the {{tl|repo link}} template, I am currently trying to work out what to do for git branches and tags on the SourceForge infrastructure.  The problem is that the presence of the character &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt; within a branch or tag name requires the text &amp;lt;code&amp;gt;/~&amp;lt;/code&amp;gt; to be appended to that name in the URL, for example:&lt;br /&gt;
&lt;br /&gt;
* Tag &amp;lt;code&amp;gt;version/2016.1.1&amp;lt;/code&amp;gt;:  https://sourceforge.net/p/flightgear/simgear/ci/version/2016.1.1/~/tree/simgear/ephemeris/ephemeris.cxx&lt;br /&gt;
* Branch &amp;lt;code&amp;gt;release/2016.1&amp;lt;/code&amp;gt;:  https://sourceforge.net/p/flightgear/simgear/ci/release/2016.1/~/tree/simgear/ephemeris/ephemeris.cxx&lt;br /&gt;
&lt;br /&gt;
I haven't found out a way to use regex to parse the &amp;lt;code&amp;gt;tag&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;branch&amp;lt;/code&amp;gt; template parameters to automate this, hence I am thinking of just giving the instruction for the template user to append this text to the &amp;lt;code&amp;gt;tag&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;branch&amp;lt;/code&amp;gt; parameter text themselves.  However this is not ideal - a change of this behaviour on the SourceForge side requires end pages with SourceForge URLs to be updated, rather than just updating {{tl|repo link}}.  I was wondering about possibility of installing the extension:&lt;br /&gt;
&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Extension:RegexParserFunctions Extension:RegexParserFunctions]&lt;br /&gt;
&lt;br /&gt;
Though I'm not 100% sure if that will work.  Or does someone else know an alternative?  Cheers!&lt;br /&gt;
&lt;br /&gt;
[[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 12:09, 22 April 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
: not a solution, just a potential workaround would be checking for the most common prefix strings used in tags/branches (e.g. version, release, topic, topics) and explicitly rewrite the URL accordingly to append the /~ suffix -[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 12:59, 22 April 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
:: That might be a solution.  But I don't know how to do that without regex ;)  We really only have #ifeq statements, but that has to match the whole string.&lt;br /&gt;
&lt;br /&gt;
:: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 13:44, 22 April 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Discussion about quotes on the wiki ==&lt;br /&gt;
{{usr|Hooray}} have started a page now at [[FlightGear wiki:Quoting Guidelines]] ([http://wiki.flightgear.org/index.php?title=FlightGear_wiki:Quoting_Guidelines&amp;amp;oldid=96104 perm]) for a discussion regarding guidelines for the use of quotes on the wiki.  Join the discussion.&lt;br /&gt;
&lt;br /&gt;
—[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 18:17, 21 March 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In slight relation to this I have tried to make the wiki more consistently use the most common spelling and case, &amp;quot;Instant-Cquotes&amp;quot; and have changed the automatic categorization accordingly.  All articles using the {{tl|FGCquote}} template can now be found in [[:Category:Articles containing Instant-Cquotes]] (currently some ~250 articles).&lt;br /&gt;
&lt;br /&gt;
—[[User:Johan G|Johan G]] ([[User_talk:Johan_G|Talk]] | [[Special:Contributions/Johan_G|contribs]]) 08:21, 23 March 2016 (EDT)&lt;br /&gt;
&lt;br /&gt;
== Reorganizing the Git articles ==&lt;br /&gt;
I've noticed that the [[Category:Git|Git articles]] suffer from duplication and are in part obsolete (especially with regard to the instructions for running Git on Windows). Thus, I propose the following reorganization:&lt;br /&gt;
* [[Development workflow]]: reorganization to explain how the patch submission process is organized from a high-level point of view (forking the repository from SourceForge, developing, pushing the commits to the personal fork, submitting a merge request/sending a patch to the mailing list);&lt;br /&gt;
* [[FlightGear Git]]: leave as is;&lt;br /&gt;
* '''Installing and configuring Git''' - new article about installing Git and configuring it (setting the username/e-mail address); merge the contents of [[FlightGear Git on Windows]] and [[Resources WRT running git on Win32]] here;&lt;br /&gt;
* [[FlightGear Git for laymen]] - make it follow [[FGW:MOS]], merge the contents of [[Howto:Start using git]] here;&lt;br /&gt;
* [[FlightGear Git: core developers]] and [[FlightGear Git: data developers]] - I'm uncertain about what I should do with them: the only piece information that would not be written in other articles is the list of alternative methods for cloning FGData;&lt;br /&gt;
* [[FlightGear Git: gitiquette]] and [[FlightGear Git: tips]] - make them follow [[FGW:MOS]].&lt;br /&gt;
Any comments? -- [[User:Elgaton|ElGaton]] ([[User talk:Elgaton|&amp;lt;tt&amp;gt;talk&amp;lt;/tt&amp;gt; to me]]) 06:11, 13 May 2016 (EDT)&lt;/div&gt;</summary>
		<author><name>Elgaton</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=FlightGear_wiki:Manual_of_Style&amp;diff=98102</id>
		<title>FlightGear wiki:Manual of Style</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=FlightGear_wiki:Manual_of_Style&amp;diff=98102"/>
		<updated>2016-05-11T17:45:06Z</updated>

		<summary type="html">&lt;p&gt;Elgaton: /* Reference */ Fix link&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{shortcut|FGW:MOS}}&lt;br /&gt;
&lt;br /&gt;
The '''Manual of Style''' is a style manual for all FlightGear wiki articles. It helps editors write articles with consistent, clear, and precise language, layout, and formatting. The goal is to make using this wiki easier and more intuitive. Consistent language, style, and formatting promote clarity and cohesion. Writing should be clear and concise. Plain English works best; avoid ambiguity, jargon, and vague or unnecessarily complex wording.&lt;br /&gt;
&lt;br /&gt;
Discuss style issues on [[FlightGear wiki talk:Manual of Style|the talk page]].&lt;br /&gt;
&lt;br /&gt;
== Article titles, headings, and sections ==&lt;br /&gt;
=== Article titles ===&lt;br /&gt;
* Use sentence case, not title case. The initial letter of a title is capitalized (except in rare cases, such as eBay), but otherwise, capital letters are used only where they would be used in a normal sentence ({{xt|List of developed airports}}, not {{!xt|List of Developed Airports}}). Also, keep in mind that the wiki software automatically capitalizes the initial letter of a namespace/page title in its address.&lt;br /&gt;
* Titles should be precise enough to unambiguously define the topical scope of the article ({{xt|Boeing 747}}, not {{!xt|747}}).&lt;br /&gt;
* The characters &amp;lt;code&amp;gt;# &amp;lt; &amp;gt; [ ] | { }&amp;lt;/code&amp;gt; are reserved by the wiki software and can not be used.&lt;br /&gt;
&lt;br /&gt;
=== Section organization ===&lt;br /&gt;
An article should begin with an introductory lead section, which should not contain section headings. The remainder may be divided into sections, each with a section heading (see below) that can be nested in a hierarchy. If there are at least four section headings in the article, a navigable table of contents is generated automatically and displayed between the lead and the first heading.&lt;br /&gt;
&lt;br /&gt;
=== Section headings ===&lt;br /&gt;
Equal signs are used to mark the enclosed text as a section heading: &amp;lt;code&amp;gt;== Title ==&amp;lt;/code&amp;gt; for a primary section; &amp;lt;code&amp;gt;=== Title ===&amp;lt;/code&amp;gt; for the next level (a subsection); and so on to the lowest-level subsection, with &amp;lt;code&amp;gt;===== Title =====&amp;lt;/code&amp;gt;. (The highest heading level technically possible is &amp;lt;code&amp;gt;= Title =&amp;lt;/code&amp;gt;; but do not use it in articles, because it is reserved for the automatically generated top-level heading at the top of the page containing the title of the whole article.) Spaces between the equal signs and the heading text are optional, and will not affect the way the heading is displayed. The heading must be typed on a separate line. Include one blank line above the heading, and optionally one blank line below it, for readability in the edit window (but not two or more consecutive blank lines, which will add unnecessary visible white space in the rendered page.)&lt;br /&gt;
&lt;br /&gt;
The provisions in [[#Article titles|Article titles]] (above) generally apply to section headings as well (for example, headings are in sentence case, not title case). The following points apply specifically to section headings:&lt;br /&gt;
* Headings should normally not contain links, especially where only part of a heading is linked.&lt;br /&gt;
* Section and subsection headings should preferably be unique within a page; otherwise section links may lead to the wrong place, and automatic edit summaries can be ambiguous.&lt;br /&gt;
* Citations should not be placed within or on the same line as section and subsection headings.&lt;br /&gt;
* Headings should not contain images.&lt;br /&gt;
&lt;br /&gt;
== Capital letters ==&lt;br /&gt;
Sentence case rather than title case is used in wiki article titles and section headings; see [[#Article titles|Article titles]] and [[#Section headings|Section headings]] above. For capitalization of list items, see [[#Bulleted and numbered lists|Bulleted and numbered lists]]. Other points concerning capitalization are summarized below.&lt;br /&gt;
&lt;br /&gt;
===Do not use capitals for emphasis===&lt;br /&gt;
Use italics, not capitals, to denote emphasis.&lt;br /&gt;
:''Incorrect'': {{!xt|It is not only a LITTLE learning that is dangerous}}.&lt;br /&gt;
:''Correct'': {{xt|It is not only a ''little'' learning that is dangerous}}.&lt;br /&gt;
&lt;br /&gt;
===Calendar items===&lt;br /&gt;
* '''Months, days of the week, and holidays''' start with a capital letter ({{xt|June}}, {{xt|Monday}}).&lt;br /&gt;
&lt;br /&gt;
===Celestial bodies===&lt;br /&gt;
* When used generally, the words '''&amp;lt;nowiki /&amp;gt;''sun'', ''earth'', and ''moon''&amp;lt;nowiki /&amp;gt;''' do not take capitals ({{xt|The sun was peeking over the mountain top}}), except when the term names a specific astronomical body ({{xt|The Moon orbits the Earth}}).&lt;br /&gt;
&lt;br /&gt;
===Compass points===&lt;br /&gt;
Do not capitalize '''directions''' such as ''north'', nor their related forms ({{xt|Follow the northern road}}), except where they are parts of proper names (such as {{xt|South Pole}}).&lt;br /&gt;
&lt;br /&gt;
Capitalize '''names of regions''' if they have attained proper-name status, including informal conventional names ({{xt|Southern California}} or {{xt|the Western Desert}}). Do not capitalize descriptive names for regions that have not attained the status of proper names, such as {{xt|southern Poland}}.&lt;br /&gt;
&lt;br /&gt;
(Composite directions may or may not be hyphenated, depending on the style adopted in the article. {{xt|Southeast Asia}} and {{xt|northwest}} are more common in American English; but {{xt|South-East Asia}} and {{xt|north-west}} in British English. In cases such as {{xt|north–south dialogue}} and {{xt|east–west orientation}} an en dash is used.)&lt;br /&gt;
&lt;br /&gt;
== Abbreviations ==&lt;br /&gt;
=== Write out both the full version and the abbreviation at first occurrence ===&lt;br /&gt;
* When an abbreviation is to be used in an article, give the expression in full at first, followed immediately by the abbreviation in parentheses (round brackets). In the rest of the article the abbreviation can then be used by itself:&lt;br /&gt;
::{{xt|The instrument landing system (ILS) is a ground-based instrument approach system}}, at the first mention of the instrument landing system; and&lt;br /&gt;
::{{xt|There are three categories of ILS}}, at a subsequent mention.&lt;br /&gt;
* Do not apply initial capitals in a full version simply because capitals are used in the abbreviation.&lt;br /&gt;
::{|style=&amp;quot;background:transparent&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|''Correct'': || {{xt|There are two types of flight rules: visual flight rules (VFR) and instrument flight rules (IFR).}}&lt;br /&gt;
|-&lt;br /&gt;
|''Incorrect'': || {{!xt|There are two types of flight rules: Visual Flight Rules (VFR) and Instrument Flight Rules (IFR).}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Ampersand ===&lt;br /&gt;
The ampersand (&amp;amp;) substitutes for the word ''and'' (it is a form of Latin ''et''). In normal text, ''and'' should be used instead: {{xt|version 1&amp;amp;nbsp;and&amp;amp;nbsp;2}}, not {{!xt|version 1&amp;amp;nbsp;&amp;amp;&amp;amp;nbsp;2}}. Ampersands may be used with consistency and discretion in tables, infoboxes, and similar contexts where space is limited.&lt;br /&gt;
&lt;br /&gt;
== Italics ==&lt;br /&gt;
=== Emphasis ===&lt;br /&gt;
Italics may be used ''sparingly'' to emphasize words in sentences (whereas boldface is normally not used for this purpose). Generally, the more highlighting in an article, the less its effectiveness.&lt;br /&gt;
&lt;br /&gt;
=== Quotations in italics ===&lt;br /&gt;
Quotations must always be clearly indicated as being quotations. For quotations, use only quotation marks (for short quotations) or block quoting (for long ones), not italics. (See [[#Quotations|Quotations]] below.) This means that (1) a quotation is not italicized inside quotation marks or a block quote just because it is a quotation, and (2) italics are no substitute for proper quotation formatting.&lt;br /&gt;
&lt;br /&gt;
== Quotations ==&lt;br /&gt;
Where the same quotation has been used elsewhere in the article, avoid duplicating it, which is regarded as poor style.&lt;br /&gt;
&lt;br /&gt;
The quotation should be representative of the whole source document; editors should be very careful to avoid misrepresentation of the argument in the source. Where a quotation presents rhetorical language in place of more neutral, dispassionate tone preferred for encyclopedias, it can be a backdoor method of inserting a non-neutral treatment of a controversial subject into the wiki's narrative on the subject, and should be avoided.&lt;br /&gt;
&lt;br /&gt;
Quotations should generally be worked into the article text, so as not to inhibit the pace, flow and organization of the article. Longer quotes may need to be set apart, generally through the use of wikitext templates such as {{tl|Quote}} or {{tl|Quotation}}. Longer quotations may also be hidden in the reference (footnote) to facilitate verification by other editors without sacrificing readability. For pull quotes (quotes of the article text used to highlight a section) the {{tl|Cquote}} template can be used. Quotations used only as sources to support statements contained in the article can be added with a &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;&amp;lt;ref&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; tag containing a reference formatted with the {{tl|cite web}} template; in that case, add {{tl|Appendix}} at the end of the page so that citations can be displayed in a uniform way.&lt;br /&gt;
&lt;br /&gt;
=== Original wording ===&lt;br /&gt;
Quotations must be verifiably attributed and the wording of the quoted text should be faithfully reproduced. If there is a significant error in the original statement, use {{xt|[''[[sic]]'']}} to show that the error was not made by the wiki editors. However, trivial spelling and typographic errors should simply be corrected without comment (for example, correct {{!xt|basicly}} to {{xt|basically}}), unless the slip is textually important.&lt;br /&gt;
&lt;br /&gt;
Use [[#Ellipses|ellipses]] to indicate omissions from quoted text. Legitimate omissions include extraneous, irrelevant, or parenthetical words. Do not omit text where doing so would remove important context or alter the meaning of the text. &lt;br /&gt;
&lt;br /&gt;
=== Typographic conformity ===&lt;br /&gt;
In most cases it is not desirable to duplicate the original formatting. Formatting and other purely typographical elements of quoted text should be adapted to the wiki's conventions without comment provided that doing so will not change or obscure the meaning of the text. These are alterations which make no difference when the text is read aloud, such as:&lt;br /&gt;
* Changing capitalization so that sentences begin with capital letters.&lt;br /&gt;
* When quoting a quotation that itself contains a quotation, single quotes may be replaced with double quotes, and vice versa. See [[#Quotations within quotations|Quotations within quotations]] below.&lt;br /&gt;
* Removing spaces before punctuation such as periods and colons.&lt;br /&gt;
* Generally preserve bold and italics (see [[#Italics|Italics]], above), but most other styling should be altered.&lt;br /&gt;
* Expanding abbreviations.&lt;br /&gt;
&lt;br /&gt;
=== Quotations within quotations ===&lt;br /&gt;
For quotations within quotations, use double quote marks outermost and, working inward, alternate single with double quote marks.&lt;br /&gt;
&lt;br /&gt;
=== Attribution ===&lt;br /&gt;
The author of a quote of a full sentence or more should be named; this is done in the main text and not in a footnote. A reader should not have to follow a footnote to learn whose words a quote is.&lt;br /&gt;
&lt;br /&gt;
=== Linking ===&lt;br /&gt;
As much as possible, avoid linking from within quotes, which may clutter the quotation, violate the principle of leaving quotations unchanged, and mislead or confuse the reader.&lt;br /&gt;
&lt;br /&gt;
=== Block quotations ===&lt;br /&gt;
Format a long quote (more than about 40 words or a few hundred characters, or consisting of more than one paragraph, regardless of length) as a block quotation, which the wiki's software will indent from both margins. Do not enclose block quotations in quotation marks (and especially avoid decorative quotation marks in normal use, such as those provided by the {{tl|cquote}} template, which are reserved for pull quotes; quoted sections from elsewhere in the same wiki article). Block quotations can be added with {{tl|quote}} or {{tl|quotation}}.&lt;br /&gt;
&lt;br /&gt;
=== Overusing quotations ===&lt;br /&gt;
Long quotations crowd the actual article and remove attention from other information. Many direct quotations can be minimized in length by providing an appropriate context in the surrounding text. A summary or paraphrase of a quotation is often better where the original wording could be improved. Consider minimizing the length of a quotation by paraphrasing, by working smaller portions of quotation into the article text, or both.&lt;br /&gt;
&lt;br /&gt;
Overuse happens when:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;a quotation is used without pertinence&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This means that a quotation is visually on the page, but its relevance is not explained anywhere.&lt;br /&gt;
&lt;br /&gt;
==== Specific recommendations ====&lt;br /&gt;
* Using too many quotes is incompatible with the encyclopedic writing style.&lt;br /&gt;
* As a matter of style, quoteboxes should generally be avoided as they draw special attention to the opinion of one source, and present that opinion as though the project endorses it. Instead of using quoteboxes to highlight its notability, explain its importance before introducing the quote or in an introduction to the quote.&lt;br /&gt;
* The wiki is not a list or repository of loosely associated topics such as quotations.&lt;br /&gt;
* Do not insert any number of quotations in a stand-alone quote section.&lt;br /&gt;
* A quotation that does not directly relate to the topic of the article or directly support the information as it is presented should not be used.&lt;br /&gt;
* Intersperse quotations with original prose that comments on those quotations instead of constructing articles out of quotations with little or no original prose.&lt;br /&gt;
* Longer quotations may be hidden in the reference as a footnote to facilitate verification by other editors without sacrificing readability.&lt;br /&gt;
&lt;br /&gt;
== Punctuation ==&lt;br /&gt;
&lt;br /&gt;
=== Apostrophes ===&lt;br /&gt;
* Consistent use of the straight (or ''typewriter'') apostrophe ({{xt|&amp;amp;nbsp;'&amp;amp;nbsp;}}) is recommended, as opposed to the curly (or ''typographic'') apostrophe ({{!xt|&amp;amp;nbsp;’&amp;amp;nbsp;}}).&lt;br /&gt;
&lt;br /&gt;
=== Quotation marks ===&lt;br /&gt;
;Double or single&lt;br /&gt;
: Enclose quotations with double quotation marks ({{xt|Bob said, &amp;quot;Jim ate the apple.&amp;quot;}}). Enclose quotations inside quotations with single quotation marks ({{xt|Bob said, &amp;quot;Did Jim say 'I ate the apple' after he left?&amp;quot;}}).&lt;br /&gt;
&lt;br /&gt;
;Block quotes&lt;br /&gt;
: As already noted [[#Quotations|above]], we use quotation marks or block quotes (not both) to distinguish long quotations from other text. Multiparagraph quotations are always block-quoted. The quotations must be precise and exactly as in the source (except for certain ''allowable typographical changes'', also noted [[#Typographic conformity|above]]). The source should be cited clearly and precisely.&lt;br /&gt;
&lt;br /&gt;
===Brackets and parentheses===&lt;br /&gt;
These rules apply to both round brackets {{xt|(&amp;amp;nbsp;)}}, often called parentheses, and square brackets {{xt|[&amp;amp;nbsp;]}}.&lt;br /&gt;
&lt;br /&gt;
If a sentence contains a bracketed phrase, place the sentence punctuation outside the brackets {{xt|(as shown here).}} However, where one or more sentences are wholly inside brackets, place their punctuation inside the brackets. There should be no space next to the inner side of a bracket. An opening bracket should usually be preceded by a space, for example. This may not be the case if it is preceded by an opening quotation mark, another opening bracket, or a portion of a word.&lt;br /&gt;
&lt;br /&gt;
There should be a space after a closing bracket, except where a punctuation mark follows (though a spaced dash would still be spaced after a closing bracket) and in unusual cases similar to those listed for opening brackets.&lt;br /&gt;
&lt;br /&gt;
If sets of brackets are nested, use different types for adjacent levels of nesting; for two levels, it is customary to have square brackets appear within round brackets. This is often a sign of excessively convoluted expression; it is often better to recast, linking the thoughts with commas, semicolons, colons, or dashes.&lt;br /&gt;
&lt;br /&gt;
Avoid adjacent sets of brackets. Either put the parenthetic phrases in one set separated by commas, or rewrite the sentence.&lt;br /&gt;
&lt;br /&gt;
Square brackets are used to indicate editorial replacements and insertions within quotations, though this should never alter the intended meaning. They serve three main purposes.&lt;br /&gt;
&lt;br /&gt;
====Sentences and brackets====&lt;br /&gt;
* If any sentence includes material that is enclosed in square or round brackets, it still must end—with a period, or a question or exclamation mark—''after'' those brackets. This principle applies no matter what punctuation is used within the brackets.&lt;br /&gt;
* However, if the entire sentence is within brackets, the closing punctuation falls within the brackets. (This sentence is an example.) This does not apply to matter that is added (or modified editorially) at the beginning of a sentence for clarity, which is usually in square brackets.&lt;br /&gt;
&lt;br /&gt;
=== Ellipses ===&lt;br /&gt;
An ellipsis (plural ''ellipses'') is used to indicate an omission of material from quoted text or some other omission, perhaps of the end of a sentence, often in a printed record of conversation. The ellipsis is represented by '''ellipsis points''': a set of three unspaced periods, surrounded by square brackets {{xt|[...]}}.&lt;br /&gt;
&lt;br /&gt;
== Dates and time ==&lt;br /&gt;
=== Time of day ===&lt;br /&gt;
Time of day is normally expressed in figures rather than being spelled out. Context determines whether the 12- or 24-hour clock is used.&lt;br /&gt;
* 12-hour clock times are written in the form {{xt|11:15&amp;amp;nbsp;a.m.}} and {{xt|2:30&amp;amp;nbsp;p.m.}}, or the form {{xt|11:15&amp;amp;nbsp;am}} and {{xt|2:30&amp;amp;nbsp;pm}}, with a space before the abbreviation.&lt;br /&gt;
* 24-hour clock times are written in the form {{xt|08:15}}, {{xt|22:55}}, with no suffix. Note that {{xt|00:00}} refers to midnight at the start of a date, and {{xt|24:00}} to midnight at the end of a date.&lt;br /&gt;
&lt;br /&gt;
=== Days ===&lt;br /&gt;
* For full dates, use the format {{xt|10 June 1921}} or the format {{xt|June 10, 1921}}. Similarly, where the year is omitted, use {{xt|10 June}} or {{xt|June 10}}. For choice of format, see below.&lt;br /&gt;
* Do not use numerical date formats such as {{!xt|03/04/2005}}, as this could refer to 3&amp;amp;nbsp;April or to March&amp;amp;nbsp;4. If a numerical format is required (e.g. for conciseness in long lists and tables), use the YYYY-MM-DD format: {{xt|2005-04-03}}.&lt;br /&gt;
&lt;br /&gt;
==== Choice of format ====&lt;br /&gt;
* All the dates in a given article should have the same format (day-month or month-day). These requirements do not apply to dates in quotations or titles.&lt;br /&gt;
* Otherwise, do not change an article from one form to another without good reason.&lt;br /&gt;
&lt;br /&gt;
=== Months ===&lt;br /&gt;
* For month and year, write {{xt|June 1921}}, with no comma.&lt;br /&gt;
* Abbreviations for months, such as {{xt|Feb}}, are used only where space is extremely limited. Such abbreviations should use three letters only, and should not be followed by a period (full stop) except at the end of a sentence.&lt;br /&gt;
&lt;br /&gt;
=== Years and longer periods ===&lt;br /&gt;
* Do not use ''the year'' before the digits ({{xt|1995}}, not {{!xt|the year 1995}}), unless the meaning would otherwise be unclear.&lt;br /&gt;
* Decades are written in the format {{xt|the 1980s}}, with no apostrophe. Use the two-digit form ('80s) only with an established social or cultural meaning. Avoid forms such as {{!xt|the 1700s}} that could refer to 10 or 100 years.&lt;br /&gt;
&lt;br /&gt;
=== Current ===&lt;br /&gt;
Use of the term &amp;quot;current&amp;quot; should be avoided. What is current today may not be tomorrow; situations change over time. Instead, use date- and time-specific text.&lt;br /&gt;
:{|style=&amp;quot;background:transparent&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|''Incorrect'':||{{!xt|FlightGear 3.0 is currently the latest version ...}}&lt;br /&gt;
|-&lt;br /&gt;
|''Correct'':||{{xt|As of February 2014, FlightGear 3.0 is the latest version ...}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Numbers ==&lt;br /&gt;
* In general, write whole numbers from one to nine as words, write other numbers that take two words or fewer to say as either figures or words (with consistency within each article), and write all other numbers as figures: {{xt|1/5}} or {{xt|one-fifth}}, {{xt|84}} or {{xt|eighty-four}}, {{xt|200}} or {{xt|two hundred}}, but {{xt|3.75}}, {{xt|544}}, {{xt|21&amp;amp;nbsp;million}}.&lt;br /&gt;
* In general, use a comma to delimit numbers with five or more digits to the left of the decimal point. Numbers with four digits are at the editor's discretion: {{xt|12,345}}, but either {{xt|1,000}} or {{xt|1000}}.&lt;br /&gt;
* In general, use decimals rather than vulgar fractions with measurements.&lt;br /&gt;
* Write out &amp;quot;million&amp;quot; and &amp;quot;billion&amp;quot; on the first use. After that, unspaced &amp;quot;M&amp;quot; can be used for millions and &amp;quot;bn&amp;quot; for billions: {{xt|70M}} and {{xt|25bn}}.&lt;br /&gt;
* Write {{xt|3%}}, {{xt|three percent}}, or {{xt|three per cent}}, but not {{!xt|3 %}} (with a space) or {{!xt|three %}}. &amp;quot;Percent&amp;quot; is American usage, and &amp;quot;per cent&amp;quot; is British usage. In ranges of percentages written with an en dash, write only one percent sign: {{xt|3–14%}}.&lt;br /&gt;
&lt;br /&gt;
==Units of measurement==&lt;br /&gt;
* The main unit in which a quantity is expressed should generally be an SI unit or non-SI unit officially accepted for use with the SI.&lt;br /&gt;
* In a direct quotation, always keep the source units. If a conversion is required, it should appear within square brackets in the quote, or else an obscure use of units can be explained in a footnote.&lt;br /&gt;
* Where space is limited (such as tables, infoboxes, parenthetical notes, and mathematical formulas) use unit symbols. In main text it is usually better to spell out unit names, but symbols may also be used when a unit (especially one with a long name) is used repeatedly. However, spell out the first instance of each unit in an article (for example, {{xt|the typical batch is 250 kilograms&amp;amp;nbsp;... and then 15&amp;amp;nbsp;kg of emulsifier is added}}), except for unit names that are hardly ever spelled out (e.g. the degree Celsius). Most unit names are not capitalized. Use &amp;quot;per&amp;quot; when writing out a unit, rather than a slash: {{xt|meter per second}}, not {{!xt|meter/second}}.&lt;br /&gt;
* Potentially unfamiliar unit symbols should be introduced parenthetically at their first occurrence in the article, with the full name given first: for example, {{xt|His initial betatron reached energies of 2.3 megaelectronvolts (MeV), while subsequent betatrons achieved 300&amp;amp;nbsp;MeV.}}&lt;br /&gt;
* When dimensions are given, each number should be followed by a unit name or symbol (e.g. write {{xt|1&amp;amp;nbsp;m × 3&amp;amp;nbsp;m × 6&amp;amp;nbsp;m}}, not {{!xt|1 × 3 × 6&amp;amp;nbsp;m}}).&lt;br /&gt;
* When they form a compound adjective, values and unit names should be separated by a hyphen: for example, {{xt|a five-day race}}.&lt;br /&gt;
* Unit symbols are preceded by figures, not by spelled-out numbers. Values and unit symbols are separated by a non-breaking space. For example, {{xt|5&amp;amp;nbsp;min}}. The percent sign, and units of degrees, minutes, and seconds ''for angles and coordinates'', are unspaced.&lt;br /&gt;
* Standard unit symbols do not require a full stop (period). However non-standard abbreviations should always be given a full stop.&lt;br /&gt;
* No ''s'' is appended, e.g. {{xt|km}}, {{xt|in}}, {{xt|lb}}, not {{!xt|kms}}, {{!xt|ins}}, {{!xt|lbs}}.&lt;br /&gt;
* Write powers of unit symbols with HTML, e.g. {{xt|&amp;lt;nowiki&amp;gt;5&amp;amp;nbsp;km&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;&amp;lt;/nowiki&amp;gt;}} not Unicode superscripts and subscripts.&lt;br /&gt;
* For quantities of bytes and bits, specify whether the binary or decimal meanings of K, M, G, etc. are intended.&lt;br /&gt;
&lt;br /&gt;
== Grammar and usage ==&lt;br /&gt;
=== First-person pronouns ===&lt;br /&gt;
Wiki articles must not be based on one person's opinions or experiences. The use of ''I'', ''my'', or similar forms is restricted to user pages and quotations. Also avoid ''we'', ''us'', and ''our'': {{!xt|We should note that some critics have argued against our proposal}} (personal rather than encyclopedic).&lt;br /&gt;
&lt;br /&gt;
== Vocabulary ==&lt;br /&gt;
=== Contractions ===&lt;br /&gt;
Uncontracted forms such as {{xt|do not}} or {{xt|it is}} are the default in encyclopedic style; {{!xt|don't}} and {{!xt|it's}} are too informal.&lt;br /&gt;
&lt;br /&gt;
=== Foreign terms ===&lt;br /&gt;
Foreign words should be used sparingly.&lt;br /&gt;
&lt;br /&gt;
==== No common usage in English ====&lt;br /&gt;
Use italics for phrases in other languages and for isolated foreign words that are not current in English.&lt;br /&gt;
&lt;br /&gt;
==== Common usage in English ====&lt;br /&gt;
Loanwords and borrowed phrases that have common usage in English ({{xt|vice versa}}) do not require italics. A rule of thumb is not to italicize words that appear unitalicized in major English-language dictionaries.&lt;br /&gt;
&lt;br /&gt;
=== Technical language ===&lt;br /&gt;
Some topics are intrinsically technical, but editors should try to make them understandable to as many readers as possible. Minimize jargon, or at least explain it. For unavoidably technical articles a separate introductory article may be the best solution. Avoid excessive ''wikilinking'' (linking within the wiki) as a substitute for parenthetic explanations such as the one in this sentence. Do not introduce new and specialized words simply to teach them to the reader when more common alternatives will do. When the notions named by jargon are too complex to concisely explain in a few parenthetical words, write one level down. For example, consider adding a brief background section with {{tl|main}} tags pointing to the full treatment article(s) of the prerequisite notions; this approach is practical only when the prerequisite concepts are central to the exposition of the article's main topic, and when such prerequisites aren't too numerous.&lt;br /&gt;
&lt;br /&gt;
=== Geographical items ===&lt;br /&gt;
Places should generally be referred to consistently by the same name as in the title of their article. Exceptions are made if there is a widely accepted historical English name appropriate to the given context. In cases where such a historical name is used, it should be followed by the modern name in round brackets (parentheses) on the first occurrence of the name in applicable sections of the article. This resembles linking; it should not be done to the detriment of style. On the other hand, it is probably better to provide such a variant too often than too rarely. If more than one historical name is applicable for a given context, the other names should be added after the modern English name, that is: &amp;quot;historical name (modern name, other historical names)&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Images ==&lt;br /&gt;
* Infoboxes, images, and related content in the lead must be right-aligned.&lt;br /&gt;
* Use captions to clarify the relevance of the image to the article (see [[#Captions|Captions]], below).&lt;br /&gt;
* Each image should be inside the major section to which it relates (within the section defined by the most recent level 2 heading or at the top of the lead), not immediately above the section heading.&lt;br /&gt;
* Avoid sandwiching text between two images that face each other, and between an image and an infobox or similar.&lt;br /&gt;
* The thumbnail option may be used (&amp;quot;&amp;lt;code&amp;gt;thumb&amp;lt;/code&amp;gt;&amp;quot;), or another size may be fixed. The default thumbnail width is 220&amp;amp;nbsp;pixels; users can adjust this in their preferences. Lead images should be no wider than &amp;quot;upright=1.35&amp;quot; (by default this is 300 pixels).&lt;br /&gt;
* Avoid referring to images as being on the left or right. Image placement is different for viewers of the mobile version of the wiki and might change in the future. Instead, use captions to identify images.&lt;br /&gt;
&lt;br /&gt;
=== Avoid entering textual information as images ===&lt;br /&gt;
Textual information should almost always be entered as text rather than as an image. True text can be colored and adjusted with CSS tags and templates, but text in images cannot be. Images are not searchable and are slower to download. Any important textual information in an image should also appear in the image's alt text, caption, or other nearby text.&lt;br /&gt;
&lt;br /&gt;
=== Captions ===&lt;br /&gt;
Photographs and other graphics should always have captions, unless they are &amp;quot;self-captioning&amp;quot; images or when they are unambiguous depictions of the subject of the article.&lt;br /&gt;
&lt;br /&gt;
==== Formatting of captions ====&lt;br /&gt;
* Captions normally start with a capital letter.&lt;br /&gt;
* Most captions are not complete sentences, but merely sentence fragments that should not end with a period. If any complete sentence occurs in a caption, all sentences and any sentence fragments in that caption should end with a period.&lt;br /&gt;
* The text of captions should not be specially formatted (with italics, for example), except in ways that would apply if it occurred in the main text.&lt;br /&gt;
* Captions should be succinct; more information about the image can be included on its description page, or in the main text.&lt;br /&gt;
* Captions for technical charts and diagrams may be substantially longer than those for other images. Captions for technical images should fully describe all the elements of the image, and the image's significance.&lt;br /&gt;
&lt;br /&gt;
== Bulleted and numbered lists ==&lt;br /&gt;
* Do not use lists if a passage is read easily as plain paragraphs.&lt;br /&gt;
* Use proper wikimarkup- or template-based list code ''(see [[Help:Formatting#Lists and indentation]])''.&lt;br /&gt;
* Do not leave blank lines between items in a bulleted or numbered list unless there is a reason to do so, since this causes the wiki software to interpret each item as beginning a new list.&lt;br /&gt;
** Indents (such as this) are permitted if the elements are &amp;quot;Children&amp;quot; items&lt;br /&gt;
* Use numbers rather than bullets only if:&lt;br /&gt;
** A need to refer to the elements by number may arise; or&lt;br /&gt;
** The sequence of the items is critical.&lt;br /&gt;
* Use the same grammatical form for all elements in a list, and do not mix sentences and sentence fragments as elements.&lt;br /&gt;
** For example, when the elements are: &lt;br /&gt;
*** ''Complete sentences'', each one is formatted with sentence case (its first letter is capitalized) and a final period (full stop).&lt;br /&gt;
*** ''Sentence fragments'', the list is typically introduced by a lead fragment ending with a colon. &lt;br /&gt;
*** ''Titles of works'', they retain the original capitalization of the titles.  &lt;br /&gt;
*** ''Other elements'', they are formatted consistently in either sentence case or lower case.&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
=== Wikilinks ===&lt;br /&gt;
'''Make [[Help:Formatting#Links|links]] only where they are relevant and helpful in the context:''' Excessive use of hyperlinks can be distracting and may slow the reader down. Redundant links clutter the page and make future maintenance harder. High-value links that ''are'' worth pursuing should stand out clearly.&lt;br /&gt;
&lt;br /&gt;
'''Linking to sections:''' A hash sign&amp;amp;nbsp;(#) followed by the appropriate heading will lead to a relevant part of a page. For example, &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;[[FlightGear#History]]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; links to a particular section of the article [[FlightGear]].&lt;br /&gt;
&lt;br /&gt;
'''Initial capitalization:''' The wiki software does not require that wikilinks begin with an upper-case character. Only capitalize the first letter where this is naturally called for.&lt;br /&gt;
&lt;br /&gt;
'''Linking in discussion pages:''' When adding a wikilink to a discussion page, it is preferable to use [[Help:Formatting#Permalinks_and_links_to_diffs|permalinks]] instead of ordinary links, since the content may have changed a lot before the next reader reads the comment. To highlight a specific edit, it might also be useful to link to a [[Help:Formatting#Permalinks_and_links_to_diffs|diff]].&lt;br /&gt;
&lt;br /&gt;
=== External links ===&lt;br /&gt;
Do not use external links in the body of an article. Articles can include an ''external links'' section at the end, pointing to further information outside the wiki as distinct from citing sources. The standard format is a primary heading, &amp;lt;code&amp;gt;==External links==&amp;lt;/code&amp;gt;, followed by a bulleted list of links. Identify the link and briefly indicate its relevance to the article: avoid linking to commercial and unrelated web sites, in essence ''spam''. For example:&lt;br /&gt;
:&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;* [http://flightgear.org Official website]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;* [https://sourceforge.net/p/flightgear/codetickets/ Bug tracker]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
These will appear as:&lt;br /&gt;
:* [http://flightgear.org Official website]&lt;br /&gt;
:* [https://sourceforge.net/p/flightgear/codetickets/ Bug tracker]&lt;br /&gt;
&lt;br /&gt;
== Miscellaneous ==&lt;br /&gt;
=== Keep markup simple ===&lt;br /&gt;
The simplest markup is often the easiest to edit, the most comprehensible, and the most predictable. Markup may appear differently in different browsers. Use HTML and CSS markup sparingly; in particular, do not use the CSS &amp;lt;code&amp;gt;float&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;line-height&amp;lt;/code&amp;gt; properties because they break rendering on some browsers when large fonts are used.&lt;br /&gt;
&lt;br /&gt;
An HTML entity is sometimes better than the equivalent Unicode character, which may be difficult to identify in edit mode; for example, &amp;lt;code&amp;gt;&amp;amp;amp;Alpha;&amp;lt;/code&amp;gt; is understood where &amp;lt;code&amp;gt;Α&amp;lt;/code&amp;gt; (the upper-case form of Greek &amp;lt;code&amp;gt;α&amp;lt;/code&amp;gt;) may not be.&lt;br /&gt;
&lt;br /&gt;
=== Use templates ===&lt;br /&gt;
Make use of [[:Category:Templates|existing templates]] whenever possible to ensure articles are styled in a uniform way. See [[Help:Templates|the Templates Help page]] for a quick introduction to templates.&lt;br /&gt;
&lt;br /&gt;
=== Formatting issues ===&lt;br /&gt;
Modifications in font size, blank space, and color (see [[#Color coding|Color coding]], below) are an issue for the wiki site-wide style sheet, and should be reserved for special cases only.&lt;br /&gt;
&lt;br /&gt;
Typically, the use of custom font styles will:&lt;br /&gt;
* reduce consistency, since the text will no longer look uniform;&lt;br /&gt;
* reduce usability, since it might be impossible for people with custom style sheets (for accessibility reasons, for example) to override it, and it might clash with a different skin as well as inconvenience people with color blindness (see below); and&lt;br /&gt;
* cause disputes, since other editors may disagree aesthetically with the choice of style.&lt;br /&gt;
&lt;br /&gt;
Outside article text, different font sizes are routinely used in navigation templates and infoboxes, tables (especially in larger ones), and some other contexts where alternatives are not available (such as table captions). Specify font sizes ''relatively'' (for example in CSS with &amp;lt;code&amp;gt;font-size: 80%&amp;lt;/code&amp;gt;) rather than ''absolutely'' (like &amp;lt;code&amp;gt;font-size: 8pt&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
==== Color coding ====&lt;br /&gt;
Information should be accessible to all. Do not use color ''alone'' to mark differences in text: they may be invisible to people with color blindness. Also, black-and-white printouts, older computer displays with fewer colors, and monochrome displays (older PDAs and cell phones) cannot show such distinctions.&lt;br /&gt;
&lt;br /&gt;
Choose colors that can be distinguished by the readers with the commonest form of colorblindness (red–green), such as &amp;lt;span style=&amp;quot;background: white; color: maroon&amp;quot;&amp;gt;maroon&amp;lt;/span&amp;gt; and &amp;lt;span style=&amp;quot;background: white; color: teal&amp;quot;&amp;gt;teal&amp;lt;/span&amp;gt;; and ''additionally'' mark the differences with change of font or some other means (&amp;lt;span style=&amp;quot;background: white; font-family: Georgia, serif; color: maroon; font face: Times New Roman&amp;quot;&amp;gt;maroon and alternative font face&amp;lt;/span&amp;gt;, &amp;lt;span style=&amp;quot;background: white; color: teal&amp;quot;&amp;gt;teal&amp;lt;/span&amp;gt;). Avoid low contrast between text and background colors. Viewing the page with [http://colorfilter.wickline.org/ Wickline] can help with the choice of colors.&lt;br /&gt;
&lt;br /&gt;
In addition to vision accessibility problems, usage of only color to encode attributes in tables instead of a separate sortable column, disables the use of the powerful wiki sortability feature on that attribute for all readers. Even for readers with unimpaired color vision, excessive background shading of table entries impedes readability and recognition of wikilinks. Background color should be used only as a ''supplementary'' visual cue, and should be subtle (consider using lighter, less-dominant pastel hues) rather than a glaring spotlight.&lt;br /&gt;
&lt;br /&gt;
===Invisible comments===&lt;br /&gt;
Editors use invisible comments to communicate with each other in the body of the text of an article. These comments are visible only in the wiki source—that is, in edit source mode, not in read mode.&lt;br /&gt;
&lt;br /&gt;
Invisible comments are useful for flagging an issue or leaving instructions about part of the text, where this is more convenient than raising the matter on the talk page. They should be used judiciously, because they can clutter the wiki source for other editors. Check that your invisible comment does not change the formatting, for example by introducing white space in read mode.&lt;br /&gt;
&lt;br /&gt;
To leave an invisible comment, enclose the text you intend to be read only by editors between &amp;lt;code&amp;gt;&amp;amp;lt;!--&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;--&amp;amp;gt;&amp;lt;/code&amp;gt;. For example: {{xt|&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&amp;lt;!--If you change this section title, please also change the links to it on the pages ...--&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
== Reference ==&lt;br /&gt;
This document contains a selection of relevant sections from {{wikipedia|Wikipedia:Manual of Style}}.&lt;br /&gt;
&lt;br /&gt;
== Related content ==&lt;br /&gt;
* [[FlightGear wiki:FlightGear screenshot categories]]&lt;br /&gt;
* {{tl|informative template}} – ''Template documentation guidelines.''&lt;br /&gt;
&lt;br /&gt;
[[Category:Wiki style guides]]&lt;/div&gt;</summary>
		<author><name>Elgaton</name></author>
	</entry>
	<entry>
		<id>https://wiki.flightgear.org/w/index.php?title=FlightGear_wiki:Manual_of_Style&amp;diff=98101</id>
		<title>FlightGear wiki:Manual of Style</title>
		<link rel="alternate" type="text/html" href="https://wiki.flightgear.org/w/index.php?title=FlightGear_wiki:Manual_of_Style&amp;diff=98101"/>
		<updated>2016-05-11T17:42:23Z</updated>

		<summary type="html">&lt;p&gt;Elgaton: /* Reference */ Use template for Wikipedia link&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{shortcut|FGW:MOS}}&lt;br /&gt;
&lt;br /&gt;
The '''Manual of Style''' is a style manual for all FlightGear wiki articles. It helps editors write articles with consistent, clear, and precise language, layout, and formatting. The goal is to make using this wiki easier and more intuitive. Consistent language, style, and formatting promote clarity and cohesion. Writing should be clear and concise. Plain English works best; avoid ambiguity, jargon, and vague or unnecessarily complex wording.&lt;br /&gt;
&lt;br /&gt;
Discuss style issues on [[FlightGear wiki talk:Manual of Style|the talk page]].&lt;br /&gt;
&lt;br /&gt;
== Article titles, headings, and sections ==&lt;br /&gt;
=== Article titles ===&lt;br /&gt;
* Use sentence case, not title case. The initial letter of a title is capitalized (except in rare cases, such as eBay), but otherwise, capital letters are used only where they would be used in a normal sentence ({{xt|List of developed airports}}, not {{!xt|List of Developed Airports}}). Also, keep in mind that the wiki software automatically capitalizes the initial letter of a namespace/page title in its address.&lt;br /&gt;
* Titles should be precise enough to unambiguously define the topical scope of the article ({{xt|Boeing 747}}, not {{!xt|747}}).&lt;br /&gt;
* The characters &amp;lt;code&amp;gt;# &amp;lt; &amp;gt; [ ] | { }&amp;lt;/code&amp;gt; are reserved by the wiki software and can not be used.&lt;br /&gt;
&lt;br /&gt;
=== Section organization ===&lt;br /&gt;
An article should begin with an introductory lead section, which should not contain section headings. The remainder may be divided into sections, each with a section heading (see below) that can be nested in a hierarchy. If there are at least four section headings in the article, a navigable table of contents is generated automatically and displayed between the lead and the first heading.&lt;br /&gt;
&lt;br /&gt;
=== Section headings ===&lt;br /&gt;
Equal signs are used to mark the enclosed text as a section heading: &amp;lt;code&amp;gt;== Title ==&amp;lt;/code&amp;gt; for a primary section; &amp;lt;code&amp;gt;=== Title ===&amp;lt;/code&amp;gt; for the next level (a subsection); and so on to the lowest-level subsection, with &amp;lt;code&amp;gt;===== Title =====&amp;lt;/code&amp;gt;. (The highest heading level technically possible is &amp;lt;code&amp;gt;= Title =&amp;lt;/code&amp;gt;; but do not use it in articles, because it is reserved for the automatically generated top-level heading at the top of the page containing the title of the whole article.) Spaces between the equal signs and the heading text are optional, and will not affect the way the heading is displayed. The heading must be typed on a separate line. Include one blank line above the heading, and optionally one blank line below it, for readability in the edit window (but not two or more consecutive blank lines, which will add unnecessary visible white space in the rendered page.)&lt;br /&gt;
&lt;br /&gt;
The provisions in [[#Article titles|Article titles]] (above) generally apply to section headings as well (for example, headings are in sentence case, not title case). The following points apply specifically to section headings:&lt;br /&gt;
* Headings should normally not contain links, especially where only part of a heading is linked.&lt;br /&gt;
* Section and subsection headings should preferably be unique within a page; otherwise section links may lead to the wrong place, and automatic edit summaries can be ambiguous.&lt;br /&gt;
* Citations should not be placed within or on the same line as section and subsection headings.&lt;br /&gt;
* Headings should not contain images.&lt;br /&gt;
&lt;br /&gt;
== Capital letters ==&lt;br /&gt;
Sentence case rather than title case is used in wiki article titles and section headings; see [[#Article titles|Article titles]] and [[#Section headings|Section headings]] above. For capitalization of list items, see [[#Bulleted and numbered lists|Bulleted and numbered lists]]. Other points concerning capitalization are summarized below.&lt;br /&gt;
&lt;br /&gt;
===Do not use capitals for emphasis===&lt;br /&gt;
Use italics, not capitals, to denote emphasis.&lt;br /&gt;
:''Incorrect'': {{!xt|It is not only a LITTLE learning that is dangerous}}.&lt;br /&gt;
:''Correct'': {{xt|It is not only a ''little'' learning that is dangerous}}.&lt;br /&gt;
&lt;br /&gt;
===Calendar items===&lt;br /&gt;
* '''Months, days of the week, and holidays''' start with a capital letter ({{xt|June}}, {{xt|Monday}}).&lt;br /&gt;
&lt;br /&gt;
===Celestial bodies===&lt;br /&gt;
* When used generally, the words '''&amp;lt;nowiki /&amp;gt;''sun'', ''earth'', and ''moon''&amp;lt;nowiki /&amp;gt;''' do not take capitals ({{xt|The sun was peeking over the mountain top}}), except when the term names a specific astronomical body ({{xt|The Moon orbits the Earth}}).&lt;br /&gt;
&lt;br /&gt;
===Compass points===&lt;br /&gt;
Do not capitalize '''directions''' such as ''north'', nor their related forms ({{xt|Follow the northern road}}), except where they are parts of proper names (such as {{xt|South Pole}}).&lt;br /&gt;
&lt;br /&gt;
Capitalize '''names of regions''' if they have attained proper-name status, including informal conventional names ({{xt|Southern California}} or {{xt|the Western Desert}}). Do not capitalize descriptive names for regions that have not attained the status of proper names, such as {{xt|southern Poland}}.&lt;br /&gt;
&lt;br /&gt;
(Composite directions may or may not be hyphenated, depending on the style adopted in the article. {{xt|Southeast Asia}} and {{xt|northwest}} are more common in American English; but {{xt|South-East Asia}} and {{xt|north-west}} in British English. In cases such as {{xt|north–south dialogue}} and {{xt|east–west orientation}} an en dash is used.)&lt;br /&gt;
&lt;br /&gt;
== Abbreviations ==&lt;br /&gt;
=== Write out both the full version and the abbreviation at first occurrence ===&lt;br /&gt;
* When an abbreviation is to be used in an article, give the expression in full at first, followed immediately by the abbreviation in parentheses (round brackets). In the rest of the article the abbreviation can then be used by itself:&lt;br /&gt;
::{{xt|The instrument landing system (ILS) is a ground-based instrument approach system}}, at the first mention of the instrument landing system; and&lt;br /&gt;
::{{xt|There are three categories of ILS}}, at a subsequent mention.&lt;br /&gt;
* Do not apply initial capitals in a full version simply because capitals are used in the abbreviation.&lt;br /&gt;
::{|style=&amp;quot;background:transparent&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|''Correct'': || {{xt|There are two types of flight rules: visual flight rules (VFR) and instrument flight rules (IFR).}}&lt;br /&gt;
|-&lt;br /&gt;
|''Incorrect'': || {{!xt|There are two types of flight rules: Visual Flight Rules (VFR) and Instrument Flight Rules (IFR).}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Ampersand ===&lt;br /&gt;
The ampersand (&amp;amp;) substitutes for the word ''and'' (it is a form of Latin ''et''). In normal text, ''and'' should be used instead: {{xt|version 1&amp;amp;nbsp;and&amp;amp;nbsp;2}}, not {{!xt|version 1&amp;amp;nbsp;&amp;amp;&amp;amp;nbsp;2}}. Ampersands may be used with consistency and discretion in tables, infoboxes, and similar contexts where space is limited.&lt;br /&gt;
&lt;br /&gt;
== Italics ==&lt;br /&gt;
=== Emphasis ===&lt;br /&gt;
Italics may be used ''sparingly'' to emphasize words in sentences (whereas boldface is normally not used for this purpose). Generally, the more highlighting in an article, the less its effectiveness.&lt;br /&gt;
&lt;br /&gt;
=== Quotations in italics ===&lt;br /&gt;
Quotations must always be clearly indicated as being quotations. For quotations, use only quotation marks (for short quotations) or block quoting (for long ones), not italics. (See [[#Quotations|Quotations]] below.) This means that (1) a quotation is not italicized inside quotation marks or a block quote just because it is a quotation, and (2) italics are no substitute for proper quotation formatting.&lt;br /&gt;
&lt;br /&gt;
== Quotations ==&lt;br /&gt;
Where the same quotation has been used elsewhere in the article, avoid duplicating it, which is regarded as poor style.&lt;br /&gt;
&lt;br /&gt;
The quotation should be representative of the whole source document; editors should be very careful to avoid misrepresentation of the argument in the source. Where a quotation presents rhetorical language in place of more neutral, dispassionate tone preferred for encyclopedias, it can be a backdoor method of inserting a non-neutral treatment of a controversial subject into the wiki's narrative on the subject, and should be avoided.&lt;br /&gt;
&lt;br /&gt;
Quotations should generally be worked into the article text, so as not to inhibit the pace, flow and organization of the article. Longer quotes may need to be set apart, generally through the use of wikitext templates such as {{tl|Quote}} or {{tl|Quotation}}. Longer quotations may also be hidden in the reference (footnote) to facilitate verification by other editors without sacrificing readability. For pull quotes (quotes of the article text used to highlight a section) the {{tl|Cquote}} template can be used. Quotations used only as sources to support statements contained in the article can be added with a &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;&amp;lt;ref&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; tag containing a reference formatted with the {{tl|cite web}} template; in that case, add {{tl|Appendix}} at the end of the page so that citations can be displayed in a uniform way.&lt;br /&gt;
&lt;br /&gt;
=== Original wording ===&lt;br /&gt;
Quotations must be verifiably attributed and the wording of the quoted text should be faithfully reproduced. If there is a significant error in the original statement, use {{xt|[''[[sic]]'']}} to show that the error was not made by the wiki editors. However, trivial spelling and typographic errors should simply be corrected without comment (for example, correct {{!xt|basicly}} to {{xt|basically}}), unless the slip is textually important.&lt;br /&gt;
&lt;br /&gt;
Use [[#Ellipses|ellipses]] to indicate omissions from quoted text. Legitimate omissions include extraneous, irrelevant, or parenthetical words. Do not omit text where doing so would remove important context or alter the meaning of the text. &lt;br /&gt;
&lt;br /&gt;
=== Typographic conformity ===&lt;br /&gt;
In most cases it is not desirable to duplicate the original formatting. Formatting and other purely typographical elements of quoted text should be adapted to the wiki's conventions without comment provided that doing so will not change or obscure the meaning of the text. These are alterations which make no difference when the text is read aloud, such as:&lt;br /&gt;
* Changing capitalization so that sentences begin with capital letters.&lt;br /&gt;
* When quoting a quotation that itself contains a quotation, single quotes may be replaced with double quotes, and vice versa. See [[#Quotations within quotations|Quotations within quotations]] below.&lt;br /&gt;
* Removing spaces before punctuation such as periods and colons.&lt;br /&gt;
* Generally preserve bold and italics (see [[#Italics|Italics]], above), but most other styling should be altered.&lt;br /&gt;
* Expanding abbreviations.&lt;br /&gt;
&lt;br /&gt;
=== Quotations within quotations ===&lt;br /&gt;
For quotations within quotations, use double quote marks outermost and, working inward, alternate single with double quote marks.&lt;br /&gt;
&lt;br /&gt;
=== Attribution ===&lt;br /&gt;
The author of a quote of a full sentence or more should be named; this is done in the main text and not in a footnote. A reader should not have to follow a footnote to learn whose words a quote is.&lt;br /&gt;
&lt;br /&gt;
=== Linking ===&lt;br /&gt;
As much as possible, avoid linking from within quotes, which may clutter the quotation, violate the principle of leaving quotations unchanged, and mislead or confuse the reader.&lt;br /&gt;
&lt;br /&gt;
=== Block quotations ===&lt;br /&gt;
Format a long quote (more than about 40 words or a few hundred characters, or consisting of more than one paragraph, regardless of length) as a block quotation, which the wiki's software will indent from both margins. Do not enclose block quotations in quotation marks (and especially avoid decorative quotation marks in normal use, such as those provided by the {{tl|cquote}} template, which are reserved for pull quotes; quoted sections from elsewhere in the same wiki article). Block quotations can be added with {{tl|quote}} or {{tl|quotation}}.&lt;br /&gt;
&lt;br /&gt;
=== Overusing quotations ===&lt;br /&gt;
Long quotations crowd the actual article and remove attention from other information. Many direct quotations can be minimized in length by providing an appropriate context in the surrounding text. A summary or paraphrase of a quotation is often better where the original wording could be improved. Consider minimizing the length of a quotation by paraphrasing, by working smaller portions of quotation into the article text, or both.&lt;br /&gt;
&lt;br /&gt;
Overuse happens when:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;a quotation is used without pertinence&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This means that a quotation is visually on the page, but its relevance is not explained anywhere.&lt;br /&gt;
&lt;br /&gt;
==== Specific recommendations ====&lt;br /&gt;
* Using too many quotes is incompatible with the encyclopedic writing style.&lt;br /&gt;
* As a matter of style, quoteboxes should generally be avoided as they draw special attention to the opinion of one source, and present that opinion as though the project endorses it. Instead of using quoteboxes to highlight its notability, explain its importance before introducing the quote or in an introduction to the quote.&lt;br /&gt;
* The wiki is not a list or repository of loosely associated topics such as quotations.&lt;br /&gt;
* Do not insert any number of quotations in a stand-alone quote section.&lt;br /&gt;
* A quotation that does not directly relate to the topic of the article or directly support the information as it is presented should not be used.&lt;br /&gt;
* Intersperse quotations with original prose that comments on those quotations instead of constructing articles out of quotations with little or no original prose.&lt;br /&gt;
* Longer quotations may be hidden in the reference as a footnote to facilitate verification by other editors without sacrificing readability.&lt;br /&gt;
&lt;br /&gt;
== Punctuation ==&lt;br /&gt;
&lt;br /&gt;
=== Apostrophes ===&lt;br /&gt;
* Consistent use of the straight (or ''typewriter'') apostrophe ({{xt|&amp;amp;nbsp;'&amp;amp;nbsp;}}) is recommended, as opposed to the curly (or ''typographic'') apostrophe ({{!xt|&amp;amp;nbsp;’&amp;amp;nbsp;}}).&lt;br /&gt;
&lt;br /&gt;
=== Quotation marks ===&lt;br /&gt;
;Double or single&lt;br /&gt;
: Enclose quotations with double quotation marks ({{xt|Bob said, &amp;quot;Jim ate the apple.&amp;quot;}}). Enclose quotations inside quotations with single quotation marks ({{xt|Bob said, &amp;quot;Did Jim say 'I ate the apple' after he left?&amp;quot;}}).&lt;br /&gt;
&lt;br /&gt;
;Block quotes&lt;br /&gt;
: As already noted [[#Quotations|above]], we use quotation marks or block quotes (not both) to distinguish long quotations from other text. Multiparagraph quotations are always block-quoted. The quotations must be precise and exactly as in the source (except for certain ''allowable typographical changes'', also noted [[#Typographic conformity|above]]). The source should be cited clearly and precisely.&lt;br /&gt;
&lt;br /&gt;
===Brackets and parentheses===&lt;br /&gt;
These rules apply to both round brackets {{xt|(&amp;amp;nbsp;)}}, often called parentheses, and square brackets {{xt|[&amp;amp;nbsp;]}}.&lt;br /&gt;
&lt;br /&gt;
If a sentence contains a bracketed phrase, place the sentence punctuation outside the brackets {{xt|(as shown here).}} However, where one or more sentences are wholly inside brackets, place their punctuation inside the brackets. There should be no space next to the inner side of a bracket. An opening bracket should usually be preceded by a space, for example. This may not be the case if it is preceded by an opening quotation mark, another opening bracket, or a portion of a word.&lt;br /&gt;
&lt;br /&gt;
There should be a space after a closing bracket, except where a punctuation mark follows (though a spaced dash would still be spaced after a closing bracket) and in unusual cases similar to those listed for opening brackets.&lt;br /&gt;
&lt;br /&gt;
If sets of brackets are nested, use different types for adjacent levels of nesting; for two levels, it is customary to have square brackets appear within round brackets. This is often a sign of excessively convoluted expression; it is often better to recast, linking the thoughts with commas, semicolons, colons, or dashes.&lt;br /&gt;
&lt;br /&gt;
Avoid adjacent sets of brackets. Either put the parenthetic phrases in one set separated by commas, or rewrite the sentence.&lt;br /&gt;
&lt;br /&gt;
Square brackets are used to indicate editorial replacements and insertions within quotations, though this should never alter the intended meaning. They serve three main purposes.&lt;br /&gt;
&lt;br /&gt;
====Sentences and brackets====&lt;br /&gt;
* If any sentence includes material that is enclosed in square or round brackets, it still must end—with a period, or a question or exclamation mark—''after'' those brackets. This principle applies no matter what punctuation is used within the brackets.&lt;br /&gt;
* However, if the entire sentence is within brackets, the closing punctuation falls within the brackets. (This sentence is an example.) This does not apply to matter that is added (or modified editorially) at the beginning of a sentence for clarity, which is usually in square brackets.&lt;br /&gt;
&lt;br /&gt;
=== Ellipses ===&lt;br /&gt;
An ellipsis (plural ''ellipses'') is used to indicate an omission of material from quoted text or some other omission, perhaps of the end of a sentence, often in a printed record of conversation. The ellipsis is represented by '''ellipsis points''': a set of three unspaced periods, surrounded by square brackets {{xt|[...]}}.&lt;br /&gt;
&lt;br /&gt;
== Dates and time ==&lt;br /&gt;
=== Time of day ===&lt;br /&gt;
Time of day is normally expressed in figures rather than being spelled out. Context determines whether the 12- or 24-hour clock is used.&lt;br /&gt;
* 12-hour clock times are written in the form {{xt|11:15&amp;amp;nbsp;a.m.}} and {{xt|2:30&amp;amp;nbsp;p.m.}}, or the form {{xt|11:15&amp;amp;nbsp;am}} and {{xt|2:30&amp;amp;nbsp;pm}}, with a space before the abbreviation.&lt;br /&gt;
* 24-hour clock times are written in the form {{xt|08:15}}, {{xt|22:55}}, with no suffix. Note that {{xt|00:00}} refers to midnight at the start of a date, and {{xt|24:00}} to midnight at the end of a date.&lt;br /&gt;
&lt;br /&gt;
=== Days ===&lt;br /&gt;
* For full dates, use the format {{xt|10 June 1921}} or the format {{xt|June 10, 1921}}. Similarly, where the year is omitted, use {{xt|10 June}} or {{xt|June 10}}. For choice of format, see below.&lt;br /&gt;
* Do not use numerical date formats such as {{!xt|03/04/2005}}, as this could refer to 3&amp;amp;nbsp;April or to March&amp;amp;nbsp;4. If a numerical format is required (e.g. for conciseness in long lists and tables), use the YYYY-MM-DD format: {{xt|2005-04-03}}.&lt;br /&gt;
&lt;br /&gt;
==== Choice of format ====&lt;br /&gt;
* All the dates in a given article should have the same format (day-month or month-day). These requirements do not apply to dates in quotations or titles.&lt;br /&gt;
* Otherwise, do not change an article from one form to another without good reason.&lt;br /&gt;
&lt;br /&gt;
=== Months ===&lt;br /&gt;
* For month and year, write {{xt|June 1921}}, with no comma.&lt;br /&gt;
* Abbreviations for months, such as {{xt|Feb}}, are used only where space is extremely limited. Such abbreviations should use three letters only, and should not be followed by a period (full stop) except at the end of a sentence.&lt;br /&gt;
&lt;br /&gt;
=== Years and longer periods ===&lt;br /&gt;
* Do not use ''the year'' before the digits ({{xt|1995}}, not {{!xt|the year 1995}}), unless the meaning would otherwise be unclear.&lt;br /&gt;
* Decades are written in the format {{xt|the 1980s}}, with no apostrophe. Use the two-digit form ('80s) only with an established social or cultural meaning. Avoid forms such as {{!xt|the 1700s}} that could refer to 10 or 100 years.&lt;br /&gt;
&lt;br /&gt;
=== Current ===&lt;br /&gt;
Use of the term &amp;quot;current&amp;quot; should be avoided. What is current today may not be tomorrow; situations change over time. Instead, use date- and time-specific text.&lt;br /&gt;
:{|style=&amp;quot;background:transparent&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|''Incorrect'':||{{!xt|FlightGear 3.0 is currently the latest version ...}}&lt;br /&gt;
|-&lt;br /&gt;
|''Correct'':||{{xt|As of February 2014, FlightGear 3.0 is the latest version ...}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Numbers ==&lt;br /&gt;
* In general, write whole numbers from one to nine as words, write other numbers that take two words or fewer to say as either figures or words (with consistency within each article), and write all other numbers as figures: {{xt|1/5}} or {{xt|one-fifth}}, {{xt|84}} or {{xt|eighty-four}}, {{xt|200}} or {{xt|two hundred}}, but {{xt|3.75}}, {{xt|544}}, {{xt|21&amp;amp;nbsp;million}}.&lt;br /&gt;
* In general, use a comma to delimit numbers with five or more digits to the left of the decimal point. Numbers with four digits are at the editor's discretion: {{xt|12,345}}, but either {{xt|1,000}} or {{xt|1000}}.&lt;br /&gt;
* In general, use decimals rather than vulgar fractions with measurements.&lt;br /&gt;
* Write out &amp;quot;million&amp;quot; and &amp;quot;billion&amp;quot; on the first use. After that, unspaced &amp;quot;M&amp;quot; can be used for millions and &amp;quot;bn&amp;quot; for billions: {{xt|70M}} and {{xt|25bn}}.&lt;br /&gt;
* Write {{xt|3%}}, {{xt|three percent}}, or {{xt|three per cent}}, but not {{!xt|3 %}} (with a space) or {{!xt|three %}}. &amp;quot;Percent&amp;quot; is American usage, and &amp;quot;per cent&amp;quot; is British usage. In ranges of percentages written with an en dash, write only one percent sign: {{xt|3–14%}}.&lt;br /&gt;
&lt;br /&gt;
==Units of measurement==&lt;br /&gt;
* The main unit in which a quantity is expressed should generally be an SI unit or non-SI unit officially accepted for use with the SI.&lt;br /&gt;
* In a direct quotation, always keep the source units. If a conversion is required, it should appear within square brackets in the quote, or else an obscure use of units can be explained in a footnote.&lt;br /&gt;
* Where space is limited (such as tables, infoboxes, parenthetical notes, and mathematical formulas) use unit symbols. In main text it is usually better to spell out unit names, but symbols may also be used when a unit (especially one with a long name) is used repeatedly. However, spell out the first instance of each unit in an article (for example, {{xt|the typical batch is 250 kilograms&amp;amp;nbsp;... and then 15&amp;amp;nbsp;kg of emulsifier is added}}), except for unit names that are hardly ever spelled out (e.g. the degree Celsius). Most unit names are not capitalized. Use &amp;quot;per&amp;quot; when writing out a unit, rather than a slash: {{xt|meter per second}}, not {{!xt|meter/second}}.&lt;br /&gt;
* Potentially unfamiliar unit symbols should be introduced parenthetically at their first occurrence in the article, with the full name given first: for example, {{xt|His initial betatron reached energies of 2.3 megaelectronvolts (MeV), while subsequent betatrons achieved 300&amp;amp;nbsp;MeV.}}&lt;br /&gt;
* When dimensions are given, each number should be followed by a unit name or symbol (e.g. write {{xt|1&amp;amp;nbsp;m × 3&amp;amp;nbsp;m × 6&amp;amp;nbsp;m}}, not {{!xt|1 × 3 × 6&amp;amp;nbsp;m}}).&lt;br /&gt;
* When they form a compound adjective, values and unit names should be separated by a hyphen: for example, {{xt|a five-day race}}.&lt;br /&gt;
* Unit symbols are preceded by figures, not by spelled-out numbers. Values and unit symbols are separated by a non-breaking space. For example, {{xt|5&amp;amp;nbsp;min}}. The percent sign, and units of degrees, minutes, and seconds ''for angles and coordinates'', are unspaced.&lt;br /&gt;
* Standard unit symbols do not require a full stop (period). However non-standard abbreviations should always be given a full stop.&lt;br /&gt;
* No ''s'' is appended, e.g. {{xt|km}}, {{xt|in}}, {{xt|lb}}, not {{!xt|kms}}, {{!xt|ins}}, {{!xt|lbs}}.&lt;br /&gt;
* Write powers of unit symbols with HTML, e.g. {{xt|&amp;lt;nowiki&amp;gt;5&amp;amp;nbsp;km&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;&amp;lt;/nowiki&amp;gt;}} not Unicode superscripts and subscripts.&lt;br /&gt;
* For quantities of bytes and bits, specify whether the binary or decimal meanings of K, M, G, etc. are intended.&lt;br /&gt;
&lt;br /&gt;
== Grammar and usage ==&lt;br /&gt;
=== First-person pronouns ===&lt;br /&gt;
Wiki articles must not be based on one person's opinions or experiences. The use of ''I'', ''my'', or similar forms is restricted to user pages and quotations. Also avoid ''we'', ''us'', and ''our'': {{!xt|We should note that some critics have argued against our proposal}} (personal rather than encyclopedic).&lt;br /&gt;
&lt;br /&gt;
== Vocabulary ==&lt;br /&gt;
=== Contractions ===&lt;br /&gt;
Uncontracted forms such as {{xt|do not}} or {{xt|it is}} are the default in encyclopedic style; {{!xt|don't}} and {{!xt|it's}} are too informal.&lt;br /&gt;
&lt;br /&gt;
=== Foreign terms ===&lt;br /&gt;
Foreign words should be used sparingly.&lt;br /&gt;
&lt;br /&gt;
==== No common usage in English ====&lt;br /&gt;
Use italics for phrases in other languages and for isolated foreign words that are not current in English.&lt;br /&gt;
&lt;br /&gt;
==== Common usage in English ====&lt;br /&gt;
Loanwords and borrowed phrases that have common usage in English ({{xt|vice versa}}) do not require italics. A rule of thumb is not to italicize words that appear unitalicized in major English-language dictionaries.&lt;br /&gt;
&lt;br /&gt;
=== Technical language ===&lt;br /&gt;
Some topics are intrinsically technical, but editors should try to make them understandable to as many readers as possible. Minimize jargon, or at least explain it. For unavoidably technical articles a separate introductory article may be the best solution. Avoid excessive ''wikilinking'' (linking within the wiki) as a substitute for parenthetic explanations such as the one in this sentence. Do not introduce new and specialized words simply to teach them to the reader when more common alternatives will do. When the notions named by jargon are too complex to concisely explain in a few parenthetical words, write one level down. For example, consider adding a brief background section with {{tl|main}} tags pointing to the full treatment article(s) of the prerequisite notions; this approach is practical only when the prerequisite concepts are central to the exposition of the article's main topic, and when such prerequisites aren't too numerous.&lt;br /&gt;
&lt;br /&gt;
=== Geographical items ===&lt;br /&gt;
Places should generally be referred to consistently by the same name as in the title of their article. Exceptions are made if there is a widely accepted historical English name appropriate to the given context. In cases where such a historical name is used, it should be followed by the modern name in round brackets (parentheses) on the first occurrence of the name in applicable sections of the article. This resembles linking; it should not be done to the detriment of style. On the other hand, it is probably better to provide such a variant too often than too rarely. If more than one historical name is applicable for a given context, the other names should be added after the modern English name, that is: &amp;quot;historical name (modern name, other historical names)&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Images ==&lt;br /&gt;
* Infoboxes, images, and related content in the lead must be right-aligned.&lt;br /&gt;
* Use captions to clarify the relevance of the image to the article (see [[#Captions|Captions]], below).&lt;br /&gt;
* Each image should be inside the major section to which it relates (within the section defined by the most recent level 2 heading or at the top of the lead), not immediately above the section heading.&lt;br /&gt;
* Avoid sandwiching text between two images that face each other, and between an image and an infobox or similar.&lt;br /&gt;
* The thumbnail option may be used (&amp;quot;&amp;lt;code&amp;gt;thumb&amp;lt;/code&amp;gt;&amp;quot;), or another size may be fixed. The default thumbnail width is 220&amp;amp;nbsp;pixels; users can adjust this in their preferences. Lead images should be no wider than &amp;quot;upright=1.35&amp;quot; (by default this is 300 pixels).&lt;br /&gt;
* Avoid referring to images as being on the left or right. Image placement is different for viewers of the mobile version of the wiki and might change in the future. Instead, use captions to identify images.&lt;br /&gt;
&lt;br /&gt;
=== Avoid entering textual information as images ===&lt;br /&gt;
Textual information should almost always be entered as text rather than as an image. True text can be colored and adjusted with CSS tags and templates, but text in images cannot be. Images are not searchable and are slower to download. Any important textual information in an image should also appear in the image's alt text, caption, or other nearby text.&lt;br /&gt;
&lt;br /&gt;
=== Captions ===&lt;br /&gt;
Photographs and other graphics should always have captions, unless they are &amp;quot;self-captioning&amp;quot; images or when they are unambiguous depictions of the subject of the article.&lt;br /&gt;
&lt;br /&gt;
==== Formatting of captions ====&lt;br /&gt;
* Captions normally start with a capital letter.&lt;br /&gt;
* Most captions are not complete sentences, but merely sentence fragments that should not end with a period. If any complete sentence occurs in a caption, all sentences and any sentence fragments in that caption should end with a period.&lt;br /&gt;
* The text of captions should not be specially formatted (with italics, for example), except in ways that would apply if it occurred in the main text.&lt;br /&gt;
* Captions should be succinct; more information about the image can be included on its description page, or in the main text.&lt;br /&gt;
* Captions for technical charts and diagrams may be substantially longer than those for other images. Captions for technical images should fully describe all the elements of the image, and the image's significance.&lt;br /&gt;
&lt;br /&gt;
== Bulleted and numbered lists ==&lt;br /&gt;
* Do not use lists if a passage is read easily as plain paragraphs.&lt;br /&gt;
* Use proper wikimarkup- or template-based list code ''(see [[Help:Formatting#Lists and indentation]])''.&lt;br /&gt;
* Do not leave blank lines between items in a bulleted or numbered list unless there is a reason to do so, since this causes the wiki software to interpret each item as beginning a new list.&lt;br /&gt;
** Indents (such as this) are permitted if the elements are &amp;quot;Children&amp;quot; items&lt;br /&gt;
* Use numbers rather than bullets only if:&lt;br /&gt;
** A need to refer to the elements by number may arise; or&lt;br /&gt;
** The sequence of the items is critical.&lt;br /&gt;
* Use the same grammatical form for all elements in a list, and do not mix sentences and sentence fragments as elements.&lt;br /&gt;
** For example, when the elements are: &lt;br /&gt;
*** ''Complete sentences'', each one is formatted with sentence case (its first letter is capitalized) and a final period (full stop).&lt;br /&gt;
*** ''Sentence fragments'', the list is typically introduced by a lead fragment ending with a colon. &lt;br /&gt;
*** ''Titles of works'', they retain the original capitalization of the titles.  &lt;br /&gt;
*** ''Other elements'', they are formatted consistently in either sentence case or lower case.&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
=== Wikilinks ===&lt;br /&gt;
'''Make [[Help:Formatting#Links|links]] only where they are relevant and helpful in the context:''' Excessive use of hyperlinks can be distracting and may slow the reader down. Redundant links clutter the page and make future maintenance harder. High-value links that ''are'' worth pursuing should stand out clearly.&lt;br /&gt;
&lt;br /&gt;
'''Linking to sections:''' A hash sign&amp;amp;nbsp;(#) followed by the appropriate heading will lead to a relevant part of a page. For example, &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;[[FlightGear#History]]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; links to a particular section of the article [[FlightGear]].&lt;br /&gt;
&lt;br /&gt;
'''Initial capitalization:''' The wiki software does not require that wikilinks begin with an upper-case character. Only capitalize the first letter where this is naturally called for.&lt;br /&gt;
&lt;br /&gt;
'''Linking in discussion pages:''' When adding a wikilink to a discussion page, it is preferable to use [[Help:Formatting#Permalinks_and_links_to_diffs|permalinks]] instead of ordinary links, since the content may have changed a lot before the next reader reads the comment. To highlight a specific edit, it might also be useful to link to a [[Help:Formatting#Permalinks_and_links_to_diffs|diff]].&lt;br /&gt;
&lt;br /&gt;
=== External links ===&lt;br /&gt;
Do not use external links in the body of an article. Articles can include an ''external links'' section at the end, pointing to further information outside the wiki as distinct from citing sources. The standard format is a primary heading, &amp;lt;code&amp;gt;==External links==&amp;lt;/code&amp;gt;, followed by a bulleted list of links. Identify the link and briefly indicate its relevance to the article: avoid linking to commercial and unrelated web sites, in essence ''spam''. For example:&lt;br /&gt;
:&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;* [http://flightgear.org Official website]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
:&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;* [https://sourceforge.net/p/flightgear/codetickets/ Bug tracker]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
These will appear as:&lt;br /&gt;
:* [http://flightgear.org Official website]&lt;br /&gt;
:* [https://sourceforge.net/p/flightgear/codetickets/ Bug tracker]&lt;br /&gt;
&lt;br /&gt;
== Miscellaneous ==&lt;br /&gt;
=== Keep markup simple ===&lt;br /&gt;
The simplest markup is often the easiest to edit, the most comprehensible, and the most predictable. Markup may appear differently in different browsers. Use HTML and CSS markup sparingly; in particular, do not use the CSS &amp;lt;code&amp;gt;float&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;line-height&amp;lt;/code&amp;gt; properties because they break rendering on some browsers when large fonts are used.&lt;br /&gt;
&lt;br /&gt;
An HTML entity is sometimes better than the equivalent Unicode character, which may be difficult to identify in edit mode; for example, &amp;lt;code&amp;gt;&amp;amp;amp;Alpha;&amp;lt;/code&amp;gt; is understood where &amp;lt;code&amp;gt;Α&amp;lt;/code&amp;gt; (the upper-case form of Greek &amp;lt;code&amp;gt;α&amp;lt;/code&amp;gt;) may not be.&lt;br /&gt;
&lt;br /&gt;
=== Use templates ===&lt;br /&gt;
Make use of [[:Category:Templates|existing templates]] whenever possible to ensure articles are styled in a uniform way. See [[Help:Templates|the Templates Help page]] for a quick introduction to templates.&lt;br /&gt;
&lt;br /&gt;
=== Formatting issues ===&lt;br /&gt;
Modifications in font size, blank space, and color (see [[#Color coding|Color coding]], below) are an issue for the wiki site-wide style sheet, and should be reserved for special cases only.&lt;br /&gt;
&lt;br /&gt;
Typically, the use of custom font styles will:&lt;br /&gt;
* reduce consistency, since the text will no longer look uniform;&lt;br /&gt;
* reduce usability, since it might be impossible for people with custom style sheets (for accessibility reasons, for example) to override it, and it might clash with a different skin as well as inconvenience people with color blindness (see below); and&lt;br /&gt;
* cause disputes, since other editors may disagree aesthetically with the choice of style.&lt;br /&gt;
&lt;br /&gt;
Outside article text, different font sizes are routinely used in navigation templates and infoboxes, tables (especially in larger ones), and some other contexts where alternatives are not available (such as table captions). Specify font sizes ''relatively'' (for example in CSS with &amp;lt;code&amp;gt;font-size: 80%&amp;lt;/code&amp;gt;) rather than ''absolutely'' (like &amp;lt;code&amp;gt;font-size: 8pt&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
==== Color coding ====&lt;br /&gt;
Information should be accessible to all. Do not use color ''alone'' to mark differences in text: they may be invisible to people with color blindness. Also, black-and-white printouts, older computer displays with fewer colors, and monochrome displays (older PDAs and cell phones) cannot show such distinctions.&lt;br /&gt;
&lt;br /&gt;
Choose colors that can be distinguished by the readers with the commonest form of colorblindness (red–green), such as &amp;lt;span style=&amp;quot;background: white; color: maroon&amp;quot;&amp;gt;maroon&amp;lt;/span&amp;gt; and &amp;lt;span style=&amp;quot;background: white; color: teal&amp;quot;&amp;gt;teal&amp;lt;/span&amp;gt;; and ''additionally'' mark the differences with change of font or some other means (&amp;lt;span style=&amp;quot;background: white; font-family: Georgia, serif; color: maroon; font face: Times New Roman&amp;quot;&amp;gt;maroon and alternative font face&amp;lt;/span&amp;gt;, &amp;lt;span style=&amp;quot;background: white; color: teal&amp;quot;&amp;gt;teal&amp;lt;/span&amp;gt;). Avoid low contrast between text and background colors. Viewing the page with [http://colorfilter.wickline.org/ Wickline] can help with the choice of colors.&lt;br /&gt;
&lt;br /&gt;
In addition to vision accessibility problems, usage of only color to encode attributes in tables instead of a separate sortable column, disables the use of the powerful wiki sortability feature on that attribute for all readers. Even for readers with unimpaired color vision, excessive background shading of table entries impedes readability and recognition of wikilinks. Background color should be used only as a ''supplementary'' visual cue, and should be subtle (consider using lighter, less-dominant pastel hues) rather than a glaring spotlight.&lt;br /&gt;
&lt;br /&gt;
===Invisible comments===&lt;br /&gt;
Editors use invisible comments to communicate with each other in the body of the text of an article. These comments are visible only in the wiki source—that is, in edit source mode, not in read mode.&lt;br /&gt;
&lt;br /&gt;
Invisible comments are useful for flagging an issue or leaving instructions about part of the text, where this is more convenient than raising the matter on the talk page. They should be used judiciously, because they can clutter the wiki source for other editors. Check that your invisible comment does not change the formatting, for example by introducing white space in read mode.&lt;br /&gt;
&lt;br /&gt;
To leave an invisible comment, enclose the text you intend to be read only by editors between &amp;lt;code&amp;gt;&amp;amp;lt;!--&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;--&amp;amp;gt;&amp;lt;/code&amp;gt;. For example: {{xt|&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&amp;lt;!--If you change this section title, please also change the links to it on the pages ...--&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
== Reference ==&lt;br /&gt;
This document contains a selection of relevant sections from {{wikipedia|Wikipedia:Manual_of_Style}}.&lt;br /&gt;
&lt;br /&gt;
== Related content ==&lt;br /&gt;
* [[FlightGear wiki:FlightGear screenshot categories]]&lt;br /&gt;
* {{tl|informative template}} – ''Template documentation guidelines.''&lt;br /&gt;
&lt;br /&gt;
[[Category:Wiki style guides]]&lt;/div&gt;</summary>
		<author><name>Elgaton</name></author>
	</entry>
</feed>