Utente:Codicorumus/WWH counter main.js

Da Wikinotizie, le notizie a contenuto aperto

Nota: dopo aver pubblicato, potrebbe essere necessario pulire la cache del proprio browser per vedere i cambiamenti.

  • Firefox / Safari: tieni premuto il tasto delle maiuscole Shift e fai clic su Ricarica, oppure premi Ctrl-F5 o Ctrl-R (⌘-R su Mac)
  • Google Chrome: premi Ctrl-Shift-R (⌘-Shift-R su un Mac)
  • Internet Explorer / Edge: tieni premuto il tasto Ctrl e fai clic su Aggiorna, oppure premi Ctrl-F5
  • Opera: premi Ctrl-F5.
/*
 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 *
 *  [it] / [en]
 *  ... but ... do not rely too much on my English :-)
 *
 *
 *  -- Licenza / Licencing --
 *
 *  Script pubblicato con licenza / Script licenced under :
 *      "Creative Commons Attribution 2.5" (CC BY 2.5) [http://creativecommons.org/licenses/by/2.5/]
 *  Autore / Author :
 *      Codicorumus [http://it.wikinews.org/wiki/Utente:Codicorumus]
 *  Prima pubblicazione / First published in :
 *      http://it.wikinews.org/wiki/Utente:Codicorumus/WWH_counter.js
 *  Versione corrente in
 *  (al precedente indirizzo ora c'è uno script che aggiorna i dati e poi lancia questo)
 *    /
 *  Current version is in
 *  (at previous address there is now a script which updates data and then loads this)
 *      http://it.wikinews.org/wiki/Utente:Codicorumus/WWH_counter_main.js
 *
 *
 *  -- Garanzia / Warrant --
 *
 *  Il codice e' reso disponibile cosi' come e', nessuna garanzia e' fornita sul suo funzionamento.
 *    /
 *  The code is made available as is, no guarantee is provided on its operation.
 *
 *
 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 *
 *  [it]
 *
 *  Questo script inserisce nella pagina
 *      http://www.wikipedia.de/wke/Special:PetitionList
 *      (e quelle con parametri)
 *  una tabella con il conteggio per nazione delle sottoscrizioni alla petizione,
 *  e fornisce il wikicode necessario per replicare la tabella.
 *
 *  Per ulteriori elaborazioni, i dati sono disponibili
 *  nell'oggetto 'window.PerCountryCounterScript'
 *
 *  Il codice puo' essere esaminato al meglio con un editor
 *  che supporta il code folding delle funzioni con nome.
 *
 *
 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 *
 *  [en]
 *  ... see again line 5
 *
 *  This script inserts in page
 *      http://www.wikipedia.de/wke/Special:PetitionList
 *      (and those with parameters)
 *  a table containing the count by country of petition signatures,
 *  and provides wikicode required to replicate same table.
 *
 *  Further processing can be done, by the data available
 *  in the object 'window.PerCountryCounterScript'
 *
 *  Best code view can be obtained with an editor
 *  which provides code folding of named functions.
 *
 *
 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 *
 *  about data in function setOldCounters() :
 *
 *  signatures data are updated up to 13:34 (UTC) 25 August 2011
 *
 *  population data (mostly with July 2011 est.) are from
 *      https://www.cia.gov/library/publications/the-world-factbook/rankorder/2119rank.html
 *      https://www.cia.gov/library/publications/the-world-factbook/rankorder/rawdata_2119.txt
 *
 *  key      = country name
 *  value[0] = number of signatures
 *  value[1] = population figure
 *
 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 */


// exits if jQuery is not avalaible
if ( typeof $ != 'function' || typeof $( 'body' ).jquery != 'string' ) {
  console.log( 'PerCountryCounterScript aborted : jQuery not avalaible' );
  throw 'PerCountryCounterScript aborted : jQuery not avalaible';
}

$( function mainCode() {

  // exits if it's wrong page
  var body = $( 'body.mediawiki.page-Special_PetitionList' );
  if ( typeof body != 'object'  ||  typeof body.size != 'function'  ||  body.length == 0 ) {
    console.log( 'PerCountryCounterScript Aborted : you\'re in wrong page' );
    return;
  }

  var
  // stage-variable values
  stage = 1,
  stageDescription = 'main script',
  nextStageScriptUrl = null,
  // global object : built at stage 0, retrieved at others
  Pcc,
  // global names for 'Pcc' :
  // default values are fixed at any stage, but could be patched at stage 0
  pccS, pccL;

  // this function is the same at any stage
  ( function setGlobalObject() {
    // stage-specific tasks are included, but the most specific must be outside

    // these default values are fixed at any stage, but could be patched at stage 0
    pccS = 'Pcc';
    pccL = 'PerCountryCounterScript';
    // fixed-value at any stage
    var uuid = '0bccbaba-2da8-4f42-9aa1-115160719149';

    function tryNames( patch ) {

      function checkType( type, property ) {

        if ( typeof property != 'string' ) {
          return typeof window[pccSPatch] == type
          && typeof window[pccLPatch] == type;
        } else {
          return typeof window[pccSPatch][property] == type
          && typeof window[pccLPatch][property] == type;
        }

      }

      function checkValue( property, value ) {

        return checkType( typeof value, property )
        && window[pccSPatch][property] == value
        && window[pccLPatch][property] == value;

      }

      // if patch == '' tries default names

      var
      pccSPatch = pccS + patch,
      pccLPatch = pccL + patch;

      // patched names are yet unused
      if ( checkType( 'undefined' ) && stage == 0 ) return true;

      if ( checkType( 'object' ) ) {
        if ( checkValue( 'uuid', uuid ) ) {
          if ( checkValue( 'stage', stage - 1 ) ) {
            // running new stage
            return true;
          }
          // script rerunning or running wrong stage
          var errorMessage = 'PerCountryCounter script aborted : rerunning or running wrong stage.';
          console.log( errorMessage );
          throw errorMessage;
        }
      }

      // patched name not fits, try next
      return false;

    }

    if ( !tryNames( '' ) ) {
      // default global names must be patched
      for ( var patchNumber = 1; true; patchNumber++ ) {
        var patch = '_' + patchNumber;
        if ( tryNames( patch ) ) {
          pccS += patch;
          pccL += patch;
          break;
        }
      }
    }

    if ( stage == 0 ) {
      Pcc = {
        'info' : info,
        'uuid' : uuid,
        'stage' : 0,
        'stages' : [ [ stageDescription, null ] ],
        'nextStageScriptUrl' : nextStageScriptUrl
      };
      window[pccS] = window[pccL] = Pcc;
    } else {
      Pcc = window[pccS];
      Pcc.stage = stage;
      Pcc.stages.push( [ stageDescription, Pcc.nextStageScriptUrl ] );
      Pcc.nextStageScriptUrl = nextStageScriptUrl;
    }

  } )();

  function sum( dict ) {

    var total = 0;
    $.each( dict, function( key, val ) {
      if ( typeof val == 'number' ) {
        total += val;
      } else {
        total += val[0];
      }
    });
    return total;

  }

  // multi-language messages (only en|it at the moment)
  var Messages = ( function setMessages() {

    var Messages = {};

    var MultiLanguageMessages = ( function setMultiLanguageMessages() {

      // general macros, that must be replaced wherever they are
      // &Pcc; >> the patched global name 'pccS'
      // &exp; >> rateDenominatorExp, as soon as it will be calculated
      // <ref-macro name> >> a note (html or wikicode) with the text of Mlm['name']
      // --- by the means of addNotes() where needed

      function urlLink( url, text, style ) {
        return '<a href="' + url +'"'
        + ( typeof style != 'string' ? '' : ' style="' + style + '"')
        + '>' + text + '</a>';
      }

      var Mlm = {};

      Mlm['language'] = {
        'it' : 'it',
        'en' : 'en'
      };

      var scriptNoteLinkOpen = '\n\
<div style="float: right; clear: both; font-size: 80%;" id="script-note-link">\n\
<a href="#script-note">\n\
',
      scriptNoteLinkClose = '\n</a>\n</div>\n',
      scriptNoteLinkText = {
        'it' : '[Nota sullo script]',
        'en' : '[Note about the script]'
      };

      Mlm['Script note link'] = {
        'it' : scriptNoteLinkOpen + scriptNoteLinkText.it + scriptNoteLinkClose,
        'en' : scriptNoteLinkOpen + scriptNoteLinkText.en + scriptNoteLinkClose
      };

      var scriptNoteOpen = '\n<div id="script-note" class="script-alert" style="margin-top: 1em">\n',
      scriptNoteClose = '\n</div>\n';
      function scriptNoteLinkLink( text ) {
        return urlLink( '#script-note-link', text, 'font-size: 80%' );
      }
      function hideScripDisplayLink( text ) {
        return urlLink( 'javascript:void()', text );
      }

      Mlm['Script note'] = {
        'it' : scriptNoteOpen + '\n\
<p>Quanto si trova tra questa nota e il link ' + scriptNoteLinkLink( scriptNoteLinkText.it )
        + ' in cima alla pagina<br />\n\
è stato inserito da uno script e non proviene direttamente dal sito che stai visitando.</p>\n\
<p>' + hideScripDisplayLink( 'Cliccando qui' )
        + ', puoi rimuovere la parte generata dallo script.<br />\n\
Se vuoi visualizzarla nuovamente, devi cliccare sulla prima riga della lista delle firme.</p>'
        + scriptNoteClose,
        'en' : scriptNoteOpen + '\n\
<p>Anything lies between this note and the link ' + scriptNoteLinkLink( scriptNoteLinkText.en )
        + ' on top of the page<br />\n\
was inserted by a script and does not come directly from the site you\'re visiting.</p>\n\
<p>By ' + hideScripDisplayLink( 'clicking here,' )
        + ' you can remove the part generated by the script.<br />\n\
If you want to show it again, you must click the first line in the list of signatures.</p>'
        + scriptNoteClose
      };

      function userPageLink( text ) {
        return urlLink( 'http://it.wikinews.org/wiki/Discussioni_utente:Codicorumus/WWH_counter.js'
          , text );
      }
      Mlm['OldCounter outdated'] = {
        'it' :
        '<p>Lo script non è aggiornato.</p>'
        + '<p>Non è perciò possibile effettuare il conteggio totale.<br />'
        + 'Riprova più tardi, oppure ' + userPageLink( 'richiedi' )
        + ' un aggiornamento dello script.</p>',
        'en' :
        '<p>The script is outdated.</p>'
        + '<p>So it can\'t make the total count.<br />'
        + 'Try again later, or ' + userPageLink( 'ask' )
        + ' for an update to the script.</p>'
      };

      var perPoterEffettuare = '<p>Per poter effettuare il conteggio totale<br />',
      inOrderToMake = '<p>In order to make the total count<br />',
      oraVieneMostrato = '<p>Ora viene mostrato il solo conteggio parziale della pagina.</p>',
      soNowYouSee = '<p>So now you see only the partial count for current page.</p>';

      Mlm['Too few signatures in page - 1'] = {
        'it' :
        perPoterEffettuare
        + 'devi essere su una pagina con almeno ',
        'en' :
        inOrderToMake
        + 'you must be on a page containing at least '
      };


      Mlm['Too few signatures in page - 2'] = {
        'it' :
        ' firme.</p>'
        + oraVieneMostrato,
        'en' :
        ' signatures.</p>'
        + soNowYouSee
      };

      Mlm['Too few signatures in page - 2 - Not in first page'] = {
        'it' :
        ' firme e che inizi dall\'ultima.</p>'
        + oraVieneMostrato,
        'en' :
        ' signatures and starting from last one.</p>'
        + soNowYouSee
      };

      Mlm['Not in first page'] = {
        'it' :
        perPoterEffettuare
        + 'devi essere su una pagina che cominci dall\'ultima firma.</p>'
        + oraVieneMostrato,
        'en' :
        inOrderToMake
        + 'you must be on a page starting with last signature.</p>'
        + soNowYouSee
      };

      Mlm['Wikicode button hide'] = {
        'it' : 'Nascondi wikicode',
        'en' : 'Hide wikicode'
      };

      Mlm['Wikicode button show'] = {
        'it' : 'Mostra wikicode',
        'en' : 'Show wikicode'
      };

      Mlm['Table button hide'] = {
        'it' : 'Nascondi tabella',
        'en' : 'Hide table'
      };

      Mlm['Table button show'] = {
        'it' : 'Mostra tabella',
        'en' : 'Show table'
      };

      Mlm['Table caption'] = {
        'it' : 'Conteggio delle adesioni per nazione',
        'en' : 'Number of signatures by country'
      };

      Mlm['Table total'] = {
        'it' : 'totale',
        'en' : 'total'
      };

      // special fix for #name="Country note"# in fixWikicode()
      // special fix for #participationRateHint# in fixWikicode()
      Mlm['Column captions - wikicode'] = {
        'it' : '\
! Ord.<br />\n\
! Nazione <ref-macro Country note><br />\n\
! Sottoscrizioni<br />\n\
! %<br />\n\
! title="#participationRateHint#" | t.p. <ref-macro Participation rate note><br />\
',
        'en' : '\
! #<br />\n\
! Country <ref-macro Country note><br />\n\
! Signatures<br />\n\
! %<br />\n\
! title="#participationRateHint#" | p.r. <ref-macro Participation rate note><br />\
'
      };

      Mlm['Column captions - table'] = {
        'it' : '<tr>\n\
<th><span style="cursor: pointer" \n\
title="Cliccando qui si aggiorna la numerazione delle righe.">Ord.</span><br /></th>\n\
<th>Nazione<ref-macro Country note><br /></th>\n\
<th>Sottoscrizioni<br /></th><th>%<br /></th>\n\
<th>t.p.<ref-macro Participation rate note><br /></th>\n\
<th><span>pop.</span><ref-macro Group note><br /></th>\n\
</tr>\
',
        'en' : '<tr>\n\
<th><span style="cursor: pointer" \n\
title="By clicking here, the row numbers will be updated.">#</span><br /></th>\n\
<th>Country<ref-macro Country note><br /></th>\n\
<th>Signatures<br /></th><th>%<br /></th>\n\
<th>p.r.<ref-macro Participation rate note><br /></th>\
<th><span>pop.</span><ref-macro Group note><br /></th>\n\
</tr>\
'
      };

      Mlm['Ref text en-de country names'] = {
        'it' : '\
Nazionalità elencate sia con la denominazione inglese che con quella tedesca. \
Nella tabella, le relative occorrenze sono riunite in un\'unica riga, \n\
con i parziali nella colonna delle nazioni e il totale nella colonna a seguire; \n\
la mancata indicazione della nazionalità è similmente divisa tra "--" e "other".\
',
        'en' : '\
Countries listed with both English and German name. \n\
Related figures are joined in a single row of the table, \n\
with partials in Country column and totals in the following one. \n\
The case of missing nationality is similarly divided between "-" and "other".\
'
      };

      Mlm['All signatures'] = {
        'it' : 'di tutte le firme',
        'en' : 'of all signatures'
      };

      Mlm['In page signatures'] = {
        'it' : 'delle firme in questa pagina',
        'en' : 'of signatures in this page'
      };

      Mlm['All/Page button'] = {
        'it' : 'tutte / pagina',
        'en' : 'all / page'
      };

      Mlm['Notes'] = {
        'it' : 'Note',
        'en' : 'Notes'
      };

      function theWorldFactbookLink( text ) {
        return urlLink( 'https://www.cia.gov/library/publications/the-world-factbook/rankorder/2119rank.html'
          , text );
      }
      function theWorldFactbookCSVLink( text ) {
        return urlLink( 'https://www.cia.gov/library/publications/the-world-factbook/rankorder/rawdata_2119.txt'
          , text );
      }
      Mlm['Country note'] = {
        'it' : 'Tenendo il puntatore del mouse sulla casella di una nazione, \n\
viene mostrato il valore della popolazione. \n\
Il dato è ricavato da ' + theWorldFactbookLink( 'The World Factbook' )
        + ' della CIA e in particolare da un ' + theWorldFactbookCSVLink( 'file CSV' )
        + ' scaricato il 5 agosto 2011; le cifre sono perlopiù stime a luglio 2011 \n\
e alcuni record sono stati unificati per corrispondere ad una indicazione di nazionalità più generica.\
',
        'en' : 'Holding the mouse pointer over a country cell, \n\
you\'ll see the corresponding population figure. \n\
Population data are obtained from ' + theWorldFactbookLink( 'The CIA World Factbook' ) + ' \n\
and were downloaded as ' + theWorldFactbookCSVLink( 'CSV file' )
        + ' on 5 August 2011; figures are mostly estimates at July 2011 \n\
and some records have been merged to fit a more generic nationality naming.\
'
      };

      Mlm['Participation rate note'] = {
        'it' : 't.p. = tasso di partecipazione, è espresso \n\
in firme per 10<sup>&exp;</sup> abitanti.<ref-macro Country note> \n\
Il denominatore del tasso è scelto in modo da avere tre cifre per il massimo valore in tabella.\
',
        'en' : 'p.r. = participation rate, which is expressed \n\
in signatures per 10<sup>&exp;</sup> inhabitants.<ref-macro Country note> \n\
The rate denominator is chosen so to set the highest value in the table as three digits long.\
'
      };

      Mlm['Participation rate hint'] = {
        'it' : 't.p. = tasso di partecipazione, in firme per 10^&exp; abitanti',
        'en' : 'p.r. = participation rate, in signatures per 10^&exp; inhabitants'
      };

      Mlm['Group note'] = {
        'it' : 'I valori in questa colonna rappresentano dei gruppi che permettono \n\
di effettuare confronti sulle altre colonne raggruppando in maniera variabile le nazioni. \n\
Il raggruppamento può essere modificato lanciando la funzione \n\
<code>&Pcc;.groupBy(&nbsp;...&nbsp;)</code><ref-macro groupBy() syntax note> \n\
che opera attraverso la media pesata dei valori \n\
\'numero di firme\', \'t.p.\', \'popolazione della nazione\' (normalizzati al valore massimo 1); \n\
questa funzione permette anche di rimuovere la colonna. \n\
Il raggruppamento presentato inizialmente mostra l\'entità della popolazione, \n\
fatto 100 il valore massimo. Il ragguppamento attuale è ottenuto con il comando \n\
<code id="nowGroupedByLong"></code> \n\
<span id="shortCommandRef">corrispondente al comando abbreviato <code id="nowGroupedByShort"></span></code>\n\
<pre id="nowGroupedByFunction" style="line-height: 1.4"></pre>\
',
        'en' : 'The values in this column represent groups that allow you to perform \n\
comparisons on the other columns &mdash; variously grouping countries. \n\
The grouping can be changed by running the function \n\
<code>&Pcc;.groupBy(&nbsp;...&nbsp;)</code><ref-macro groupBy() syntax note> \n\
which works by weighted average of the values ​​\n\
\'number of signatures\', \'p.r.\', \'country population\' (normalized to the maximum value of 1); \n\
this function also allows you to remove the column. \n\
At the start, the grouping is showing population size, \n\
with the maximum value set at 100. The current grouping is obtained by the command \n\
<code id="nowGroupedByLong"></code> \n\
<span id="shortCommandRef">equivalent to the shorter command <code id="nowGroupedByShort"></span></code>\
'
      };

      Mlm['SetGroup options'] = {
        'it' : {
          'n' : 'numero-gruppi',
          'sig-w' : 'peso-firme',
          'pr-w' : 'peso-t.p.',
          'pop-w' : 'peso-popolazione',
          'log-scale' : 'scala-logaritmica',
          '-f' : '-primo'
        },
        'en' : {
          'n' : 'groups-number',
          'sig-w' : 'signatures-weight',
          'pr-w' : 'participation-rate-weight',
          'pop-w' : 'population-weight',
          'log-scale' : 'logarithmic-scale',
          '-f' : '-first'
        }
      };

      // only here %1 %2 %3 %4 %5 #1 #2 #3 #4 #5 will be treated as macros and then replaced
      Mlm['groupBy() syntax note'] = {
        'it' : 'La funzione <code>groupBy()</code> vuole come parametro principale una stringa \n\
che deve contenere, in qualsiasi ordine, 2 o più pseudo-parametri separati da spazi. \n\
Gli pseudo-parametri possibili sono: %1 %2 %3 %4 %5 %6; \n\
possono anche essere indicati nelle forme abbreviate: #1 #2 #3 #4 #5 #6. \n\
<a id="show-more-syntax-note" href="javascript:void(0)">... [mostra il resto]</a>\n\
<span id="more-syntax-note">\n\
<a id="show-less-syntax-note" href="javascript:void(0)">[nascondi il resto della nota]</a>\n\
%1 (o #1) deve essere sempre indicato e deve essere seguito dal numero dei gruppi richiesti; \n\
deve anche essere sempre indicato almeno uno tra #2 #3 e #4, seguito dal relativo valore del peso; \n\
#5 (o %5) è facoltativo e la sua assenza comporta l\'uso di una scala lineare; \n\
anche %6 è facoltativo, se impostato, l\'ordinamento mette come primo \n\
il gruppo dei valori non calcolabili, che per default risulta ultimo. \n\
Questo parametro può anche essere una funzione; per la documentazione, \n\
cerca la funzione <code>optionsOrFunctionReplaced()</code> nel codice dello script principale \n\
(indicato nell\'array <code>'
        + pccS + '.stages</code> dalla descrizione <code>\'main script\'</code>).<br />\n\
Per esempio, <code>&Pcc;.groupBy( \'%14 %41&nbsp;\' )</code> \n\
produce 4 intervalli suddivisi linearmente in base all\'entità della popolazione, \n\
similmente fa la forma abbreviata <code>&Pcc;.groupBy( \'#14 #41&nbsp;\' )</code><br />\n\
Per mezzo di un secondo parametro è possibile modificare il titolo della colonna per adattarlo \n\
al senso del raggruppamento, prima di stampare o catturare la pagina; \n\
per esempio <code>&Pcc;.groupBy( \'\', \'indice pop.\' )</code>; \n\
inoltre, i valori <code>\'hide\'</code> e <code>\'show\'</code>, \n\
invece di modificare il titolo, rimuovono o visualizzano la colonna; \n\
mentre <code>\'stringSort\'</code>\ e <code>\'numberSort\'</code> \n\
ne modificano la modalità di ordinamento.<br />\n\
Il modo più immediato per lanciare la funzione \n\
è inserirla nella barra degli indirizzi come \n\
<code>javascript:' + pccS + '.groupBy(...)</code>\n\
</span>\n\
',
        'en' : 'The function <code>groupBy()</code> takes as main parameter a string \n\
that should contain, in any order, 2 or more pseudo-parameters separated by spaces. \n\
The pseudo-parameters are: %1 %2 %3 %4 %5 %6; \n\
they can also be given in short form: #1 #2 #3 #4 #5 #6. \n\
<a id="show-more-syntax-note" href="javascript:void(0)">... [show more]</a>\n\
<span id="more-syntax-note">\n\
<a id="show-less-syntax-note" href="javascript:void(0)">[hide the rest of the note]</a>\n\
%1 (or #1) must always be given and must be followed by the number of required groups; \n\
it must also always be given at least one between #2 #3 and #4, \n\
followed by the related value of the weight; \n\
#5 (or %5) is optional and in its absence a linear scale will be used; \n\
%6 also is optional, if it\'s given then the group of not calculable values \n\
will appear in first place rather than in last place (as it is by default). \n\
This parameter can also be set as a function; for documentation, \n\
see the function <code>optionsOrFunctionReplaced()</code> in the main-script code \n\
(identified, in the array <code>'
        + pccS + '.stages</code>, by the description <code>\'main script\'</code>).<br />\n\
For example, <code>&Pcc;.groupBy(\'%14 %41&nbsp;\')</code> \n\
will produce 4 linear ranges based on the population figure, \n\
the short form <code>&Pcc;.groupBy(\'#14 #41&nbsp;\')</code> does the same.<br /> \n\
By means of a second parameter you can change the column caption \n\
to fit the meaning of grouping, before printing or capturing the page. \n\
For example, <code>&Pcc;.groupBy( \'\', \'population rank\' )</code>. \n\
Moreover, instead of changing the title: the values \n\
​<code>\'hide\'</code> and <code>\'show\'</code> \n\
modify the column visibility; \n\
and the values <code>\'stringSort\'</code>\ and <code>\'numberSort\'</code>\n\
modify the column sort type.<br />\n\
The easiest way to run the function is to enter it into the address bar as \n\
<code>javascript:' + pccS + '.groupBy(...)</code>\n\
</span>\n\
'
      };

      return Mlm;

    } )();

    var testText = $( '.mw-spcontent > p:eq(1)' ).text();
    var testRegexIT = new RegExp( /^Di seguito vengono presentati al massimo / );
    var interfaceLanguage = testRegexIT.test( testText ) ? 'it' : 'en';

    $.each( MultiLanguageMessages, function eachMultiLanguageMessages( msgKey, msg) {
      // every &Pcc; occurrence will be replaced by the patched global name 'pccS'

      Messages[msgKey]
      = typeof msg[interfaceLanguage] == 'string'
      ? msg[interfaceLanguage].replace( /&Pcc;/g, pccS )
      : msg[interfaceLanguage];

    } );

    // Messages['groupBy() syntax note'] language filling
    var count = 0;
    $.each( Messages['SetGroup options'], function syntaxNoteSubst( stdOption, altOption) {

      ++count;
      Messages['groupBy() syntax note']
      = Messages['groupBy() syntax note']
      .replace( '%' + count, '&nbsp;<code style="white-space: nowrap">' + altOption + '</code>&nbsp;', 'g' )
      .replace( '#' + count, '&nbsp;<code style="white-space: nowrap">' + stdOption + '</code>&nbsp;', 'g' );

    });

    return Messages;

  } )();

  // first level old data
  // population data are from https://www.cia.gov/library/publications/the-world-factbook/rankorder/rawdata_2119.txt
  // signatures data are updated up to 13:34 (UTC) 25 August 2011
  Pcc.OldCounters = ( function setOldCounters() {

    return {
'&amp;lt;petitionpage-fromcountry-dropdown&amp;gt;':[1,0],
'--':[9,0],
'Afghanistan':[4,29835392],
'Albania':[60,2994667],
'Algeria':[7,34994937],
'American Samoa':[0,67242],
'Andorra':[2,84825],
'Angola':[1,13338541],
'Anguilla':[0,15094],
'Antarctica':[0,0],
'Antigua And Barbuda':[1,87884],
'Argentina':[398,41769726],
'Armenia':[5,2967975],
'Aruba':[0,106113],
'Ascension':[2,0],
'Australia':[102,21766711],
'Austria':[124,8217280],
'Azerbaijan':[2,8372373],
'Bahamas':[1,313312],
'Bahrain':[1,1214705],
'Bangladesh':[38,158570535],
'Barbados':[0,286705],
'Belarus':[97,9577552],
'Belgien':[18,0],
'Belgium':[109,10431477],
'Belize':[1,321115],
'Benin':[0,9325032],
'Bermuda':[0,68679],
'Bhutan':[0,708427],
'Bolivia':[13,10118683],
'Bosnia And Herzegovina':[7,4622163],
'Botswana':[1,2065398],
'Bouvet Island':[0,0],
'Brazil':[732,203429773],
'Brunei Darussalam':[0,401890],
'Bulgaria':[37,7093635],
'Burkina Faso':[0,16751455],
'Burundi':[0,10216190],
'Cambodia':[0,14701717],
'Cameroon':[0,19711291],
'Canada':[180,34030589],
'Cape Verde':[2,516100],
'Cayman Islands':[0,51384],
'Central African Republic':[0,4950027],
'Chad':[0,10758945],
'Chile':[84,16888760],
'China':[93,1336718015],
'Christmas Island':[0,1402],
'Cocos (keeling) Islands':[0,596],
'Colombia':[86,44725543],
'Comoros':[0,794683],
'Congo':[1,75956796],
'Cook Islands':[1,11124],
'Costa Rica':[22,4576562],
'Create Britain':[0,0],
'Croatia':[51,4483804],
'Cuba':[7,11087330],
'Cyprus':[7,1120489],
'Czech Republic':[44,10190213],
'CÔte D\'ivoire':[0,21504162],
'Denmark':[27,5529888],
'Deutschland':[14955,0],
'Diego Garcia':[0,0],
'Djibouti':[0,757074],
'Dominica':[0,72969],
'Dominican Republic':[20,9956648],
'Dänemark':[6,0],
'Ecuador':[38,15007343],
'Egypt':[12,82079636],
'El Salvador':[10,6071774],
'Equatorial Guinea':[0,668225],
'Eritrea':[0,5939484],
'Estonia':[11,1282963],
'Ethiopia':[0,90873739],
'Europäische Union':[6,0],
'Falkland Islands (malvinas)':[0,3140],
'Faroe Islands':[1,49267],
'Fiji':[0,883125],
'Finland':[39,5259250],
'France':[247,65312249],
'French Guiana':[0,0],
'French Polynesia':[0,294935],
'Gabon':[0,1576665],
'Gambia':[0,1797860],
'Georgia':[11,4585874],
'Germany':[648,81471834],
'Ghana':[2,24791073],
'Gibraltar':[0,28956],
'Greece':[63,10760136],
'Greenland':[0,57670],
'Grenada':[0,108419],
'Guadeloupe':[0,0],
'Guam':[0,0],
'Guatemala':[7,13824463],
'Guernsey':[0,65068],
'Guinea':[0,10601009],
'Guinea-bissau':[1,1596677],
'Guyana':[0,744768],
'Haiti':[0,9719932],
'Heard Island And Mcdonald Islands':[0,0],
'Holy See (vatican City State)':[0,832],
'Honduras':[4,8143564],
'Hong Kong':[20,7122508],
'Hungary':[52,9976062],
'Iceland':[7,311058],
'India':[336,1189172906],
'Indonesia':[12,245613043],
'Iran, Islamic Republic Of':[113,77891220],
'Iraq':[0,30399572],
'Ireland':[43,4670976],
'Israel':[40,7473052],
'Italy':[24080,61016804],
'Jamaica':[12,2868380],
'Japan':[37,126475664],
'Jersey':[2,94161],
'Jordan':[2,6508271],
'Kanarische Inseln':[0,0],
'Kazakhstan':[23,15522373],
'Kenya':[3,41070934],
'Kiribati':[0,100743],
'Kuwait':[0,2595628],
'Kyrgyzstan':[3,5587443],
'Lao People\'s Democratic Republic':[0,6477211],
'Latvia':[15,2204708],
'Lebanon':[6,4143101],
'Lesotho':[0,1924886],
'Liberia':[0,3786764],
'Libyan Arab Jamahiriya':[0,6597960],
'Liechtenstein':[4,35236],
'Lithuania':[38,3535547],
'Luxembourg':[26,503302],
'Luxemburg':[35,0],
'Macao':[5,573003],
'Macedonia, The Former Yugoslav Republic Of':[10,2077328],
'Madagascar':[0,21926221],
'Malawi':[1,15879252],
'Malaysia':[16,28728607],
'Maldives':[1,394999],
'Mali':[0,14159904],
'Malta':[8,408333],
'Marshall Islands':[0,67182],
'Martinique':[0,0],
'Mauritania':[1,3281634],
'Mauritius':[1,1303717],
'Mayotte':[0,0],
'Mexico':[181,113724226],
'Micronesia':[0,106836],
'Moldova':[17,4314377],
'Monaco':[1,30539],
'Mongolia':[1,3133318],
'Montserrat':[1,5140],
'Morocco':[12,31968361],
'Mozambique':[2,22948858],
'Myanmar':[0,53999804],
'Namibia':[1,2147585],
'Nauru':[0,9322],
'Nepal':[14,29391883],
'Netherlands Antilles':[1,0],
'Netherlands':[250,16847007],
'Neutrale Zone':[0,0],
'New Caledonia':[0,256275],
'New Zealand':[18,4290347],
'Nicaragua':[1,5666301],
'Niger':[0,16468886],
'Nigeria':[4,155215573],
'Niue':[0,1311],
'Norfolk Island':[0,2169],
'North Korea':[0,24457492],
'Northern Mariana Islands':[0,46050],
'Norway':[31,4691849],
'Oman':[1,3027959],
'Pakistan':[8,187342721],
'Palau':[0,20956],
'Palestinian Territory':[0,4225710],
'Panama':[12,3460462],
'Papua New Guinea':[0,6187591],
'Paraguay':[11,6459058],
'Peru':[78,29248943],
'Philippines':[10,101833938],
'Pitcairn':[0,48],
'Poland':[46,38441588],
'Portugal':[202,10760305],
'Puerto Rico':[3,3989133],
'Qatar':[1,848016],
'Romania':[89,21904551],
'Russian Federation':[848,138739892],
'Rwanda':[1,11370425],
'RÉunion':[0,0],
'Saint Helena':[0,0],
'Saint Kitts And Nevis':[0,50314],
'Saint Lucia':[0,161557],
'Saint Pierre And Miquelon':[0,5888],
'Saint Vincent/Grenadines':[0,103869],
'Samoa':[0,193161],
'San Marino':[16,31817],
'Sao Tome And Principe':[0,179506],
'Saudi Arabia':[3,26131703],
'Schweiz':[452,0],
'Senegal':[1,12643799],
'Serbien und Montenegro':[36,7972362],
'Seychelles':[0,89188],
'Sierra Leone':[0,5363669],
'Singapore':[13,4740737],
'Slovakia':[5,5477038],
'Slovenia':[25,2000092],
'Solomon Islands':[1,571890],
'Somalia':[0,9925640],
'South Africa':[13,49004031],
'South Korea':[8,48754657],
'Spain':[746,46754784],
'Sri Lanka':[10,21283913],
'Sudan':[1,45047502],
'Suriname':[1,491989],
'Svalbard And Jan Mayen':[0,2019],
'Swaziland':[0,1370424],
'Sweden':[80,9088728],
'Switzerland':[338,7639961],
'Syrian Arab Republic':[1,22517750],
'Taiwan, Province Of China':[3,0],
'Taiwan':[16,23071779],
'Tajikistan':[2,7627200],
'Tanzania':[0,42746620],
'Thailand':[31,66720153],
'Timor-leste':[0,1177834],
'Togo':[0,6771993],
'Tokelau':[0,1384],
'Tonga':[0,105916],
'Trinidad And Tobago':[1,1227505],
'Tristan da Cunha':[0,0],
'Tunisia':[6,10629186],
'Turkey':[27,78785548],
'Turkmenistan':[0,4997503],
'Turks And Caicos Islands':[0,44819],
'Tuvalu':[0,10544],
'UK':[327,62698362],
'Uganda':[1,34612250],
'Ukraine':[268,45134707],
'United Arab Emirates':[11,5148664],
'United States':[748,313232044],
'Uruguay':[33,3308535],
'Uzbekistan':[3,28128600],
'Vanuatu':[0,224564],
'Venezuela':[100,27635743],
'Viet Nam':[16,90549390],
'Virgin Islands, U.s.':[0,109666],
'Wallis And Futuna':[1,15398],
'Western Sahara':[0,507160],
'Yemen':[0,24133492],
'Zambia':[1,13881336],
'Zimbabwe':[1,12084304],
'other':[42,0],
'Åland Islands':[0,0],
'Österreich':[1034,0]
};

  } )();

  // given the json-like part for 'setOldCounters()', returns the text for the whole function
  function getOldCountersString( jsonString ) {

    return '\
  Pcc.OldCounters = ( function setOldCounters() {\n\
\n\
    return ' + jsonString + ';\n\
\n\
  } )();\n';

  }

  // updates Pcc.OldCounters with data from launcher script (stage 0)
  Pcc.OldCountersActuallyUpdated = ( function updateOldCounters() {

    // key = country
    // value = previous population data, if updated
    // value = null, if new country added
    var OldCountersActuallyUpdated = {};

    if ( Pcc.OldCountersUpdate ) {
      $.each( Pcc.OldCountersUpdate, function( country, signatures ) {

        if ( country in Pcc.OldCounters ) {
          OldCountersActuallyUpdated[country] = Pcc.OldCounters[country][0];
          Pcc.OldCounters[country][0] += signatures;
        } else {
          OldCountersActuallyUpdated[country] = null;
          Pcc.OldCounters[country] = [ signatures, 0 ];
        }

      });
    }

    return OldCountersActuallyUpdated;

  } )();

  // Pcc.OldCounters is set in a previuos-stage script
  Pcc.oldCountersTotal = sum( Pcc.OldCounters );

  // sets a string of JSON-like data in Pcc.Json and then alert( it )
  // more comment inside
  Pcc.getJson = function getJson( Counters, option ) {

    // for instance, to update getOldCounters()
    //      use simply getJson(), but Pcc.pageOkForTotal must be true
    // with getJson( xCounters ) uses data from the specified xCounters
    // if option contains 'full' (provided that Counters is not given and pageOkForTotal==true)
    // - outputs a full update for function setOldCounters()
    // - else outputs a partial update for function setOldCountersUpdate() in stage 0 script
    // if option contains 'singleLine' then outputs so, else multi-line
    // if option contains 'function subst' then alerts text for whole-function substitution

    function sortJson( countryOrNumber ) {

      var arrayForSort = [], jsonSorted = {};

      $.each( Json, function( key, value ) {
        arrayForSort.push( [key, value] );
      } );

      if ( typeof countryOrNumber == 'string' && countryOrNumber == 'number' ) {
        arrayForSort.sort( function(a, b) {
          if ( typeof a[1] == 'object' ) {
            var a1 = a[1][0], b1 = b[1][0];
          } else {
            a1 = a[1], b1 = b[1];
          }
          if ( a1 == b1 ) {
            return ( a[0] < b[0] ? -1 : 1 );
          } else {
            return b1 - a1;
          }
        });
      } else {
        arrayForSort.sort();
      }

      $.each( arrayForSort, function( index, value ) {
        jsonSorted[ value[0] ] = value[1];
      } );

      Json = jsonSorted;

    }

    var recordSeparator = '\n', partialUpdate = true, wholeFunction = false;
    // decode option string
    if ( typeof option == 'string' ) {
      if ( option.indexOf( 'singleLine' ) != -1 ) recordSeparator = '';
      if ( option.indexOf( 'full' ) != -1 ) partialUpdate = false;
      if ( option.indexOf( 'function subst' ) != -1 ) wholeFunction = true;
    }

    var Json = null, updateStringRequested = false;

    //
    // if Counters is given or !pageOkForTotal // Json only assigned
    //
    if ( typeof Counters == 'object' ) {
      Json = Counters;
    } else if ( !pageOkForTotal ) {
      Json = Pcc.PageCounters;
      sortJson( 'number' );
    }

    //
    // Json must be built and pageOkForTotal==true
    //
    if ( Json == null ) {

      Json = {};
      updateStringRequested = true;

      if ( partialUpdate ) {
        // makes a copy of Pcc.NewCounters and then adds contribution of Pcc.OldCountersUpdate

        $.extend( Json, Pcc.NewCounters );
        $.each( Pcc.OldCountersActuallyUpdated, function( country, value ) {
          var partialUpdate = Pcc.OldCounters[country] - Pcc.OldCountersActuallyUpdated[country];
          if ( country in Json )
            Json[country] += partialUpdate;
          else
            Json[country] = partialUpdate;
        } );

      } else {
        // makes a copy of Pcc.OldCounters and then adds new signature's data

        $.each( Pcc.OldCounters, function( country, value ) {
          Json[country] = [ value[0], value[1] ];
        } );
        $.each( Pcc.NewCounters, function( country, value ) {
          if ( Json[country] )
            Json[country][0] += value;
          else
            Json[country] = [value, 0];
        } );

      }

      // sorts Json by country key
      sortJson( 'country' );

    }

    // sets global property
    Pcc.json =
    ( function getJsonFromObject( object, recordSeparator ) {

      var jsonString = '{' + recordSeparator;

      $.each( object, function( key, value ) {

        jsonString += "'" + key.replace( "'", "\\'" ) + '\':';

        if ( $.isArray( value ) ) {
          jsonString += '[';
          for (var item in value) {
            jsonString += value[item] + ',';
          }
          jsonString += '],' + recordSeparator;
          jsonString = jsonString.replace( ',],', '],' );
        } else {
          jsonString += value + ',' + recordSeparator;
        }

      } );

      jsonString += '}';

      // strip last comma
      return jsonString.replace( ',' + recordSeparator + '}', recordSeparator + '}' );

    }
    )( Json, recordSeparator );

    // alerts value for easily copying
    alert(
      updateStringRequested && wholeFunction
      ? ( partialUpdate ? Pcc.getOldCountersUpdateString : getOldCountersString )( Pcc.json )
      : Pcc.json
      );

  };

  ( function fix_mw_spcontent_TextNode() {
    // in fr language version (at least) what we expect in '.mw-spcontent > p:eq(0)'
    // is instead in a TextNode

    $( '.mw-spcontent' ).contents().filter( function() {
      return this.nodeType == 3 && this.textContent.indexOf( 'All Signatories' ) != -1
    } ).wrap( '<p>');

  } )();
  // gets from page the total number of signatures
  Pcc.signaturesNumber = parseInt( $( '.mw-spcontent > p:eq(0)' ).text().match(/^.+\D(\d+)\./)[1] );
  Pcc.firstSignatureInPage = parseInt( $( '.mw-spcontent > p:eq(1)' ).text().match(/^.+\D(\d+)\./)[1] );

  // country entries in page
  var countryList = $('.mw-petition-listentry-country');

  // checks if current page is suitable for the total count
  var notOkForTotalAlertText = null;
  var pageOkForTotal = ( function checkPage() {

    var totalToOldDiff = Pcc.signaturesNumber - Pcc.oldCountersTotal;
    if ( totalToOldDiff > countryList.length ) {

      notOkForTotalAlertText
      = totalToOldDiff > 5000
      ? Messages['OldCounter outdated']
      : ( Messages['Too few signatures in page - 1']
        + totalToOldDiff
        + ( Pcc.firstSignatureInPage == 1
          ? Messages['Too few signatures in page - 2']
          : Messages['Too few signatures in page - 2 - Not in first page']
          )
        );

      return false;
    }

    if ( Pcc.firstSignatureInPage > 1 ) {
      notOkForTotalAlertText = Messages['Not in first page'];
      return false;
    }

    return true;

  } )();
  Pcc.pageOkForTotal = pageOkForTotal;

  // Pcc.PageCounters / all signatures in page
  // Pcc.NewCounters / signatures up to Pcc.signaturesNumber
  ( function setNewAndPageCounters() {

    Pcc.PageCounters = {};

    var feedingNewCounters = pageOkForTotal;
    if ( feedingNewCounters ) {
      Pcc.NewCounters = {};
    }

    var tempCounter = Pcc.oldCountersTotal;
    countryList.each( function eachCountryList( index, element ){

      if ( tempCounter++ == Pcc.signaturesNumber ) {
        // stop feeding NewCounters (if doing it)
        feedingNewCounters = false;
      }
      var country = $.trim(element.textContent).replace( / +/g, ' ' );
      if (Pcc.PageCounters[country]) {
        Pcc.PageCounters[country] += 1;
        if ( feedingNewCounters ) {
          Pcc.NewCounters[country] += 1;
        }
      } else {
        Pcc.PageCounters[country] = 1;
        if ( feedingNewCounters ) {
          Pcc.NewCounters[country] = 1;
        }
      }

    });

  } )();

  Pcc.pageCountersTotal = sum( Pcc.PageCounters );
  if ( pageOkForTotal ) {
    Pcc.newCountersTotal = sum( Pcc.NewCounters );
  }

  // joins Pcc.NewCounters and Pcc.OldCounters
  if ( pageOkForTotal ) {

    Pcc.OldPlusNewCounters = ( function getOldPlusNewCounters() {

      var OldPlusNewCounters = {};

      $.each( Pcc.OldCounters, function( country, val ) {
        if ( val[0] > 0 ) {
          OldPlusNewCounters[country] = val[0];
        }
      } );

      $.each( Pcc.NewCounters, function( country, val ) {
        if ( OldPlusNewCounters[country] ) {
          OldPlusNewCounters[country] += val;
        } else {
          OldPlusNewCounters[country] = val;
        }
      } );

      return OldPlusNewCounters;

    } )();

    Pcc.oldPlusNewCountersTotal = sum ( Pcc.OldPlusNewCounters );

  }

  ( function showPageItems() {

    //
    // main wikicode filling and html building
    //
    function buildTableAndWikicode ( allOrPage ) {

      // HTML and wikicode notes
      function buildNote( htmlOrWiki, noteText, noteName ) {

        //      function buildNote( htmlOrWiki, noteText, noteName, startsWith ) {

        var notesDiv = allOrPage == 'page' ? notesDivPage : notesDivAll,
        noteGroup = notesObject[allOrPage][htmlOrWiki];
        var notes = noteGroup.notes;

        var text =
        // recursive substitution
        addNotes( htmlOrWiki, noteText )
        // &exp; substitution
        .replace( /&exp;/g, rateDenominatorExp );

        // change text to the first previous note starting with 'text', if any
        //        if ( typeof startsWith == 'string' && startsWith == 'startsWith' ) {
        //          for ( var previousNote in notes ) {
        //            if ( text == previousNote.substr( 0, text.length ) ) {
        //              text = previousNote;
        //              break;
        //            }
        //          }
        //        }

        if ( notes[text] ) {
          ++notes[text];           //  multiple references to this note
        } else {
          notes[text] = 1;         //  not yet multiple references to this note
          noteGroup.number += 1;   //  unique notes in the group
        }

        if ( htmlOrWiki == 'html' ) {
          return ( function getHtmlNote() {

            var idLink = 'link-nota-' + allOrPage + '-' + noteGroup.number + '-' + notes[text],
            idLinkPre = 'link-nota-' + allOrPage + '-' + noteGroup.number + '-' + ( notes[text] - 1 ),
            idNota = 'nota-' + allOrPage + '-' + noteGroup.number;

            if ( notes[text] == 1 ) {
              notesDiv.append(
                $( '<p id="' + idNota + '"><a href="#' + idLink + '">'
                  + noteGroup.number + '</a> &nbsp;&nbsp;&nbsp;' + text + '</p>' )
                );
            } else {
              var linkPre = $( 'a[href=#' + idLinkPre + ']' );
              if ( notes[text] == 2 ) {
                linkPre.text( linkPre.text() + '.1' );
              }
              linkPre
              .after( $( '<a href="#' + idLink + '">' + noteGroup.number + '.' + notes[text] + '</a>' ) )
              .after( ' &nbsp;' );
            }

            // note's title, added if div is not empty (i.e. adding first note)
            if ( noteGroup.number == 1 && notes[text] == 1 ) {
              notesDiv.prepend( $( '<p><b>' + Messages['Notes'] + '</b></p>' ) );
            }

            return '<sup>&nbsp;<a id="' + idLink + '" href="#' + idNota + '">[' + noteGroup.number + ']</a></sup>';

          } )();
        } else {
          return ( function getWikicodeNote() {

            if ( notes[text] == 1 ) {
              // first note occurrence

              if ( text.indexOf( '<ref ') == -1 ) {
                // normal ref
                return '<ref group="t" name="' + noteName + '">\n' + text + '\n</ref>';
              } else {
                // ref with another ref inside
                return '{{#tag:ref|\n' + text + '\n|group=t|name=' + noteName + '\n}}';
              }

            } else {
              // new occurrence of previous note

              return '<ref group="t" name="' + noteName + '" />';

            }

          } )();
        }

      }

      function addNotes( htmlOrWiki, text ) {

        var noteRefs = text.match( /<ref-macro +[^>]+>/g );
        if ( noteRefs ) {
          for ( var noteRefIndex in noteRefs ) {
            var noteRef = noteRefs[noteRefIndex];
            var noteNameFound = noteRef.match( /<ref-macro +([^ >][^>]*[^ >]) *>/ );
            if ( noteNameFound && Messages[ noteNameFound[1] ]) {
              text = text.replace(
                noteRef,
                buildNote( htmlOrWiki, Messages[ noteNameFound[1] ], noteNameFound[1] )
                );
            }
          }
        }

        return text;

      }

      function getPopulation( country ) {

        if ( Pcc.OldCounters[country] ) {
          return Pcc.OldCounters[country][1];
        } else {
          return 0;
        }

      }

      // modifies group column
      function setGroup( table, optionsOrFunction, groupColumnDisplay ) {

        // hide, show or modify caption of group column
        if ( typeof groupColumnDisplay == 'string' ) {
          switch ( groupColumnDisplay ) {
            case 'hide':
              table.find( 'tr > *:last-child' ).hide();
              break;
            case 'show':
              table.find( 'tr > *:last-child' ).show();
              break;
            case 'numberSort':
              table.find( 'tr:eq(1) th:last-child' ).text( '0' );
              break;
            case 'stringSort':
              table.find( 'tr:eq(1) th:last-child' ).text( 'A' );
              break;
            default:
              table.find( 'tr th:last-child span:eq(0)' ).html( groupColumnDisplay );
              break;
          }
        }

        var signaturesMax = table.data( 'signaturesMax' ),
        participationRateMax = table.data( 'participationRateMax' ),
        populationMax = table.data( 'populationMax' );

        var signatures, participationRate, population;
        function getRowValues( rowElement ) {

          var row = $( rowElement );

          signatures = parseInt( row.find( 'td:eq(2)').text().replace( / /g, '' ) );
          participationRate = parseInt( row.find( 'td:eq(4)').text()
            .replace( ',', '.' )
            .replace( '-', '0' )
            );
          population = -1;
          var populationHint = row.find( 'td:eq(1)').attr( 'title' );
          if ( populationHint && !( populationHint == '-' && signaturesWeight == 0 ) ) {
            population = parseInt( populationHint.replace( / /g, '' ).replace( '-', '0' ) );
          }

        }

        if ( typeof optionsOrFunction == 'string' ) {

          var groupsNumber = 0,
          signaturesWeight = 0, participationRateWeight = 0, populationWeight = 0,
          logScale = false, dashEqMaxValue = true;
          if ( !( function decodeOptions() {

            function eqOptionNames( stdName, otherName ) {

              if ( stdName == otherName
                || otherName == Messages['SetGroup options'][stdName]
                  ) return true;
              else return false;

            }

            function stdOptionName( optionName ) {

              if ( optionName in Messages['SetGroup options'] ) {
                return optionName;
              }

              for ( var stdName in Messages['SetGroup options'] ) {
                if ( optionName == Messages['SetGroup options'][stdName] ) {
                  return stdName;
                }
              }

              return false;

            }

            function setGroupingReferencesOptions() {

              var functionCallStart = pccS + '.groupBy( \'',
              shortParameter = '_n_' + groupsNumber,
              longParameter = '_' + Messages['SetGroup options']['n'] + '_' + groupsNumber;

              if ( logScale ) {
                shortParameter += '_ ' + 'log-scale',
                longParameter += '_ ' + Messages['SetGroup options']['log-scale'];
              }

              if ( signaturesWeight != 0 ) {
                shortParameter += '_ ' + 'sig-w' + '_' + signaturesWeight,
                longParameter += '_ ' + Messages['SetGroup options']['sig-w'] + '_' + signaturesWeight;
              }

              if ( participationRateWeight != 0 ) {
                shortParameter += '_ ' + 'pr-w' + '_' + participationRateWeight,
                longParameter += '_ ' + Messages['SetGroup options']['pr-w'] + '_' + participationRateWeight;
              }

              if ( populationWeight != 0 ) {
                shortParameter += '_ ' + 'pop-w' + '_' + populationWeight,
                longParameter += '_ ' + Messages['SetGroup options']['pop-w'] + '_' + populationWeight;
              }

              if ( dashEqMaxValue == false ) {
                shortParameter += '_ ' + '-f',
                longParameter += '_ ' + Messages['SetGroup options']['-f'];
              }

              var shortRef = functionCallStart + shortParameter + '_\' )',
              longRef = functionCallStart + longParameter + '_\' )';
              var tableHeaderHint = shortRef.replace( /_/g, ' ' );

              shortRef = shortRef.replace( /_/g, '&nbsp;' );
              longRef = longRef.replace( /_/g, '&nbsp;' );

              var notesDiv = $( '#' + table.attr( 'id' ).replace( 'table', 'notes-div' ) );
              notesDiv.find( '#nowGroupedByFunction' ).hide();
              notesDiv.find( '#nowGroupedByShort' ).html( shortRef );
              notesDiv.find( '#shortCommandRef' ).show();
              notesDiv.find( '#nowGroupedByLong' )
              .html( longRef )
              .show();

              table.find( 'tr th:eq(5)').attr( 'title', tableHeaderHint );

            }

            var optionsList = $.trim( optionsOrFunction ).replace( /\s+(-?\d)/g, '_$1' ).split( /\s+/ );
            for (var singleOptionIndex in optionsList) {

              var singleOptionSplit = optionsList[singleOptionIndex].split( '_' );

              var stdOption = stdOptionName( singleOptionSplit[0] );
              if ( stdOption ) {

                if ( singleOptionSplit.length > 1 ) {
                  var value = parseFloat( singleOptionSplit[1].replace( ',', '.' ) );
                } else {
                  value = 0;
                }

                switch ( stdOption ) {
                  // with value
                  case 'n':
                    groupsNumber = Math.abs( parseInt( value ) );
                    break;
                  case 'sig-w':
                    signaturesWeight = value;
                    break;
                  case 'pr-w':
                    participationRateWeight = value;
                    break;
                  case 'pop-w':
                    populationWeight = value;
                    break;
                  // no value
                  case 'log-scale':
                    logScale = true;
                    break;
                  case '-f':
                    dashEqMaxValue = false;
                    break;
                }

              }

            }

            if (
              ( signaturesWeight == 0 && participationRateWeight == 0 && populationWeight == 0 )
              || groupsNumber < 2
                ) return false;
            else {
              setGroupingReferencesOptions();
              return true;
            }

          } )() ) return;

        } else if ( typeof optionsOrFunction == 'function' ) {

          var rowFunction = ( function optionsOrFunctionReplaced() {

            // for instance, try :
            // Pcc.groupBy( function() { return $spT( $round( $p / 1000 ) ) }, 'pop. <small>(x1000)</small>' )

            // 'function execFunction( rowElement )' returns 'eval( rowFunction )'
            // which value will be assigned to the last cell in each row
            // This also determines the context of 'rowFunction'.

            return ( '(' + optionsOrFunction + ')();' )
            // functions
            .replace( '$spT',   'spaceThousands' )  // see 'function spaceThousands( num )'
            .replace( '$round', 'Math.round' )
            // variables
            .replace( '$sm',  'signaturesMax' )
            .replace( '$prm', 'participationRateMax' )
            .replace( '$pm',  'populationMax' )
            .replace( '$s',   'signatures' )
            .replace( '$pr',  'participationRate' )  // != $s / $p ... it is, instead, the actual value in the table
            .replace( '$p',   'population' );

          } )();

          ( function setGroupingReferencesFunction() {

            var functionCall = pccS + '.groupBy( ' + optionsOrFunction + ' )';

            var notesDiv = $( '#' + table.attr( 'id' ).replace( 'table', 'notes-div' ) );
            notesDiv.find( '#nowGroupedByLong' ).hide();
            notesDiv.find( '#shortCommandRef' ).hide();
            notesDiv.find( '#nowGroupedByFunction' )
            .html( functionCall )
            .show();

            table.find( 'tr th:eq(5)').attr( 'title', '' + functionCall );

          } )();

        } else {
          return;
        }

        // calculates group following the string-coded options in 'optionsOrFunction'
        function getGroup( rowElement ) {

          getRowValues( rowElement );

          if ( population == -1 ) {
            return dashEqMaxValue
            ? '<span style="display:none">' + ( 1 + groupsNumber ) + '</span>-'
            : '-';
          }

          var rank = (
            signatures / signaturesMax * signaturesWeight
            + participationRate / participationRateMax * participationRateWeight
            + population / populationMax * populationWeight
            - ( signaturesWeight < 0 ? signaturesWeight : 0 )
            - ( participationRateWeight < 0 ? participationRateWeight : 0 )
            - ( populationWeight < 0 ? populationWeight : 0 )
            )
          / (
            Math.abs( signaturesWeight )
            + Math.abs( participationRateWeight )
            + Math.abs( populationWeight )
            ) ;

          if ( logScale ) {
            rank = groupsNumber - Math.floor( Math.log( 1 + rank * Math.exp( groupsNumber - 1 ) ) )
          } else {
            rank = groupsNumber - Math.floor( groupsNumber * rank );
          }

          return rank == 0 ? 1 : spaceThousands( rank );

        }

        // calculates value for Group column by the function in 'optionsOrFunction'
        function execFunction( rowElement ) {

          getRowValues( rowElement );

          if ( population == -1 ) {
            return dashEqMaxValue
            ? '<span style="display:none">' + ( 1 + groupsNumber ) + '</span>-'
            : '-';
          }

          return eval( rowFunction );

        }

        table.find( 'tr' ).each( function() {
          $( this ).find( 'td:last-child' ).html(
            ( typeof optionsOrFunction == 'function' ? execFunction : getGroup)( this )
            );
        } );

      }

      function setGroupForInPageTable( optionsOrFunction, groupColumnDisplay ) {

        $( 'table.table-conteggi:visible' ).each( function() {
          setGroup( $( this ), optionsOrFunction, groupColumnDisplay );
        });

      }
      Pcc.groupBy = setGroupForInPageTable;

      // all or page initialization
      if ( allOrPage == 'page' ) {
        var Counters = Pcc.PageCounters,
        countersTotal = Pcc.pageCountersTotal,
        table = tablePage;
      } else {
        Counters = Pcc.OldPlusNewCounters;
        countersTotal = Pcc.oldPlusNewCountersTotal;
        table = tableAll;
      }

      // counters in ordered arrays
      // joins also entries in 'Counters'
      var countriesOrd = ( function getEnDeEntriesJoinedArray() {

        // country names changed over time, or different between [en] and [de] subscription page version
        // extends Pcc.silentJoins, if it exists (from stage 0)
        var silentJoins = ( function setSilentJoins() {
          // names in the array will be shown with the key value

          var silentJoins = {};

          if ( typeof Pcc.silentJoins == 'object' ) {
            $.each( Pcc.silentJoins, function eachPccSilentJoins( destination, itemsToJoin ) {
              silentJoins[destination] = [];
              for ( var index in itemsToJoin ) {
                silentJoins[destination].push( itemsToJoin[index] );
              }
            } );
          }

          var newSilentJoins = {
            'Taiwan' : ['Taiwan, Province Of China'],
            'other' : ['&amp;lt;petitionpage-fromcountry-dropdown&amp;gt;']
          };

          $.each( newSilentJoins, function eachNewSilentJoins( destination, itemsToJoin ) {
            if ( !( destination in silentJoins ) ) {
              silentJoins[destination] = [];
            }
            for ( var index in itemsToJoin ) {
              silentJoins[destination].push( itemsToJoin[index] );
            }
          } );

          return silentJoins;

        } )();

        $.each( silentJoins, function eachSilentJoins( destination, itemsToJoin ){

          if ( Counters[destination] ) {
            $.each( itemsToJoin, function ( index, item ){

              if ( Counters[item] ) {
                Counters[destination] = Counters[destination] + Counters[item];
                delete Counters[item];
              }

            });
          }

        });

        // en/de country names joining
        var enDePairs = [ ['Germany', 'Deutschland'], ['Austria', 'Österreich'], ['Switzerland', 'Schweiz'], ['Belgium', 'Belgien'], ['Luxembourg', 'Luxemburg'], ['Denmark', 'Dänemark'], ['--', 'other'] ];
        var countryNamesJoined = {};
        $.each( enDePairs, function eachPairsEnDe( index, item ){

          var en = item[0], de = item[1];
          var enVal = Counters[en] ? Counters[en] : 0;
          var deVal = Counters[de] ? Counters[de] : 0;
          var keyEnDe = en + ' / ' + de
          + ' (' + spaceThousands( enVal ) + ' / ' + spaceThousands( deVal ) + ')';
          if ( enVal + deVal > 0) {
            countryNamesJoined[en] = keyEnDe;
            Counters[en] = enVal + deVal;
          }
          delete Counters[de];

        });

        // makes array for ordering
        var countriesOrd = [];
        $.each( Counters, function( country, count ){
          var population = getPopulation( country );
          countriesOrd.push( [
            countryNamesJoined[country] ? countryNamesJoined[country] : country,
            count,
            population == 0 ? 0 : count / population, // temporary value of participation rate, to be normalized later
            population
            ] );
        });

        // ordering
        countriesOrd.sort( function(a, b) {
          if ( a[1] == b[1] ) {
            return ( a[0] < b[0] ? -1 : 1 );
          } else {
            return b[1] - a[1];
          }
        });

        return countriesOrd;

      } )() ;

      // rateDenominatorExp is set so as participationRateMax would have 3 digits
      // values are also saved as table.data( '...' )
      var populationMax = 0, signaturesMax = 0, participationRateMax = 0, rateDenominatorExp;
      ( function calcMaximumsAndExp() {

        $.each( countriesOrd, function() {

          var signatures = this[1],
          participationRate = this[2],
          population = this[3];

          populationMax = Math.max( population, populationMax );
          participationRateMax = Math.max( participationRate, participationRateMax );
          signaturesMax = Math.max( signatures, signaturesMax );

        });

        rateDenominatorExp = 2 - Math.floor( Math.log( participationRateMax ) / Math.LN10 );

        participationRateMax =  Math.round( participationRateMax * Math.pow( 10, rateDenominatorExp ) );

        table.data( 'populationMax', populationMax );
        table.data( 'participationRateMax', participationRateMax );
        table.data( 'signaturesMax', signaturesMax );

      } )();

      // normalizes participationRate
      $.each( countriesOrd, function() {
        this[2] = Math.round( this[2] * Math.pow( 10, rateDenominatorExp ) );
      });

      // table caption
      $( '<caption>'
        + Messages['Table caption']
        + '<br/>' + Messages['Table total'] + ' = ' + spaceThousands( countersTotal )
        + '</caption>')
      .prependTo( table );

      // html table - header row
      table.append( $( addNotes( 'html', Messages['Column captions - table'] ) ) );

      // html table - hidden row for column sort type
      table.append( $( '\
<tr class="unsortable" style="display: none">\n\
<th>0</th><th>A</th><th>0</th><th>0</th><th>0</th><th>0</th>\n\
</tr>' ) );

      var participationRateHint
      = Messages['Participation rate hint'].replace( /&exp;/g, rateDenominatorExp );
      table.find( 'tr th:eq(4)' ).attr( 'title', participationRateHint );

      // wikicode table header
      var wikicode = '{| class="wikitable sortable" style="text-align:right;"\n|-\n'
      + addNotes( 'wiki', Messages['Column captions - wikicode'] )
      // wikicode table hidden row for column sort type
      + '\n|- class="unsortable" style="display: none"'
      +'\n! 0 !! a !! 0 !! 0 !! 0'

      // adds sigle rows - html and wikicode
      $.each( countriesOrd, function eachCountriesOrd( index, item ){

        var signaturesCount = item[1],
        population = item[3],
        participationRate = population == 0 ? '-' : item[2];

        var percent = ( '' + Math.round( 1000.0 * signaturesCount / countersTotal ) / 10 )
        .replace(/^(\d+)$/, '$1.0');
        if ( Messages.language == 'it' )  percent = percent.replace( '.', ',' );

        // population figure hint, also used in group column calculation
        var populationHint = population == 0 ? '-' : spaceThousands( population );

        // wikicode table row
        wikicode += '\n|-\n| ' + (1+index)
        + ' || align=left title="' + populationHint + '"| '
        + item[0].replace(')', ') <ref group="t" name="en-de country names" />')
        + ' || ' + spaceThousands( signaturesCount ) + ' || ' + percent + ' || ' + participationRate;

        // html table row
        var tempRow = '<tr><td>'+ (1+index)
        + '</td><td title="' + populationHint + '">' + item[0]
        + '</td><td>'+ spaceThousands( signaturesCount ) + '</td><td>'
        + percent + '</td><td>' + participationRate + '</td><td></td></tr>';
        if ( tempRow.indexOf( '(' ) != -1 ) {
          tempRow = tempRow.replace( ')', ')' + buildNote( 'html', Messages['Ref text en-de country names'] ) )
        }
        //
        $( tempRow ).appendTo( table );

      });

      // adds grouping values in last html column
      var defaultGrouping = 'n 100 pop-w -1 -f';
      setGroup( tablePage, defaultGrouping );
      if ( pageOkForTotal )  setGroup( tableAll, defaultGrouping );

      // sets visibility and adds onclicks for 'groupBy() syntax note'
      ( function setGroupBySyntaxNoteVisibility() {

        var notesDiv = $( '#' + table.attr( 'id' ).replace( 'table', 'notes-div' ) );

        var
        showMoreLink = notesDiv.find( '#show-more-syntax-note' ),
        showLessLink = notesDiv.find( '#show-less-syntax-note' ),
        moreSyntax = notesDiv.find( '#more-syntax-note' );

        moreSyntax.hide();
        showMoreLink.click( function showMoreLinkOnclick() {
          showMoreLink.hide();
          moreSyntax.show();
        } );
        showLessLink.click( function showMoreLinkOnclick() {
          showMoreLink.show();
          moreSyntax.hide();
        } );

      } )();

      wikicode = ( function fixWikicode() {

        // removes 'name' property in single references
        ( function removeNameProperty() {

          // find multiple references
          var
          multipleReferences = {},
          regex = /<ref group="t" name="([^"]+)" \/>/g;
          var refFound = null;
          while ( ( refFound = regex.exec( wikicode ) ) ) {
            multipleReferences[ refFound[1] ] = true;
          }

          // find single references
          var unnamedReferences = {};
          regex = /<ref group="t"( name="([^"]+))(">)|\|group=t(\|name=([^\n]+))(\n}})/g;
          refFound = null;
          while ( ( refFound = regex.exec( wikicode ) ) ) {
            for (var i = 1; i < 5; i += 3) {
              // 1 2 3 for <ref...> 4 5 6 for {{#tag|ref...
              if ( typeof refFound[i] != 'undefined' ) {
                var propertyText = refFound[i],
                propertyName = refFound[i+1],
                postPropertyText = refFound[i+2];
                if ( !multipleReferences[propertyName] ) {
                  unnamedReferences[propertyName] = [ propertyText, postPropertyText ];
                }
              }
            }
          }

          // removes 'name' property in single references
          for ( propertyName in unnamedReferences ) {
            propertyText = unnamedReferences[propertyName][0],
            postPropertyText = unnamedReferences[propertyName][1];
            wikicode = wikicode.replace( propertyText + postPropertyText, postPropertyText, 'g' );
          }

        })();

        return wikicode
        // <a ref links to [url text]
        .replace( /<a href="([^"]+)">([^<]+)<\/a>/g, '[$1 $2]')
        // wikicode ref text for en-de country names
        .replace(
          /en-de country names" \/>/,
          'en-de country names"><br />\n' + Messages['Ref text en-de country names'] + '\n</ref>' )
        .replace( /&exp;/g, rateDenominatorExp )
        .replace( /#participationRateHint#/g, participationRateHint );

      } )();
      // closes table and adds references tag
      wikicode += '\n|}\n\n;' + Messages['Notes'] + '\n<references group="t" />';

      // all or page wikicode saving
      if ( allOrPage == 'page' )
        wikicodePage = wikicode;
      else
        wikicodeAll = wikicode;

    }

    // inserts spaces as thousands separators
    function spaceThousands( num ) {

      return ( '' + num )
      .replace( /(\d)(\d\d\d)$/, '$1 $2' )
      .replace( /(\d)(\d\d\d )/, '$1 $2' )
      .replace( /(\d)(\d\d\d )/, '$1 $2' );

    }

    var showingAllSignatures = pageOkForTotal;
    var showingTable = true;
    var showingTextarea = false;

    // HTML and wikicode notes
    var notesObject = ( function setNotesObject() {

      return {
        'page' : {
          'wiki' : {
            'number' : 0,
            'notes' : {}
          },
          'html' : {
            'number' : 0,
            'notes' : {}
          }
        },
        'all' : {
          'wiki' : {
            'number' : 0,
            'notes' : {}
          },
          'html' : {
            'number' : 0,
            'notes' : {}
          }
        }
      };

    } )();

    // general script div
    var scriptDiv = $( '<div id="PerCountryContersDiv">' )
    .prependTo('#bodyContent');

    // inserts CSS
    function setCSS() {

      var cssText = '<style id="PerCountryCounterScript-general" type="text/css"><!--  _\
_\
.table-conteggi th { padding: .4em 1em .1em 1em }  _\
_\
.table-conteggi td {  _\
  padding: .1em 1em;  _\
  text-align: right;  _\
}  _\
_\
.table-conteggi tr td:first-child + td { text-align: left }  _\
_\
.table-conteggi caption { margin-bottom: .2em }  _\
_\
#table-button { margin-left: .5em }  _\
_\
#wikicode-conteggi {  _\
  display: block;  _\
  width: 100%;  _\
  margin-top: 1em;  _\
}  _\
_\
#firstHeading { border: none }  _\
_\
.script-alert {  _\
  background-color: #F6F6F6;  _\
  border: 1px solid #A7D7F9;  _\
  margin-bottom: 1em;  _\
  padding: .6em 1.3em .3em;  _\
  clear: both;  _\
}  _\
_\
.script-alert p { .7em 0 .5em }  _\
_\
.notes-div {  _\
  margin-bottom: 2em;  _\
  font-size: 85%;  _\
  text-align: justify;  _\
}  _\
_\
.mw-spcontent { margin-top: 1em }  _\
_\
--></script>_';

      scriptDiv.prepend( cssText.replace( / *_/g, '\n' ) );

    }
    setCSS();

    $( Messages['Script note link'] )
    .appendTo( scriptDiv );

    // alert text div
    if ( notOkForTotalAlertText ) {
      var unfittingPageAlertDiv = $(
        '<div id="unfitting-page-alert" class="script-alert">'
        + notOkForTotalAlertText.replace( /\n/g, '<br />' )
        + '</div>'
        ).appendTo( scriptDiv );
    }

    // wikicode button
    var wikicodeButton = $( '<input type="button" id="wikicode-button">' )
    .attr( 'value', Messages['Wikicode button show'] )
    .click( function showHideWikicode() {

      if ( showingTextarea ) {

        wikicodeButton.attr( 'value', Messages['Wikicode button show'] );
        wikicodeTextarea.hide();

      } else {

        wikicodeButton.attr( 'value', Messages['Wikicode button hide'] );
        wikicodeTextarea.show();

      }

      showingTextarea = !showingTextarea;

    } )
    .appendTo( scriptDiv );

    // table button
    var tableButton = $( '<input type="button" id="table-button">' )
    .attr( 'value', Messages['Table button hide'] )
    .click( function showHideTable() {

      var table = showingAllSignatures ? tableAll : tablePage;
      var notesDiv = showingAllSignatures ? notesDivAll : notesDivPage;

      if ( showingTable ) {

        tableButton.attr( 'value', Messages['Table button show'] );
        table.hide();
        notesDiv.hide();

      } else {

        tableButton.attr( 'value', Messages['Table button hide'] );
        table.show();
        notesDiv.show();

      }

      showingTable = !showingTable;

    } )
    .appendTo( scriptDiv );

    // 'All signatures' or 'In page signatures' message
    var allOrPageMessage = $( '<span id="all-page-message" style="padding: 0 2em 0 1em">' + Messages[
      pageOkForTotal ? 'All signatures' : 'In page signatures'
      ] + '</span>' )
    .appendTo( scriptDiv );

    // all/page switcher
    if ( pageOkForTotal ) {
      $( '<input type="button" id="all-page-button">' )
      .attr( 'value', Messages['All/Page button'] )
      .click( function allPageSwitch() {

        if ( showingAllSignatures ) {
          allOrPageMessage.text( Messages['In page signatures'] );
          wikicodeTextarea.val( wikicodePage );
        } else {
          allOrPageMessage.text( Messages['All signatures'] );
          wikicodeTextarea.val( wikicodeAll );
        }

        if ( showingTable ) {
          if ( showingAllSignatures ) {
            tableAll.hide();
            notesDivAll.hide();
            tablePage.show();
            notesDivPage.show();
          } else {
            tablePage.hide();
            notesDivPage.hide();
            tableAll.show();
            notesDivAll.show();
          }
        }

        showingAllSignatures = !showingAllSignatures;

      } )
      .appendTo( scriptDiv );
    }

    // textarea
    var wikicodeTextarea = $( '<textarea id="wikicode-conteggi" rows="10">' )
    .hide()
    .appendTo( scriptDiv );

    // table for in page signatures
    var tablePage = $( '<table id="table-page" class="wikitable sortable table-conteggi"><tbody>' )
    .appendTo( scriptDiv );

    // table for all signatures
    if ( pageOkForTotal ) {
      var tableAll = tablePage.clone()
      .attr( 'id', 'table-all')
      .appendTo( scriptDiv );
      // hides table for in page signatures
      tablePage.hide();
    }

    // notes div
    var notesDivPage = $( '<div id="notes-div-page" class="notes-div">' )
    .appendTo( scriptDiv );
    if ( pageOkForTotal ) {
      var notesDivAll = $( '<div id="notes-div-all" class="notes-div">' )
      .appendTo( scriptDiv );
      // hides notes for in page signatures
      notesDivPage.hide();
    }

    $( Messages['Script note'] )
    .appendTo( scriptDiv )
    .find( 'a:eq(1)' )
    .click( function hideScriptDisplay() {

      $( '#PerCountryContersDiv' )
      .hide()
      .find( 'style' ).remove();
      $().scrollTop( 0 );

    } );

    $( '.mw-petition-listentry:eq(0)' ).click( function showScriptDisplay() {

      setCSS();
      $( '#PerCountryContersDiv' )
      .show()
      .scrollTop( 0 );

    } );


    // strings for wikicode
    var wikicodePage = '', wikicodeAll = '';

    // fills tables
    buildTableAndWikicode ( 'page' );
    if ( pageOkForTotal ) {
      buildTableAndWikicode ( 'all' );
    }

    // makes tables sortable
    sortables_init();

    // click for rows renumering / must be after 'sortables_init()'
    $( 'table.table-conteggi' )
    .find( 'tr th:eq(0) span:eq(0)' )
    .click( function renumberRows() {

      var count = 0;
      $( 'table.table-conteggi:visible tr td:first-child' ).each( function() {
        $( this ).text( ++count );
      } );

    } );

    // fills wikicode textarea
    wikicodeTextarea.val( pageOkForTotal ? wikicodeAll : wikicodePage );

  } )();

} );