L'ordinateur

Débit et graphiques
de plein-jeux.

Code source.

La totalité des sources est disponible en archive ZIP ici.

L'Hydraule


Le code.

pleinjeu.inc.php.

<?php

 // ************************************************************************************************
 // ***                 Les constantes déterminées dans ce fichier sont partagées                ***
 // *** par le script principal (./pleinjeu.php) et l'image graphique PNG (./pleinjeuGraph.php). ***
 // ************************************************************************************************

 // Noms des notes ; la traduction des NOMS DE NOTATION est faite automatiquement plus bas.
 $note[1] = array(0 => "Anglo-Saxonne", "C",  "C#",  "D",  "D#",  "E",  "F",  "F#",   "G",   "G#",  "A",  "A#",  "B");
 $note[2] = array(0 => "Allemande 1",   "C",  "C#",  "D",  "D#",  "E",  "F",  "F#",   "G",   "G#",  "A",   "B",  "H");
 $note[3] = array(0 => "Allemande 2",   "C",  "Cs",  "D",  "Ds",  "E",  "F",  "Fs",   "G",   "Gs",  "A",   "B",  "H");
 $note[4] = array(0 => "Allemande 3",   "C", "Cis",  "D", "Dis",  "E",  "F", "Fis",   "G",  "Gis",  "A", "Ais",  "H");
 $note[5] = array(0 => "Latine 1",     "Ut", "Ut#", "Ré", "Ré#", "Mi", "Fa", "Fa#", "Sol", "Sol#", "La", "La#", "Si");
 $note[6] = array(0 => "Latine 2",     "Ut", "Ut#", "Ré", "Mib", "Mi", "Fa", "Fa#", "Sol", "Sol#", "La", "Sib", "Si");
 $note[7] = array(0 => "Dom Bedos",     "C",  "C#",  "D",  "Eb",  "E",  "F",  "F#",   "G",   "G#",  "A",  "Bb",  "B");

 // Noms par défaut des notes.
 $nbRanRom = array(1 =>  "I", "II", "III",  "IV",    "V",  "VI", "VII", "VIII",
                        "IX",  "X",  "XI", "XII", "XIII", "XIV",  "XV",  "XVI");
  
 // Définition des couleurs des rangs.
 $couleur  = array(1 => "#000000", "#ff0000", "#008000", "#0000ff", "#ff00ff", "#ffaa00", "#00ffff", "#ffa0a0",
                        "#909090", "#800000", "#ff00ff", "#ffaa00", "#00ff00", "#ffa0a0", "#909090", "#800000");

 // Nom des tessitures.
 $nomTessi  [0] = " - "   ; $nomTessi  [1] = "32'"    ; $nomTessi  [5] = "25'3/5" ; $nomTessi  [8] = "21'1/3" ;
 $nomTessi [13] = "16'"   ; $nomTessi [17] = "12'4/5" ; $nomTessi [20] = "10'2/3" ; $nomTessi [25] = "8'"     ;
 $nomTessi [29] = "6'2/5" ; $nomTessi [32] = "5'1/3"  ; $nomTessi [37] = "4'"     ; $nomTessi [41] = "3'1/5"  ;
 $nomTessi [44] = "2'2/3" ; $nomTessi [49] = "2'"     ; $nomTessi [53] = "1'3/5"  ; $nomTessi [56] = "1'1/3"  ;
 $nomTessi [61] = "1'"    ; $nomTessi [65] = "4/5'"   ; $nomTessi [68] = "2/3'"   ; $nomTessi [73] = "1/2'"   ;
 $nomTessi [77] = "2/5'"  ; $nomTessi [80] = "1/3'"   ; $nomTessi [85] = "1/4'"   ; $nomTessi [89] = "1/5'"   ;
 $nomTessi [92] = "1/6'"  ; $nomTessi [97] = "1/8'"   ; $nomTessi[101] = "1/10'"  ; $nomTessi[104] = "1/12'"  ;
 $nomTessi[109] = "1/16'" ; $nomTessi[113] = "1/20'"  ; $nomTessi[116] = "1/24'"  ; $nomTessi[121] = "1/32'"  ;
 
 // Convertit en binaire en formatant la chaîne avec les zéros de gauche.
 function deciBin($valeur) {return sprintf("%08s", decbin($valeur)); };

 // Encode une valeur numérique sur deux octets.
 function encodeVal($input)
 {
  //      |<----- Poids fort ----->|   |<- Poids faible ->|
  return chr(floor($input / 256)) . chr($input % 256);
 };

 // Décode une valeur numérique sur deux octets.
 function decodeVal($input)
 {
  //      |<---------- Poids fort ---------->|    |<---- Poids faible ----->|
  return (ord(substr($input, 0, 1)) * 256) + ord(substr($input, 1, 1));
 };
?>   


pleinjeu.php.

<?php
 /*


                                                ----------------------------------------------------
                                                                        _
                 ORGANUM                                               | | _
                                                       Sébastien       | || | _
              Logiciel libre                           Matthieu        | || || | _
          de gestion de données                        Cosson          | || || || | _
           de facture d'orgues                         Jacquet         | || || || || | _
                                                                       | || || || || || | _
                                                                       | || || || || || || |
                    M                                                  | || || || || || || |
                  *   *                                ,-~~-.___.      | || || || || || || |___
                S A T O R                             /  | .     \     |_||_||_||_||_||_||_|  /|
              * A R E P O *                          (   )        O    |_||_||_||_||_||_||_| / |
            S   T E N E T   C                         \_/-. ,----'    / V  V  V  V  V  V  V /  |
              * O P E R A *                               ====      _/____________________ /  /
                R O T A S                                /  \-'~;  /|  The Organbuilder   |  /
                  *   *                                 /  __/~|  /_|   and his organ     | /
                    J                                o=(_______|  |_|_____________________|/

                                                ----------------------------------------------------
                                                   Site web : http://www.hydraule.org/
                                                     E-mail : smcj@hydraule.org
                                                ----------------------------------------------------


 Choses à faire.
  - Traduire l'aide de l'utilitaire et l'article sur ODL en allemand.
  - S’occuper du cas de la liste de coche rapide pour éviter l’erreur quand aucune case n’est cochée.

 Choses à revoir
  - Si $t1, $t2 et $t3 existent, on considère la saisie valide ; c'est peut-être sujet à caution.
  - Améliorer l'image graphique.

  - Lecture du fichier XML :
    - Récupérer le nom du clavier dans l'attribut "def_kb" de <MIXTURE>.
    - Chercher un <KB> qui porte la même valeur dans l'attribut "name".
*/

 // Les constantes déterminées dans ce fichier include sont partagées par l'image graphique PNG (./pleinjeuGraph.php).
 include("./pleinjeu.inc.php");

 // Fixe le nombre de ligne et de colonne de la grille AFFICHÉES (et non PRÉSENTES car elles le sont toutes) au départ.
 $lignes = 3; $colonnes = 4;

 // Masque de coches des 54 premières notes.
 $XMLclavier = str_repeat("1", 54) . str_repeat("0", 7);

 // Chaine « $comprep » et « $noterep » contenant les composition des tessitures et des reprises.
 $comprep = str_repeat(chr(0), 256); $noterep = str_repeat(chr(0), 16);
 $noterep = substr_replace($noterep, chr(1), 0, 1);                          // Première note à Do1.

 // Fixe la largeur et la hauteur par défaut de l'image graphique.
 $largImgGraph = 450; $hautImgGraph = 278;

 // Traitement du choix de la langue.
   $listeLangue = array(0 => "fr", "en", "de"); $defautLangue = 0;
 $commentLangue = array(0 => "Version française", "English version", "Deutsche Version");

 $choixLangue = isset($_GET ['l']) ? $_GET ['l'] : $listeLangue[$defautLangue]; $passe = false;
 for ($i = 0; $i <= (count($listeLangue) - 1); $i++) {if ($choixLangue == $listeLangue[$i]) {$passe = true; }; };
 if (!$passe) {$choixLangue = $listeLangue[$defautLangue]; };

 switch ($choixLangue) // Une certaine idée de l'Europe...
 {
  case $listeLangue[0] : $langueActive = 0; $notNot = 1; $notOct = 1; break; // Français.
  case $listeLangue[1] : $langueActive = 1; $notNot = 1; $notOct = 1; break; // English.
  case $listeLangue[2] : $langueActive = 2; $notNot = 2; $notOct = 2; break; // Deutsch.
 };

 // Titres généraux.
 $langue [0] = array(0 => "L'ordinateur", "The computer", "Der Computer");
 $langue [1] = array(0 => "Débit et graphiques<br />de plein-jeux", "Data outflows and<br />graphics of mixtures", "Datendurchsatz und<br />Grafiken von Mixturen");
 $langue [2] = array(0 => "Formulaire de saisie", "Entry Form", "Eingabeformular");

 // Titre haut et bas du formulaire des cases à cocher.
 $langue [3] = array(0 => "Notes du<br />clavier", "Notes of<br />keyboard", "Tonklaviatur");
 $langue [4] = array(0 => "Coche<br />rapide", "Quickly<br />check", "Schnellhäkchen");
 $langue [5] = array(0 => "Oct. c.", "S. oct", "K. Okt.");

 // Sous-titres de la colonne de droite.
 $langue [6] = array(0 => "Données générales ", "General Datas", "Allgemeine Daten");
 $langue [7] = array(0 => "Composition ", "Composition", "Zusammenstellung");
 $langue [8] = array(0 => "Commandes et résultats ", "Orders and results", "Befehle und Ergebnisse");

 // Contenu du formulaire de données générales.
 $langue [9] = array(0 => "Nom du jeu ", "Stop name", "Registerbezeichnung");
 $langue[10] = array(0 => "Nombre de rangs ", "Number of ranks", "Zahl der fache");
 $langue[11] = array(0 => "Nombre de reprises ", "Number of repetitions", "Zahl der Wiederholungen");
 $langue[12] = array(0 => "Notation des notes ", "Notes notation", "Tonbezeichnunge");
 $langue[13] = array(0 => "Notation des octaves ", "Octaves notation", "Oktavebezeichnunge");
 $langue[14] = array(0 => "Image graphique ", "Graphic image", "Grafik");
 $langue[15] = array(0 => "Largeur ", "Width", "Breite");
 $langue[16] = array(0 => "Hauteur", "Height", "Höhe");
 $langue[17] = array(0 => "Fourniture", "Mixture", "Mixtur");

 // Liste de notation des notes.
 // Attention, il faut que le choix français soit au moins en partie présent dans la liste des noms des notes.
 $langue[18] = array(0 => "Anglo-Saxonne", "Anglo-Saxon", "Anglo-amerikanischen");
 $langue[19] = array(0 => "Allemande", "German", "Deutsch");
 $langue[20] = array(0 => "Latine", "Latin", "Latein");

 if ($langueActive != 0) // Pas la peine de traduire du français par du français.
 {
  for ($i = 18; $i <= 20; $i++)
  {
   for ($j = 1; $j <= 7; $j++) {$note[$j][0] = str_replace($langue[$i][0], $langue[$i][$langueActive], $note[$j][0]); };
  };
 };

 // Liste de notation des octaves.
 $langue[21] = array(0 => "Numérique", "Digital", "Digital");
 $langue[22] = array(0 => "Allemande", "German", "Deutsch");

 // Contenu du formulaire de composition des reprises et des tessitures.
 $langue[23] = array(0 => "Reprises ", "Breaks", "Punkten");
 $langue[24] = array(0 => "Tessitures ", "Ranges", "Tonbereichen");
 $langue[25] = array(0 => "   Valider   ", "   Submit   ", " Ãœbermitteln ");

 // Contenu des deux formulaires d'entrée et de sortie.
 $langue[26] = array(0 => "Entrée O.D.L.", "O.D.L. input", "O.D.L. eingabe");
 $langue[27] = array(0 => "Sortie", "Output", "Ausgabe");
 $langue[28] = array(0 => " Entrée du fichier ", " File input ", " Datei eingabe ");
 $langue[29] = array(0 => "   Débit   ", "    Outflows    ", " Durchsatz ");
 $langue[30] = array(0 => "Texte seulement", "Text only", "Nur Text");
 $langue[31] = array(0 => "Initialiser", "Initialize", "Initialisieren");
 $langue[32] = array(0 => "    Aide    ", "    Help    ", "    Hilfe    ");

 // Boites de dialogue de messages.
 $langue[33] = array(0 => "Votre saisie est impossible.\\nFaites-en une autre ou corrigez\\nles valeurs des cellules avoisinantes.", "Your input is impossible.\\nDo another or fix the values\\nof neighboring cells.", "Ihre Eingabe ist nicht möglich.\\nMachen Sie einer anderen oder korrigieren Sie\\ndie Werte der benachbarten Zellen.");
 $langue[34] = array(0 => "Au moins douze notes\\ndoivent être cochées.", "At least twelve notes\\nmust be checked.", "Mindestens zwölf Noten\\nmüssen häkchen sein.");
 $langue[35] = array(0 => "Saisissez un nom de jeu.", "Enter a name stop.", "Geben Sie einen Stimmenname.");
 $langue[36] = array(0 => "Vous n\'avez pas saisi toutes\\nles notes des reprises.", "You have not entered all\\nthe notes of the repetitions.", "Sie haben nich alle\\nTonwiederholungen gegeben.");
 $langue[37] = array(0 => "Entrez au moins\\nune tessiture par rang.", "Enter at least\\na range by rank.", "Geben Sie mindestens\\neinen Tonbereichen von Fach.");
 $langue[38] = array(0 => "Choisissez d\'abord un fichier ODL\\nsur votre disque dur.", "Choose first a ODL file\\non your hard drive.", "Wählen Sie zunächst\\neine ODL Datei auf Ihrer Festplatte.");
 $langue[39] = array(0 => "Entrez une AAA d\'image\\nBBB ou égale à", "Enter an image AAA\\nBBB or equal than", "Geben Sie eine AAA des Bildes\\nBBB oder gleich zu");
 $langue[40] = array(0 => "largeur", "width", "Breite");
 $langue[41] = array(0 => "hauteur", "height", "Höhe");
 $langue[42] = array(0 => "inférieure", "less", "bis");
 $langue[43] = array(0 => "supérieure", "greater", "größer");
 $langue[44] = array(0 => "Êtes-vous sûr de vouloir\\nrecharger cette page à blanc ?", "Are you sure you want to\\nreload this page blank?", "Sind Sie sicher, dass wollen Sie\\ndiese Seite leer zu machen?");

 // Résultats.
 $langue[45] = array(0 => "Composition :", "Arrangement:", "Zusammenstellung:");
 $langue[46] = array(0 => "Graphiques ASCII :", "ASCII graphics:", "ASCII Grafik:");
 $langue[47] = array(0 => "Débit :", "Data outflows:", "Datendurchsatz:");
 $langue[48] = array(0 => "Nombre total de tuyaux :", "Total number of pipes:", "Anzahl der Pfeifen:");
 $langue[49] = array(0 => "Cliquez ici pour cacher ce tableau.", "Click here to hide this table.", "Klicken Sie hier für die Tabelle verstecken.");
 $langue[50] = array(0 => "Cliquez ici pour afficher tous les tableaux.", "Click here to view all tables.", "Klicken Sie hier für alle Tabellen anzeigen.");

 // Place les noms des notes en première et dernière ligne du tableau de composition.
 function titreTab()
 {
  global $nbRep, $noteOctave, $affiNoteOctave, $repri, $formSort;
  switch ($formSort)                                                    // La mise en forme n'est pas la même selon le format de sortie.
  {
   case 1 : // Mise en forme HTML.
    echo("    <tr valign=\"bottom\">\n");
    for ($i = 0; $i <= ($nbRep -1); $i++) {echo("     <th> " . $affiNoteOctave[$repri[$i]] . " </th>\n"); };
    echo ("    </tr>\n");
   break;

   case 2 : // Mise en forme RTF.
    echo ("\par\plain\qj\\f2\\fs24\cf0");
    for ($i = 0; $i <= ($nbRep -1); $i++) {echo("\\tab " . str_replace("°", "\\'b0", utf8_decode($affiNoteOctave[$repri[$i]]) )); };
    echo ("\n");
   break;

   case 3 : // Mise en forme TXT.
    for ($i = 0; $i <= ($nbRep -1); $i++) {echo("\t " . $noteOctave[$repri[$i]]); };
    echo ("\n");
   break;
  };
 };

 // Analyse de la chaîne pour mettre les fractions des tessitures en exposant.
 function expoTessi($chaine)
 {
  global $formSort; $place = strpos($chaine, "'");
  switch ($formSort)                                       // Les enrichissements ne sont pas les mêmes selon le format de sortie.
  {
   case 1 : // Enrichissements HTML.
    if (($place >= 1) && ($place != (strlen($chaine) - 1)))
    {
     $chaine = substr($chaine, 0, ($place + 1)) . "<sup>" . substr($chaine, ($place + 1)) . "</sup>";
    };
   break;

   case 2 : // Enrichissements RTF.
    if ($place >= 1) 
    {
     if ($place != (strlen($chaine) - 1))
     {
      $chaine = substr($chaine, 0, $place) . "\\rquote {\super " . substr($chaine, ($place + 1)) . "}";
     };
     if ($place == (strlen($chaine) - 1))
     {
      $chaine = substr($chaine, 0, $place) . "\\rquote ";
     };
    };
   break;
  };
  return $chaine;
 };

 // Sans doute ce que je crois avoir programmé de plus dense et de plus beau dans ma vie...
 function debitASCII()
 {
  global $formSort, $couleur, $ligne, $cell, $note, $notNot, $notOct, $nomTessi, $repri, $nbRep, $nbTuy, $premOct, $dernOct, $haut, $bas;

  // Détermination des lignes de titre du pseudo-graphique.
  for ($i = 0; $i <= 6; $i++)
  {
   $ligne[$i] = "              ";
   for ($j = $repri[0]; $j <= ($repri[$nbRep] - 1); $j++) {$ligne[$i] .= " ";}
   $ligne[$i] .= "                    \n";
  };

  $repri[$nbRep]--;                                                      // Pour pouvoir afficher la dernière note.
  for ($i = 0; $i <= $nbRep; $i++)
  {
   $chaine = $note[$notNot][(($repri[$i] - 1) % 12) + 1];                // Nom de la note.
   $a = ($repri[$i] + 14) - $repri[0];                                   // Place de la note ; 14 est le nombre de caractère de la marge.

   // Passe le nom des notes en minuscules.
   if (($notOct == 2) && ($repri[$i] > 12)) {$chaine = strtolower($chaine);}

   for ($j = 1; $j <= strlen($chaine); $j++)                             // Affiche la note.
   {
    $ligne[$j] = substr_replace($ligne[$j], substr($chaine, ($j - 1), 1), $a, 1);
   }
   if ($notOct == 1)                                                     // Notation numérique.
   {
    $ligne[$j] = substr_replace($ligne[$j], (floor($repri[$i] / 12) + 1), $a, 1);
   }
   else                                                                  // Notation allemande des octaves.
   {
    if (($repri[$i] >= 12) && ($repri[$i] < 25))                         // Affiche le null.
    {
     $ligne[$j] = substr_replace($ligne[$j], "X", $a, 1);
    }
    if ($repri[$i] >= 25)                                                // Affiche les guillemets.
    {
     for ($k = $j; $k <= ($j + (floor($repri[$i] / 12) - 2)); $k++)
     {
      $ligne[$k] = substr_replace($ligne[$k], "'", $a, 1);
     };
    };
   };
  };
  $repri[$nbRep]++;                                                      // On restitue en l'état...

  // substr_replace est fâché avec l'UTF8 car il prend deux caractères pour « ° »...
  for ($i = 2; $i <= 6; $i++) {$ligne[$i] = str_replace("X", "°", $ligne[$i]); };

  // Affichage des lignes de titre.
  function affiLigneTitre()
  {
   global $formSort, $ligne;

   for ($i = 1; $i <= 6; $i++)                                                                   
   {
    if ($ligne[$i] != $ligne[0])
    {
     switch ($formSort)
     {
      case 1 : echo($ligne[$i]);                                          break;                  // HTML.
      case 2 : echo("\par " . str_replace("°", "\\'b0", $ligne[$i])); break;                  // RTF.
      case 3 : echo(          str_replace("°", "°",     $ligne[$i])); break;                  // TXT.
     };
    };
   };
  };

  affiLigneTitre();
  $nbTuy = 0; $haut = 121; $bas = 1;                                                              // Initialisation des variables.
  while($cell[$haut] == $cell[0]) {$haut--; };                                                    // Empêche l'affichage des aigus inutiles.

  for ($i = $haut; $i >= 1; $i--)                                                                 // Toutes les tessitures qui possèdent des tuyaux.
  {
   // Titre des lignes.
   $titre = $note[$notNot][(($i - 1) % 12) + 1] . "      ";
   $titre = substr($titre, 0, (6 - strlen($titre)));
   // Détection des Octaves, Tierces et Quintes.
   if (((($i - 1) % 12) == 0 ) || ((($i + 7) % 12) == 0 ) || ((($i + 4) % 12) == 0 ))
   {
    $titre .= $nomTessi[$i];
   };
   $titre .= "            "; $titre = substr($titre, 0, (12 - iconv_strlen($titre)));             // Seul endroit (pour l'instant) où la fonction iconv_strlen() est utilisé (à cause de l'UTF8 sur la notation latine "Ré").
   if (($formSort == 1) || ($formSort == 3)) {echo(" "      .             $titre  . "|"); };      // HTML et TXT.
   if  ($formSort == 2)                      {echo("\par  " . utf8_decode($titre) . "|"); };      // RTF.
  
   // Traduction de la chaîne $cell[$i] en une chaîne ($a) affichable à l'écran.
   $a = ""; $b = ""; $c = 0; $d = 0; $r = 0;

   for ($t = ((($repri[0] - 1) * 2) + 1); $t <= (($repri[$nbRep] - 1) * 2); $t += 2)              // Tout le clavier par saut de deux octets.
   {
    $b = deciBin(ord(substr($cell[$i], ($t + 1), 1))) . deciBin(ord(substr($cell[$i], $t, 1)));   // Extrait et concatène deux octets.
    $c = strlen(str_replace("0", "", $b)); $d += $c;                                              // Comptabilise le nombre de tuyau sur cette note. Ajoute au total de la ligne.
    if ($c == 0)                                                                                  // Tout ce qui ne concerne pas le slash.
    {
     if ((((($t - 1) / 2) + 1) == $repri[$r]) && ($r != 0))                                       // Barre des reprises sauf sur la première.
     {
      // Sur les octaves et les quintes : croisement. Sur le reste : barre verticale.
      if (((($i - 1) % 12) == 0 ) || ((($i + 4) % 12) == 0 ) || ($i == $haut)) {$a .= "+"; } else {$a .= "|"; };
     }
     else
     {
      // Sur les octaves et les quintes : tiret. Sur le reste : espace.
      if (((($i - 1) % 12) == 0 ) || ((($i + 4) % 12) == 0 ) || ($i == $haut)) {$a .= "-"; } else {$a .= " "; };
     };
    }
    else                                                                                          // Y'en a !
    {
     if ($c == 1)                                                                                 // Un si petit slash...
     {
      switch ($formSort)
      {
       case 1 : $a .= "<font color=\"" . $couleur[16 - strpos($b, "1")] . "\">/</font>";          break; // HTML.
       case 2 : $a .= "\plain\\f3\\fs12\cf" . (16 - strpos($b, "1")) . "\b /\plain\\f3\\fs12\b "; break; // RTF.
       case 3 : $a .= "/";                                                                        break; // TXT.
      };
     };
     if (($c >= 2) && ($c <= 9)) {$a .= $c;}                                                      // Doublures, triplures, chiures et bavochures.
     if ($c >= 10) {$a .= "*";}                                                                   // Accordeur, sois patient, tu fais un bÔ métier.
    };
    if ( ((($t - 1) / 2) + 1) == $repri[$r] ) {$r++; };                                           // Changement de reprise.
   };

   $b = $d . "";  $c = strlen($b);                                                                // Mesure (en caractère) de la longueur de $d.
   switch ($formSort)                                                                             // En rouge et aligné à droite.
   {
    case 1 : $chaine = "<font color=\"#ff0000\">" . $d . "</font> - $titre \n";                                break; // HTML.
    case 2 : $chaine = "\plain\\f3\\fs12\cf2\b " . $d . "\plain\\f3\\fs12\b  - " . utf8_decode($titre) . "\n"; break; // RTF.
    case 3 : $chaine = $d . " - $titre \n";                                                                    break; // TXT.
   };
   echo($a . "|" . substr("   ", 0, (3 - $c)) . $chaine);
   $cell[$i] = substr_replace($cell[$i], chr($d), 0, 1);                                          // Stockage dans le premier octet de $cell[$i].
   $nbTuy += $d;                                                                                  // Comptabilise le nombre total de tuyaux.

   // Empêche l'affichage du grave s'il est vide en totalité.
   $j = $i - 1; while (($j > 0) && ($cell[$j] == $cell[0])) {$j--; }; if ($j < 1) {$i = 0; }
  };

  affiLigneTitre();
  
  // $premOct et $dernOct ==> Nécessaire à l'établissement des tableaux de débit -->
  $t = 0; $i = 1;   while ($t == 0) {$t = ord(substr($cell[$i], 0, 1)); $i++;} $premOct = floor(($i - 2) / 12);
  $t = 0; $i = 121; while ($t == 0) {$t = ord(substr($cell[$i], 0, 1)); $i--;} $dernOct = floor($i / 12);

  // Localise la première tessiture grave ==> $haut et $bas nécessaires au graphique PNG.
  for ($i = 1; $i <= 121; $i++) {if ($cell[$i] != $cell[0]) {$bas = $i; $i = 122; }; };
 };

 // Détermination des variables reçues en provenance de la validation du formulaire.
 $t1 = isset($_POST ['t1']) ? $_POST ['t1'] : "";
 $t2 = isset($_POST ['t2']) ? $_POST ['t2'] : "";
 $t3 = isset($_POST ['t3']) ? $_POST ['t3'] : "";

 // Traitement des données depuis un fichier XML s'il y a lieu.
 $adresseFichier = isset($_GET ['url']) ? $_GET ['url'] : "";                   // L'adresse du fichier est dans l'URL.
 if (!$adresseFichier) {$adresseFichier = isset($_FILES['XMLfichier']['tmp_name']) ? $_FILES['XMLfichier']['tmp_name'] : ""; };
 
 // Le fichier est transféré depuis le disque dur.
 if ((is_uploaded_file($adresseFichier)) || ($adresseFichier))
 {
  $xmlDoc = new DOMDocument(); $xmlDoc->load($adresseFichier);                  // Chargement du fichier.
  
  // Coches du clavier.
  $XMLclavier = $xmlDoc->getElementsByTagName("KB")->item(0)->getElementsByTagName("PRESENT_NOTE")->item(0)->firstChild->nodeValue;
  $XMLclavier = preg_replace( '`[^0-1]`', '', $XMLclavier);                     // Supprime tout ce qui n'est pas 0 ou 1 dans le contenu.

  $XMLpleinjeu = $xmlDoc->getElementsByTagName("MIXTURE")->item(0);
  $langue[17][$langueActive] = $XMLpleinjeu->getAttributeNode('name')->value;   // Nom du jeu.
    $lignes = $XMLpleinjeu->getElementsByTagName("RANK")->length;               // Nombre de rangs.
                                                                                // Nombre de reprises (du premier rang).
  $colonnes = $XMLpleinjeu->getElementsByTagName("RANK")->item(0)->getElementsByTagName("BREAK")->length;

  for ($j = 1; $j <= $colonnes; $j++)                                           // Notes des reprises.
  {
   $k = $XMLpleinjeu->getElementsByTagName("RANK")->item(0)->getElementsByTagName("BREAK")->item($j - 1)->getAttributeNode('pos')->value;
   $noterep = substr_replace($noterep, chr($k), ($j - 1), 1);                   // Toujours du premier rang.
  };

  for ($j = 1; $j <= $lignes; $j++)                                             // Composition du plein jeu.
  {
   for ($i = 1; $i <= $colonnes; $i++)
   {
    $k = $XMLpleinjeu->getElementsByTagName("RANK")->item($j - 1)->getElementsByTagName("BREAK")->item($i - 1)->getAttributeNode('range')->value;
    $comprep = substr_replace($comprep, chr($k), ((($j - 1) * 16) + ($i - 1)), 1);
   };
  };

  $eXecute = isset($_GET ['f']) ? $_GET ['f'] : 0;                       // Exécutera le débit si f != 0 (format).
  if ($eXecute != 0)                                                     // en reconstituant les chaines $t1, $t2 et $t3
  {                                                                      // qui sont normalement issues du formulaire.
   $chaine1 = $XMLclavier . "000"; $chaine2 = "";                        // On a besoin d'une chaîne de 64 caractères.
   for ($i = 0; $i <= 7; $i++)                                           // Réduit les 64 bits précédents à huit octets.
   {
    $chaine2 .= chr(bindec(substr($chaine1, ($i * 8), 8)));              // Notes du clavier.
   };
   $chaine  = $chaine2 . encodeVal($lignes);                             // Nombre de rangs.
   $chaine .= encodeVal($colonnes);                                      // Nombre de reprises.
   $chaine .= encodeVal($notNot);                                        // Notation des notes.
   $chaine .= encodeVal($notOct);                                        // Notation des octaves.
   $chaine .= encodeVal($largImgGraph);                                  // Largeur de l'image graphique.
   $chaine .= encodeVal($hautImgGraph);                                  // Hauteur de l'image graphique.
   $chaine .= encodeVal($eXecute);                                       // Format de sortie.
   $chaine .= $XMLpleinjeu->getAttributeNode('name')->value;             // Nom du jeu (255 octets maximum).

        $t1 = base64_encode($chaine);                                    // Encodage de la chaîne $t1.
        $t2 = base64_encode($noterep);                                   // Encodage de la chaîne $t2.
        $t3 = base64_encode($comprep);                                   // Encodage de la chaîne $t3.
  };
 };

 // Si les trois existent, on considère la saisie valide.
 if ($t1 && $t2 && $t3)
 {
  // +--------------------------------------------------------------+
  // | Récupération des variables à partir des chaînes transférées. |
  // +--------------------------------------------------------------+
  $chaine = base64_decode($t1);                                          // Décodage de la chaîne $t1.

  $noteCoche = "";                                                       // Notes du clavier.
  for ($i = 0; $i <= 7; $i++)
  {
   $chaine1 = decbin(ord(substr($chaine, $i, 1))); while (strlen($chaine1) < 8) {$chaine1 = "0" . $chaine1;}
   $noteCoche .= $chaine1;
  };

     $nbRan =    decodeVal(substr($chaine,  8,                      2)); // Nombre de rangs.
     $nbRep =    decodeVal(substr($chaine, 10,                      2)); // Nombre de reprises.
    $notNot =    decodeVal(substr($chaine, 12,                      2)); // Notation des notes.
    $notOct =    decodeVal(substr($chaine, 14,                      2)); // Notation des octaves.
     $l_img =    decodeVal(substr($chaine, 16,                      2)); // Largeur de l'image graphique.
     $h_img =    decodeVal(substr($chaine, 18,                      2)); // Hauteur de l'image graphique.
  $formSort =    decodeVal(substr($chaine, 20,                      2)); // Format de sortie.
    $nomJeu = stripslashes(substr($chaine, 22, (strlen($chaine) - 22))); // Nom du jeu (255 octets maximum).

  // Valeurs des notes de reprises.
  $chaine = base64_decode($t2);                                          // Décodage de la chaîne $t2.
  for ($i = 0; $i <= 15; $i++) {$repri[$i] = ord(substr($chaine, $i, 1)); };

  // Valeurs des tessitures.
  $chaine = base64_decode($t3);                                          // Décodage de la chaîne $t3.
  for ($i = 0; $i <= 15; $i++)
  {
   for ($j = 0; $j <= 15; $j++) {$tessi[$i][$j] = ord(substr($chaine, (($i * 16) + $j), 2)); };
  };

  // +---------------------------------------------------------------------------------+
  // |                         Mise en mémoire des données.    +-----+                 |
  // | On est prié de remarquer que le tableau/chaînes ne fait | QUE | 15006 octets... |
  // +---------------------------------------------------------+-----+-----------------+
  // Déclaration des chaînes vierges.
  $cell[0] = str_repeat(chr(0), 123);                                    // $cell[0] servira à la comparaison de chaînes vides.
  for ($i = 1; $i <= 121; $i++) {$cell[$i] = $cell[0]; };                // Initialisation des chaînes en copie de $cell[0].

  $repri[$nbRep] = strlen(rtrim($noteCoche, "0")) + 1;                   // Pour pouvoir passer la dernière reprise.

  for ($i = 1; $i <= $nbRan; $i++)                                       // Boucle des rangs.
  {
   for ($j = 1; $j <= $nbRep; $j++)                                      // Boucle des reprises.
   {
    if ($tessi[$i - 1][$j - 1] != 0)                                     // Cas des reprises vides (trous).
    {
     $vraiNote = $tessi[$i - 1][$j - 1] + $repri[$j - 1] - 1;            // Première note RÉELLE de la reprise.
     for ($k = $repri[$j - 1]; $k < $repri[$j]; $k++)                    // Boucle des notes.
     {
      if (substr($noteCoche, ($k - 1), 1) == "1")                        // À la condition que les notes soient présentes.
      {
       if ($i <= 8)                                                      // Les huit premiers rangs.
       {
        $place = ((($k - 1) * 2) + 1);                                   // Localise la place pour $cell[$vraiNote]

        // Extrait la valeur, la convertit en binaire et ajoute le bit à la place du rang.
        $chaine = substr_replace(deciBin(ord(substr($cell[$vraiNote], $place))), "1", (8 - $i), 1);
       }
       else                                                              // Les huit derniers rangs.
       {
        $place = ((($k - 1) * 2) + 2);                                   // Localise la place pour $cell[$vraiNote].

        // Extrait la valeur, la convertit en binaire et ajoute le bit à la place du rang.
        $chaine = substr_replace(deciBin(ord(substr($cell[$vraiNote], $place))), "1", (16 - $i), 1);
       };
       // Stocke la valeur en décimal sur la bonne tessiture et à la bonne note.
       $cell[$vraiNote] = substr_replace($cell[$vraiNote], chr(bindec($chaine)), $place, 1);
      };
      $vraiNote++;                                                       // Incrémente la reprise.
     };
    };
   };
  };
 }; // Fin de la condition sur $t1, $t2 et $t3.

 // Détermination des chaînes de caractères de notation des notes avec enrichissement.
 for ($j = 1; $j <= count($note); $j++)
 {
  for ($i = 1; $i <= 12; $i++)
  {
   $chaine = ""; $traitementFormSort = isset($formSort) ? $formSort : 1; // Traitement de la mise en exposant ou indice pur « # », « b », « s » et « is ».   
   switch ($traitementFormSort)                                          // Les enrichissements ne sont pas les mêmes selon le format de sortie.
   {
    case 1 : // Enrichissements HTML.
     if (strpos($note[$j][$i], "#", 0)) {$chaine = substr_replace($note[$j][$i], "<sup>#</sup>", strpos($note[$j][$i], "#", 0), 1); };
     if (strpos($note[$j][$i], "b", 0)) {$chaine = substr_replace($note[$j][$i], "<sub>b</sub>", strpos($note[$j][$i], "b", 0), 1); };
     if (strpos($note[$j][$i], "s", 0)) // Notation allemande.
     {
      if (strpos($note[$j][$i], "is", 0))
      {
       $chaine = substr_replace($note[$j][$i], "<sup>is</sup>", strpos($note[$j][$i], "is", 0), 2);
      }
      else
      {
       $chaine = substr_replace($note[$j][$i], "<sup>s</sup>", strpos($note[$j][$i], "s", 0), 1);
      };
     };
    break;
    case 2 : // Enrichissements RTF.
     if (strpos($note[$j][$i], "#", 0)) {$chaine = substr_replace($note[$j][$i], "{\super #}", strpos($note[$j][$i], "#", 0), 1); };
     if (strpos($note[$j][$i], "b", 0)) {$chaine = substr_replace($note[$j][$i], "\\'b0", strpos($note[$j][$i], "b", 0), 1); };
     if (strpos($note[$j][$i], "s", 0))                                  // Notation allemande.
     {
      if (strpos($note[$j][$i], "is", 0))
      {
       $chaine = substr_replace($note[$j][$i], "{\super is}", strpos($note[$j][$i], "is", 0), 2);
      }
      else
      {
       $chaine = substr_replace($note[$j][$i], "{\super s}", strpos($note[$j][$i], "s", 0), 1);
      };
     };
    break;
   };
   if (!$chaine) {$chaine = $note[$j][$i]; };                            // Note sans retouche.
   $affiNote[$j][$i] = $chaine;                                          // $affiNote[$j][$i] sera sans retouche pour TXT.
  };
 };

 // Fabrication de la combination de la notation des notes ET des octaves.
 $noteOctave[0] = " - ";                                                 // Utile à l'affichage des cellules vides.
 for ($i = 1; $i <= 61; $i++)
 {
  $j = ((($i - 1) % 12) + 1); $k = floor((($i - 1) / 12) + 1);

  // Notation numérique des octaves.
  if ($notOct == 1)
  {
       $noteOctave[$i] =     $note[$notNot][$j] . $k;                    // Sans enrichissement.
   $affiNoteOctave[$i] = $affiNote[$notNot][$j] . $k;                    // Avec enrichissement (pour le résultat).
  };

  // Notation allemande des octaves.
  if ($notOct == 2)
  {
   if ($k == 1)
   {
        $noteOctave[$i] =     $note[$notNot][$j];                        // Sans enrichissement.
    $affiNoteOctave[$i] = $affiNote[$notNot][$j];                        // Avec enrichissement (pour le résultat).
   }
   else                                                                  // Passe en minuscule.
   {
        $noteOctave[$i] = strtolower    ($note[$notNot][$j]);            // Sans enrichissement.
    $affiNoteOctave[$i] = strtolower($affiNote[$notNot][$j]);            // Avec enrichissement (pour le résultat).
   };

   if ($k == 2)                                                          // Ajoute le null pour la deuxième octave.
   {
        $noteOctave[$i] .= "°";                                          // Sans enrichissement.
    $affiNoteOctave[$i] .= "°";                                          // Avec enrichissement (pour le résultat).
   };

   if ($k >= 3)                                                          // Ajoute les guillemets à partir de la troisième octave.
   {
    for ($l = 1; $l <= ($k - 2); $l++)
    {
         $noteOctave[$i] .= "'";                                         // Sans enrichissement.
     $affiNoteOctave[$i] .= "'";                                         // Avec enrichissement (pour le résultat).
    };
   };
  };
 };

 // Ne commence à envoyer du HTML que dans le cas du formulaire de saisie ou de la sortie demandée en HTML.
 if ((!isset($formSort)) || ($formSort <= 1))
 {
  header("Content-type:text/html; charset=UTF-8");

?><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Page HTML composée et programmée par S.M.C.J. -->
<!-- Sources PHP ./src/code.php -->
<html>
 <head>
  <title><?php echo(str_replace("<br />", " ", $langue[1][$langueActive])); ?>.</title>

  <meta http-equiv="content-language" content="<?php echo($choixLangue); ?>" />
  <meta http-equiv="content-type"     content="text/html; charset=UTF-8" />
  <meta       name="author"           content="S.M.C.J." />
  <meta       name="keywords"         content="Hydraule Orgue Orgao Organo Orgel Organ" />
  <meta       name="description"      content="Calcul du nombre de tuyaux identiques d'un plein-jeu." />

  <link rel="shortcut icon" href="img/favicon.png" />
  <link rel="stylesheet" type="text/css" href="styles.css" />

  <script language="javaScript">
   <!--
<?php
 if (!isset($formSort))  // Insertion du JavaScript du formulaire.
 {
?>
    // Déclaration des variables GLOBALES.
    var  base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
    var note = new Array(<?php echo(count($note)); ?>);
<?php
 // Transfert des notation de notes de PHP à JavaScript.
 for ($j = 1; $j <= count($note); $j++)
 {
  echo("    note[" . $j . "] = new Array(");
  for ($i = 1; $i <= 12; $i++)
  {
   echo("\"" . $note[$j][$i] . "\"");
   if ($i < 12) {echo(", "); }
  };
  echo(");\n");
 };
?>

    // Initialisation des variables, reset des champs de saisie Focus sur la saisie du nom de jeu et activation de la première cellule.
    function init()
    {
     // Composition du plein jeu et des emplacements de reprises. « testcomprep » sert à tester la validité de la saisie.
     noterep = base64_decode(document.form_06.t2.value); comprep = base64_decode(document.form_06.t3.value);
     testcomprep = ""; for (i = 0; i <= 15; i++) {testcomprep += String.fromCharCode(0); };

     cellActive = document.getElementById("cellInputTessi_1");
     document.form_01.reset(); document.form_02.reset(); document.form_03.reset();
     document.form_04.reset(); document.form_05.reset(); document.form_06.reset();
     scrollTo(0, 0); document.form_02.nomjeu.focus();
    };

    // Recharge la page avec le bouton « Initialiser ».
    function recharge()
    {
     if (confirm("<?php echo($langue[44][$langueActive]); ?>")) {document.location.href = document.location.href; };
    };

    // Attribue une valeur (un caractère) dans une chaine - Simplification d'écriture.
    function attrib(chaine, place, remp)
    {
     return chaine.substr(0, place) + remp + chaine.substr(place + remp.length);
    };

    // Conversion d'une chaîne en binaire. Source : Philippe Baumann - http://kevin.vanzonneveld.net
    function binDec(input) {input = (input + '').replace(/[^01]/gi, ''); return parseInt(input, 2); };
    
    // Encodage et décodage en base 64. Source : Tyler Akins - http://rumkin.com
    function base64_encode(input)
    {
     var output = ""; var chr1, chr2, chr3; var enc1, enc2, enc3, enc4; var i = 0;

     do
     {
      chr1 = input.charCodeAt(i++); chr2 = input.charCodeAt(i++); chr3 = input.charCodeAt(i++);
      enc1 = chr1 >> 2; enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); enc4 = chr3 & 63;

      if (isNaN(chr2)) {enc3 = enc4 = 64;} else if (isNaN(chr3)) {enc4 = 64;}

      output = output + base64.charAt(enc1) + base64.charAt(enc2) + base64.charAt(enc3) + base64.charAt(enc4);
     }
     while (i < input.length);

     return output;
    };

    function base64_decode(input)
    {
     var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
     var output = ""; var i = 0;
     input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");

     do
     {
      enc1 = base64.indexOf(input.charAt(i++)); enc2 = base64.indexOf(input.charAt(i++));
      enc3 = base64.indexOf(input.charAt(i++)); enc4 = base64.indexOf(input.charAt(i++));
      chr1 = (enc1 << 2) | (enc2 >> 4); chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); chr3 = ((enc3 & 3) << 6) | enc4;

      output = output + String.fromCharCode(chr1);

      if (enc3 != 64) {output = output + String.fromCharCode(chr2); };
      if (enc4 != 64) {output = output + String.fromCharCode(chr3); };
     } while (i < input.length);

     return output;
    };


    // Encode une valeur numérique sur deux octets.
    function encodeVal(input)
    {
     //     |<------------- Poids fort ------------->|   |<------- Poids faible ------->| 
     return String.fromCharCode(parseInt(input / 256)) + String.fromCharCode(input % 256);
    };

    // Empêche la saisie d'autre chose que des neuf chiffres.
    // Fonctions écrites par Bertrand Wattel (http://bertrand.wattel.free.fr/)
    // et trouvé sur le site SELFHTML (http://actuel.fr.selfhtml.org/articles/javascript/entrees_formulaire/index.htm).
    function codeTouche(evenement)
    {
     for (prop in evenement) {if (prop == 'which') return (evenement.which); };
     return(evenement.keyCode);
    };

    function scanTouche(evenement)
    {
     var reCarSpeciaux = /[\x00\x08\x0D]/;
     var reCarValides = /[0-9]/;

     var codeDecimal  = codeTouche(evenement);
     var car = String.fromCharCode(codeDecimal);
     var autorisation = reCarValides.test(car) || reCarSpeciaux.test(car);

     return autorisation;
    };

    // Fenêtre d'aide.
    function ouvre(nomFenetre)
    {
     var nomFenetre = nomFenetre + "_<?php echo($choixLangue); ?>";
     var posgauche = 1; var poshaut = 1; var largeur = 300; var hauteur = 300;
     if (screen.width)  {largeur = Math.floor(screen.width  / 1.5); posgauche = Math.floor(screen.width  / 50); };
     if (screen.height) {hauteur = Math.floor(screen.height / 1.5);   poshaut = Math.floor(screen.height / 50); };

     var para = "toolbar=1,location=0,directories=0,status=0,menubar=1,resizable=1,scrollbars=1,width=" + largeur + ",height=" + hauteur + ",top=" + poshaut + ",left=" + posgauche;
     nomFenetre = window.open(nomFenetre + ".htm", nomFenetre, para); nomFenetre.focus();
    };

    // Travail sur les étiquettes du tableau de coche. Du D.O.M. en toutes choses...
    function renommeCoch(notation)
    {
     for (i = 1; i <= 61; i++)
     {
      // Écrit la notation des notes.
      j = ((i - 1) % 12); chaine = note[notation][j]; // « chaine » juste pour la lisibilité du code.

      // Afin de savoir si la notation des notes est allemande.
      with(document.form_02.notNot) {estTeuton = (options[selectedIndex].text.toLowerCase().indexOf("allemande", 0) == -1); };

      // Mise en minuscules des notes (hors la première octave) pour la notation des octaves allemande.
      if ((document.form_02.notOct.options[1].selected == true) && (Math.floor((((i - 1) / 12)) + 1) > 1)) {chaine = chaine.toLowerCase(); };

      // Ne laisse qu'un seul enfant D.O.M. dans les cellules afin de conserver le nom de l'ID.
      eval("noeud = document.getElementById('nomCoch" + i + "')");
      while (noeud.childNodes[1]) {noeud.removeChild(noeud.childNodes[1]); };

      // Remplacement à la condition que « chaine » NE CONTIENNE PAS « # », « b » et « s ».
      if ((chaine.indexOf("#", 0) == -1) && ((chaine.indexOf("b", 0) == -1) || (!estTeuton)) && (chaine.indexOf("s", 0) == -1))
      {
       eval("with(document.getElementById('nomCoch" + i + "').firstChild) replaceData(0, length, chaine);");
      };

      // Traitement de la mise en exposant ou en indice si « chaine » contient « # », « b », « s » ou « is ».
      if (chaine.indexOf("#", 0) != -1)
      {
       eval("with(document.getElementById('nomCoch" + i + "').firstChild) replaceData(0, length, chaine.substring(0, chaine.indexOf('#', 0)));"); // Partie gauche.
       enfant = document.createElement('sup'); enfant.appendChild(document.createTextNode('#')); noeud.appendChild(enfant); // Incorporation du nouveau <sup>.
      };

      if ((chaine.indexOf("b", 0) != -1) && (estTeuton)) // Pas de traitement de <sub> sur la lettre « B » en Allemagne !
      {
       eval("with(document.getElementById('nomCoch" + i + "').firstChild) replaceData(0, length, chaine.substring(0, chaine.indexOf('b', 0)));"); // Partie gauche.
       enfant = document.createElement('sub'); enfant.appendChild(document.createTextNode('b')); noeud.appendChild(enfant); // Incorporation du nouveau <sub>.
      };

      if (chaine.indexOf("s", 0) != -1)
      {
       if (chaine.indexOf("is", 0) != -1)
       {
        eval("with(document.getElementById('nomCoch" + i + "').firstChild) replaceData(0, length, chaine.substring(0, chaine.indexOf('is', 0)));"); // Partie gauche.
        enfant = document.createElement('sup'); enfant.appendChild(document.createTextNode('is')); noeud.appendChild(enfant); // Incorporation du nouveau <sup>.
       }
       else
       {
        eval("with(document.getElementById('nomCoch" + i + "').firstChild) replaceData(0, length, chaine.substring(0, chaine.indexOf('s', 0)));"); // Partie gauche.
        enfant = document.createElement('sup'); enfant.appendChild(document.createTextNode('s')); noeud.appendChild(enfant); // Incorporation du nouveau <sup>.
       };
      };

      // Écrit la notation des octaves.
      if (document.form_02.notOct.options[0].selected == true)
      {
       eval("with(document.getElementById('numeroCoch" + i + "').firstChild) replaceData(0, length, '" + i + "');"); // Numéro de note.
      }
      else                                                                            // Notation allemande.
      {
       k = Math.floor(((i - 1) / 12) + 1);
       if (k == 1) {chaine = " "; };                                                  // Première octave.
       if (k == 2) {chaine = "°"; };                                                  // Deuxième octave.
       if (k >= 3) {chaine = ""; for (l = 1; l <= (k - 2); l++) {chaine += "'"; }; }; // Octaves suivantes.

       eval("with(document.getElementById('numeroCoch" + i + "').firstChild) replaceData(0, length, chaine);");
      };
     };
    };

    // Écriture dans la liste déroulante. Ceci arrive :
    //  * Quand on change la notation des notes ou des octaves.
    //  * Quand on change les cases à cocher en cliquant dessus ou par la liste des coches rapides.
    function actuListeRep(coche)
    {
     // Garde en mémoire la VALEUR de la sélection de la liste.
     with (document.getElementById("listeRep")) memoValSel = options[selectedIndex].value;

     // Mise à blanc de la liste déroulante avant reconstitution immédiate afin de respecter le « miroir » des cases à cocher.
     with(document.getElementById("listeRep")) while (firstChild) {removeChild(firstChild); };

     // Établissement de la combination de la notation des notes ET des octaves en fonction de la notation en cours.
     var noteOctave = new Array(61);
     premNote = "";
     for (i = 1; i <= 61; i++) // i : numéro de note dans le jeu - j : numéro de note dans l'octave - k : numéro d'octave.
     {
      j = ((i - 1) % 12); k = Math.floor(((i - 1) / 12) + 1);

      // Notation numérique des octaves.
      if (document.form_02.notOct.options[0].selected == true) {noteOctave[i] = note[document.form_02.notNot.value][j] + k; };

      // Notation allemande des octaves.
      if (document.form_02.notOct.options[1].selected == true)
      {
       if (k == 1)
       {
        noteOctave[i] = note[document.form_02.notNot.value][j];
       }
       else
       {
        noteOctave[i] = note[document.form_02.notNot.value][j].toLowerCase();  // Passe en minuscule.
       };

       if (k == 2) {noteOctave[i] += "°"; };                                            // Ajoute le null.

       if (k >= 3) {for (l = 1; l <= (k - 2); l++) {noteOctave[i] += "'"; }; };         // Ajoute les guillemets.
      };

      // Attribution du texte et de son attribut au sein même de la liste déroulante en « miroir » des cases cochées.
      if (eval("document.getElementById('cochNote" + i + "').checked == true;"))
      {
       if (!premNote) // Écriture de la première note dans la première cellule du tableau.
       {
        premNote = noteOctave[i]; document.getElementById("cellInputRep_1").value = premNote;
         noterep = attrib(noterep, 0, String.fromCharCode(i));                          // Sans oublier d'en prendre note...
       }
       else          //  Écriture du reste dans la liste déroulante (De l'art du D.O.M.).
       {
            enfant = document.createElement("option");           enfant.appendChild(document.createTextNode(noteOctave[i]));
        enfantAttr = document.createAttribute("value");          enfantAttr.value = i;
        document.getElementById("listeRep").appendChild(enfant); enfant.setAttributeNode(enfantAttr);
       };
      };

      // Traitement des en-têtes de reprises pour les changement de notations et pour la dévalidation des coches.
      for (k = 2; k <= 16; k++)                                                  // La première reprise, c'est déjà fait.
      {
       if ((noterep.charAt(k - 1).charCodeAt(0) == i) && (eval("document.getElementById('cochNote" + i + "').checked == false")))
       {
        eval("document.getElementById('cellInputRep_" + k + "').value = ' - '"); // Mise à blanc de l'en-tête.
        noterep = attrib(noterep, (k - 1), String.fromCharCode(0));              // Mise en mémoire de cette suppression.
       };

       if (noterep.charAt(k - 1).charCodeAt(0) == i)                             // Réaffiche le contenu des en-têtes.
       {
        eval("document.getElementById('cellInputRep_" + k + "').value = noteOctave[i]");
       }
      };
     };

     // Remet la position de la sélection de la liste en place.
     //  Si la coche se fait AU DESSUS de la sélection ==> Cherche dans la liste le « value » adéquat pour en connaître la place.
     // Si la coche se fait EN DESSOUS de la sélection ==> Pas de traitement.
     //         Si la décoche se fait SUR la sélection ==> memoValSel = 0, soit le premier choix de la liste.
     indexSelection = 0;
     for (i = 0; i <= (memoValSel - 1); i++) // Recherche sur la valeur et non sur la position à cause des trous possibles.
     {
      if (document.getElementById("listeRep").options[i].value == memoValSel)  {indexSelection = i; i = memoValSel; };  // Sortie de la boucle.
     };
     document.getElementById("listeRep").selectedIndex = indexSelection;

     // Met à jour la liste de coches rapides avec la notation.
     for (i = 1; i <= (document.form_01.rapidCoch.length - 2); i++)
     {
      with (document.form_01.rapidCoch.options[i])
      {
       text = noteOctave[value.indexOf("X") + 1] + " - " + noteOctave[value.lastIndexOf("X") + 1];
      };
     };
    };

    // Coche les cases en série en fonction de types prédéfinis.
    function serieCoche(serie)
    {
     for (i = 1; i <= 61; i++)
     {
      if (serie.substr((i - 1), 1) == "X")
      {
       eval("document.getElementById('cochNote" + i + "').checked = true;");
      }
      else
      {
       eval("document.getElementById('cochNote" + i + "').checked = false;");
      }
     }
     actuListeRep(-1);
    };

    // N'accepte pas la notation allemande des octaves si la notation des notes est « Latine » ou « Dom Bedos ».
    function verifNotAllemande()
    {
     with(document.form_02.notNot) {chaine = options[selectedIndex].text; };
     if ((chaine.toLowerCase().indexOf("<?php echo(strtolower($langue[20][$langueActive])); ?>", 0) != -1) || (chaine.toLowerCase().indexOf("bedos", 0) != -1))
     {
      document.form_02.notOct.options[0].selected = true;
     };
    };

    // Contrôle la saisie des largeurs et hauteurs du futur fichier graphique.
    function controle(objet, type, memo)
    {
     valeur = objet.value; saisie = true;

     switch(type)
     {
      case 1:
<?php
 $chaine = str_replace("AAA", $langue[40][$langueActive], $langue[39][$langueActive]);
 $chaine = str_replace("BBB", $langue[42][$langueActive], $chaine);
?>
       if (valeur > 800) {alert('<?php echo($chaine); ?> 800.'); saisie = false; };
<?php
 $chaine = str_replace("AAA", $langue[40][$langueActive], $langue[39][$langueActive]);
 $chaine = str_replace("BBB", $langue[43][$langueActive], $chaine);
?>
       if (valeur < 200) {alert('<?php echo($chaine); ?> 200.'); saisie = false; };
      break;

      case 2:
<?php
 $chaine = str_replace("AAA", $langue[41][$langueActive], $langue[39][$langueActive]);
 $chaine = str_replace("BBB", $langue[42][$langueActive], $chaine);
?>
       if (valeur > 600) {alert('<?php echo($chaine); ?> 600.'); saisie = false; };
<?php
 $chaine = str_replace("AAA", $langue[41][$langueActive], $langue[39][$langueActive]);
 $chaine = str_replace("BBB", $langue[43][$langueActive], $chaine);
?>
       if (valeur < 150) {alert('<?php echo($chaine); ?> 150.'); saisie = false; };
      break;

      case 3: // Validation du formulaire de téléchargement du fichier XML.
       if (!valeur) {alert('<?php echo($langue[38][$langueActive]); ?>'); saisie = false; } else {document.form_04.submit(); };
      break;
     };

     if (!saisie)
     {
      if (type < 3)  {objet.value = memo; objet.select(); };
      objet.focus();
     };
    };

    // Change le nombre de lignes ou de colonnes affichées du tableau.
    function changeAffich(colonnes, lignes)
    {
     // Cellules de titre (NOTES du tableau).
     for (i = 2; i <= 16; i++)
     {
      commande = "document.getElementById('cellTdNot_" + i + "').className = '";
      if (i <= colonnes) {eval(commande + "affiCell'"); } else {eval(commande + "disparait'"); };
     };

     // Cellules de valeurs (REPRISES du tableau).
     for (j = 1; j <= 16; j++)
     {
      // Action sur les lignes (ceci est fait pour éviter les <tr></tr> vide qui prennent quand même de la place même quand les <td></td> sont neutralisés.
      commande = "document.getElementById('ligne_" + j + "').className = '";
      if ((j <= lignes)) {eval(commande + "affiLigne'"); } else {eval(commande + "disparait'"); };
      for (i = 1; i <= 16; i++)
      {
       // Action sur les cellules.
       commande = "document.getElementById('cellTdTessi_" + String.fromCharCode(i + 64) + j + "').className = '";
       if ((j <= lignes) && (i <= colonnes)) {eval(commande + "affiCell'"); } else {eval(commande + "disparait'"); };
      };
     };
    };

    function changeTitrePleinJeu()
    {
     with(document.form_02) {titre = nomjeu.value + " " + nbRangs.options[nbRangs.value - 1].text; };
     with(document.getElementById("titrePleinJeu").firstChild) {replaceData(0, length, titre); };
    };

    // Change la classe de la cellule, met en mémoire son contenu, change son contenu et passe le focus à la liste.
    function re1(c)
    {
     c.className="cellFocus"; memo = c.value; c.value = " <<< ";
     document.getElementById("listeRep").focus(); document.getElementById("listeRep").className = "cellFocus";
    };

    // Traite le remplissage visible de la cellule de reprises et s'occupe de la mise en mémoire dans la variable « noterep ».
    function re2(c)
    {
     if (c.id.indexOf("cellInputRep") != -1)
     {
      with (document)
      {
       // Attribue la valeur d'une reprise à la bonne place dans la bonne cellule.
       c.value = getElementById("listeRep")[getElementById("listeRep").selectedIndex].text;
       noCell = parseInt(c.id.substr(13, (c.id.length - 13)))                                    // « cellInputRep_ » fait 12 caractères.
       // Comparaison avec les valeurs des cellules voisines.
       // Attention, cette comparaison de s'éffectue que de proche en proche ; il doit être possible d'améliorer
       i = noterep.charAt(noCell - 2).charCodeAt(0);                                             // Cellule précédente.
       j = parseInt(getElementById("listeRep")[getElementById("listeRep").selectedIndex].value); // Cellule active.
       k = noterep.charAt(noCell).charCodeAt(0);                                                 // Cellule suivante.

       if ((j <= i) || ((j >= k) && (k != 0)))
       {
        alert("<?php echo($langue[33][$langueActive]); ?>");
        c.value = memo;                                                                          // Remet la valeur d'origine.
       }
       else
       {
        // Attribue la valeur d'une reprise à la bonne place dans la chaîne « noterep ».
        noterep = attrib(noterep, (noCell - 1), String.fromCharCode(j));
       };
      };
      c.className = "fondSaisie"; document.getElementById("listeRep").className = "fondSaisie";
     };
    };

    // Change la classe de la cellule, met en mémoire son contenu, change son contenu et passe le focus à la liste.
    function te1(c)
    {
     c.className="cellFocus"; memo = c.value; c.value = " <<< ";
     document.getElementById("listeTessi").focus(); document.getElementById("listeTessi").className = "cellFocus";
    };

    // Traite le remplissage visible de la cellule de tessitures et s'occupe de la mise en mémoire dans la variable « comprep ».
    function te2(c)
    {
     if (c.id.indexOf("cellInputTessi") != -1)
     {
      with (document)
      {
       // Attribue la valeur d'une tessiture à la bonne place dans la bonne cellule.
       c.value = getElementById("listeTessi")[getElementById("listeTessi").selectedIndex].text;
       noCell = parseInt(c.id.substr(15, (c.id.length - 15)));                                       // « cellInputTessi_ » fait 14 caractères.
       j = parseInt(getElementById("listeTessi")[getElementById("listeTessi").selectedIndex].value); // Cellule active.

       // Attribue la valeur d'une tessiture à la bonne place dans la chaîne COMPREP.
       comprep = attrib(comprep, (noCell - 1), String.fromCharCode(j))
      };
      c.className = "fondSaisie"; document.getElementById("listeTessi").className = "fondSaisie";
     };
    };

    // Remet les choses en place si la saisie n'a pas été modifiée.
    function memoCell(c)
    {
     if (c.value == " <<< ")
     {
      document.getElementById("listeRep").className = "fondSaisie"; document.getElementById("listeTessi").className = "fondSaisie";
      c.className = "fondSaisie"; c.value = memo;
     };
    };

    // Convertit les trois chaînes « noterep » et « comprep » en base 64 (pour le transfert).
    function debit()
    {
     passe = true;

     // À la condition que douze notes soient cochées au minimum.
     j = 0; for (i = 1; i <= 61; i++) {if (eval("document.getElementById('cochNote" + i + "').checked == true;")) {j++;}; };
     if (j < 12) {alert('<?php echo($langue[34][$langueActive]); ?>'); passe = false; };

     // À la condition qu'un nom de jeu soit saisi.
     if (document.form_02.nomjeu.value == "") {alert("<?php echo($langue[35][$langueActive]); ?>"); passe = false;}

     // À la condition que toutes les reprises du tableau affiché aient été saisies.
     if (noterep.substr(1, (document.form_02.nbReps.value - 1)).indexOf(String.fromCharCode(0)) == -1)
     {
      chaine1 = "";                                  // Traitement de « chaine1 ».
      for (i = 1; i <= 61; i++)
      {
       if (eval("document.getElementById('cochNote" + i + "').checked == true")) {chaine1 += "1"; } else {chaine1 += "0"; };
      };
      chaine1 += "000"; chaine2 = "";                // On a besoin d'une chaîne de 64 caractères.
      for (i = 0; i <= 7; i++)                       // Réduit les 64 bits précédents à huit octets.
      {
       chaine2 += String.fromCharCode(binDec(chaine1.substr((i * 8), 8)));
      };

      // Code les valeurs numériques de form_02 par une suite de deux octets et rajoute le format de sortie et le nom du jeu.
      with (document.form_02)
      {
       chaine1 = chaine2 + encodeVal(nbRangs.value); // Nombre de rangs.
       chaine1 +=          encodeVal( nbReps.value); // Nombre de reprises.
       chaine1 +=          encodeVal( notNot.value); // Notation des notes.
       chaine1 +=          encodeVal( notOct.value); // Notation des octaves.
       chaine1 +=          encodeVal(  l_img.value); // Largeur de l'image graphique.
       chaine1 +=          encodeVal(  h_img.value); // Hauteur de l'image graphique.
      };

      with (document.form_05)                        // Format de sortie.
      {
       for (i = 1; i <= formatSortie.length; i++)
       {
        if (formatSortie[(i - 1)].checked) {chaine1 += encodeVal(i); i = formatSortie.length; };
       };
      };
      
      chaine1 += document.form_02.nomjeu.value;      // Nom du jeu (255 octets maximum).

      document.form_06.t1.value = base64_encode(chaine1);
      document.form_06.t2.value = base64_encode(noterep);
      document.form_06.t3.value = base64_encode(comprep);
     }
     else
     {
      alert('<?php echo($langue[36][$langueActive]); ?>');  passe = false;
     };

     // À la condition qu'au moins une tessiture par rang ait été saisie.
     for (i = 0; i <= (document.form_02.nbRangs.value - 1); i++)
     {
      if (comprep.substr((i * 16), 16) == testcomprep)
      {
       alert("<?php echo($langue[37][$langueActive]); ?>");  i = 16; passe = false;
      };
     };

     // Valide ou - non - le formulaire.
     if (passe) {document.form_06.submit(); };
    };
<?php
 }  // Fin de l'insertion du JavaScript du formulaire.
 else
 {  // Insertion du JavaScript du résultat.
?>
    // Cache une partie du résultat pour l'impression.
    function cacheBlock(objet) {objet.className = "disparait"; };

    // Affiche tous les tableaux de résultat pour l'impression.
    function affiBlock()
    {
     var affiId = new Array("Compo", "ASCII", "Debit", "Graphique");
     for (i = 0; i < affiId.length; i++) {document.getElementById("tableau" + affiId[i]).className = "affiBloc"; };
    };
<?php
 }; // Fin de l'insertion du JavaScript du résultat.
?>
   // -->
  </script>
 </head>

 <body text="#000000" link="#0000ff" vlink="#551a8b" alink="#ff0000"<?php if (!isset($formSort)) {echo(" onLoad=\"javaScript:init();\"");}; ?>>
  <table border="0" cellpadding="0" cellspacing="0" width="100%">
   <tr>
    <td align="center" valign="center">
     <br /><br /><h1><font color="#ff0000"><?php echo($langue[0][$langueActive]); ?></font></h1>
     <h2><font color="#008000"><?php echo($langue[1][$langueActive]); ?>.</font></h2>
     <h3><font color="#000080"><?php

 if (!isset($formSort)) // Mode formulaire.
 {
  echo($langue[2][$langueActive] . "</font></h3>\n");
  for ($i = 0; $i <= 2; $i++)
  {
   if ($choixLangue != $listeLangue[$i])
   {
    echo("     <a href=\"pleinjeu.php?l=" . $listeLangue[$i] . "\"><img src=\"img/flag_" . $listeLangue[$i] . ".gif\" border=\"0\" width=\"40\" height=\"28\" alt=\"" . $commentLangue[$i] . "\" title=\"" . $commentLangue[$i] . "\"></a>");
    echo("    \n");
   };
  };
 }
 else
 {
  $nomJeu = utf8_encode($nomJeu) . " " . $nbRanRom[$nbRan];
  echo("<span onClick=\"javaScript:affiBlock();\" style=\"cursor:pointer;\" title=\"" . $langue[50][$langueActive] . "\">" . $nomJeu . "</span></font></h3>\n");
 };
?>
    </td>
    <td align="right">
     <a href="http://hydraule.org/" target="_top"><img src="img/hydraule.png" border="0" width="216" height="230" alt="L'Hydraule" title="L'Hydraule"></a>
    </td>
   </tr>
  </table>

  <br /><br /><br /><br />

  <center>
<?php
 // Affichage du formulaire.
 if (!isset($formSort))
 {
?>
   <table border="0" width="88%" cellpadding="0" cellspacing="0">
    <tr>
     <!-- Cellule de la coche des notes (gauche).-->
     <td width="10%">
      <form name="form_01">
       <!-- Table de la coche des notes. -->
       <table border="5" cellspacing="0" cellpadding="15" bgcolor="#f5e9cf" background="img/ingres.jpg">
        <tr>
         <td align="center">
          <table border="0" cellpadding="0" cellspacing="0">
           <tr><th colspan="3" nowrap><?php echo($langue[3][$langueActive]); ?><br /><br /></th></tr>
<?php
 // Affichage des cases à cocher avec leur étiquettes.
 for ($i = 1; $i <= 61; $i++)
 {
  $j = ((($i - 1) % 12) + 1); $k = floor((($i - 1) / 12) + 1);
  echo("           <tr><td align=\"right\"><span id=\"nomCoch" . $i . "\">");
  if (($notOct == 2) && ($k >= 2)) {echo(strtolower($affiNote[$notNot][$j])); } else {echo($affiNote[$notNot][$j]); };
  echo("</span></td><td align=\"left\"> <span id=\"numeroCoch" . $i . "\">");
  if ($notOct == 1)
  {
   echo($i);                                                                             // Numéro de note.
  }
  else
  {
   if ($k == 1) {$chaine = " "; };                                                       // Première octave.
   if ($k == 2) {$chaine = "°"; };                                                       // Deuxième octave.
   if ($k >= 3) {$chaine = ""; for ($l = 1; $l <= ($k - 2); $l++) {$chaine .= "'"; }; }; // Octaves suivantes.
   echo($chaine);
  };

  echo("</span></td><td><input type=\"checkbox\" id=\"cochNote" . $i . "\" onChange=\"javaScript:actuListeRep(" . $i . ")\"");

  // Application du masque de coches.
  if (substr($XMLclavier, ($i - 1), 1) == "1") {echo(" checked"); };
  echo(" /></td></tr>\n");
 };
?>
           <tr>
            <th colspan="3">
             <br /><?php echo($langue[4][$langueActive]); ?><br />
             <select name="rapidCoch" class="fondSaisie" onChange="javaScript:serieCoche(this.value);">
              <option value="OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO" selected>----------</option>
              <option value="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"><?php echo($noteOctave[1]  . " - " . $noteOctave[61]); ?></option><!-- C1 - C6 -->
              <option value="XXXXXXXXXXXXXXXXXXOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO"><?php echo($noteOctave[1]  . " - " . $noteOctave[18]); ?></option><!-- C1 - F2 -->
              <option value="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO"><?php echo($noteOctave[1]  . " - " . $noteOctave[30]); ?></option><!-- C1 - F3 -->
              <option value="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXOOOOOOOOOOOOOOOOOOOOOOOOOOOOO"><?php echo($noteOctave[1]  . " - " . $noteOctave[32]); ?></option><!-- C1 - G3 -->
              <option value="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXOOOOOOO"><?php echo($noteOctave[1]  . " - " . $noteOctave[54]); ?></option><!-- C1 - F5 -->
              <option value="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXOOOOO"><?php echo($noteOctave[1]  . " - " . $noteOctave[56]); ?></option><!-- C1 - G5 -->
              <option value="OOOOOXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXOOOOOOO"><?php echo($noteOctave[6]  . " - " . $noteOctave[54]); ?></option><!-- F1 - F5 -->
              <option value="OOOOOOOOOOOOXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXOOOOOOO"><?php echo($noteOctave[13] . " - " . $noteOctave[54]); ?></option><!-- C2 - F5 -->
              <option value="OOOOOOOOOOOOOOOOOXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXOOOOOOO"><?php echo($noteOctave[18] . " - " . $noteOctave[54]); ?></option><!-- F2 - F5 -->
              <option value="OOOOOOOOOOOOOOOOOOOOOOOOXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXOOOOOOO"><?php echo($noteOctave[25] . " - " . $noteOctave[54]); ?></option><!-- C3 - F5 -->
              <option value="XOXOXXOXOXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXOOOOOOOOOOOO"><?php echo($langue[5][$langueActive]); ?></option><!-- Octave courte -->
             </select>
            </th>
           </tr>
          </table>
         </td>
        </tr>
       </table> <!-- Fin de la table de la coche des notes. -->
      </form>
     </td> <!-- Fin de la cellule de gauche. -->

     <!-- Cellule de droite. -->
     <td valign="top" align="center">
      <h2><font color="#008000"><?php echo($langue[6][$langueActive]); ?>:</font></h2><br />

      <form name="form_02">
       <!-- Table de la sélection des données générales. -->
       <table border="5" cellpadding="14" cellspacing="0" bgcolor="#f5e9cf" background="img/ingres.jpg" width="75%">
        <tr>
         <td>
          <table border="0" cellpadding="7" cellspacing="0" width="100%">
           <tr>
            <td>
             <table border="0" width="100%" cellpadding="0" cellspacing="0">
              <tr>
               <td width="1%" nowrap><b><?php echo($langue[9][$langueActive]); ?>:</b>  </td>
               <td class="pointsDeSuite"> </td>
               <td align="right" width="1%" nowrap>
                 
                <input type="text" name="nomjeu" size="25" value="<?php echo($langue[17][$langueActive]); ?>" onFocus="javaScript:this.select()" onChange="javaScript:changeTitrePleinJeu()" class="fondSaisie" />
               </td>
              </tr>
             </table>
            </td>
           </tr>
           <tr>
            <td>
             <table border="0" width="100%" cellpadding="0" cellspacing="0">
              <tr>
               <td width="1%" nowrap><b><?php echo($langue[10][$langueActive]); ?>:</b>  </td>
               <td class="pointsDeSuite"> </td>
               <td align="right" width="1%" nowrap>
                 
                <select name="nbRangs" onChange="javaScript:changeAffich(document.form_02.nbReps.value, this.value); changeTitrePleinJeu()" class="fondSaisie">
<?php
for ($i = 1; $i <= 16; $i++)
{
 echo("                 <option value=\"" . $i . "\"");
 if ($i == $lignes) {echo(" selected"); };
 echo(">" . $nbRanRom[$i] . " </option>\n");
}; ?>
                </select>
               </td>
              </tr>
             </table>
            </td>
           </tr>
           <tr>
            <td>
             <table border="0" width="100%" cellpadding="0" cellspacing="0">
              <tr>
               <td width="1%" nowrap><b><?php echo($langue[11][$langueActive]); ?>:</b>  </td>
               <td class="pointsDeSuite"> </td>
               <td align="right" width="1%" nowrap>
                 
                <select name="nbReps" onChange="javaScript:changeAffich(this.value, document.form_02.nbRangs.value)" class="fondSaisie">
<?php
for ($i = 1; $i <= 16; $i++)
{
 echo("                 <option value=\"" . $i . "\"");
 if ($i == $colonnes) {echo(" selected"); };
 echo(">" . $i . " </option>\n");
}; ?>
                </select>
               </td>
              </tr>
             </table>
            </td>
           </tr>
           <tr>
            <td>
             <table border="0" width="100%" cellpadding="0" cellspacing="0">
              <tr>
               <td width="1%" nowrap><b><?php echo($langue[12][$langueActive]); ?>:</b>  </td>
               <td class="pointsDeSuite"> </td>
               <td align="right" width="1%" nowrap>
                 
                <select name="notNot" class="fondSaisie" onChange="javaScript:verifNotAllemande(); renommeCoch(this.value); actuListeRep(0);">
<?php
for ($i = 1; $i <= count($note); $i++)
{
 echo("                <option value=\"" . $i . "\"");
 if ($i == $notNot) {echo(" selected"); };
 echo(">" . $note[$i][0] . "</option>\n");
};
?>
                </select>
               </td>
              </tr>
             </table>
            </td>
           </tr>
           <tr>
            <td>
             <table border="0" width="100%" cellpadding="0" cellspacing="0">
              <tr>
               <td width="1%" nowrap><b><?php echo($langue[13][$langueActive]); ?>:</b>  </td>
               <td class="pointsDeSuite"> </td>
               <td align="right" width="1%" nowrap>
                 
                <select name="notOct" class="fondSaisie" onChange="javaScript:verifNotAllemande(); renommeCoch(document.form_02.notNot.value); actuListeRep(0);">
                 <option value="1"<?php if ($notOct == 1) {echo(" selected"); }; echo (">" . $langue[21][$langueActive]); ?></option>
                 <option value="2"<?php if ($notOct == 2) {echo(" selected"); }; echo (">" . $langue[22][$langueActive]); ?></option>
                </select>
               </td>
              </tr>
             </table>
            </td>
           </tr>
           <tr>
            <td>
             <table border="0" width="100%" cellpadding="0" cellspacing="0">
              <tr>
               <td width="1%" nowrap><b><?php echo($langue[14][$langueActive]); ?>:</b>  </td>
               <td class="pointsDeSuite"> </td>
               <td align="right" width="1%" nowrap>
                 
                <?php echo($langue[15][$langueActive]); ?>:
                <input type="text" name="l_img" size="4" maxlength="3" onKeyPress="return scanTouche(event);" value="<?php echo($largImgGraph); ?>" onFocus="javaScript:this.select(); memo=this.value;" onBlur="javaScript:controle(this, 1, memo);" class="fondSaisie" /> -
                <?php echo($langue[16][$langueActive]); ?>:
                <input type="text" name="h_img" size="4" maxlength="3" onKeyPress="return scanTouche(event);" value="<?php echo($hautImgGraph); ?>" onFocus="javaScript:this.select(); memo=this.value;" onBlur="javaScript:controle(this, 2, memo);" class="fondSaisie" />
               </td>
              </tr>
             </table>
            </td>
           </tr>
          </table>
         </td>
        </tr>
       </table> <!-- Fin de la table de la sélection des données générales. -->
      </form>

      <br /><br /><h2><font color="#008000"><?php echo($langue[7][$langueActive]); ?>:</font></h2><br />

      <form name="form_03">
       <!-- Table de la sélection des reprises. -->
       <table border="5" cellpadding="15" cellspacing="0" bgcolor="#f5e9cf" background="img/ingres.jpg">
        <tr>
         <caption align="top"><font size="+1"><b><span id="titrePleinJeu"><?php echo($langue[17][$langueActive] . " " . $nbRanRom[$lignes]); ?></span></b></font></caption>
         <td>
          <table border="0" cellpadding="0" cellspacing="0">
           <tr><th colspan="3" align="left"><?php echo($langue[23][$langueActive]); ?>:</th></tr>
           <tr>
            <td valign="top" rowspan="2">
             <select id="listeRep" onChange="javaScript:re2(cellActive)" onBlur="javaScript:memoCell(cellActive)" class="fondsaisie">
<?php
for ($i = 2; $i <= 54; $i++)
{
 echo("               <option value=\"" . $i . "\"");
 if ($i == 13) {echo(" selected"); };
 echo(">" . $noteOctave[$i] . "</option>\n");
};
?>
             </select>
            </td>
            <td rowspan="3" width="10"> </td>
            <td>
             <table border="0">
              <tr>
               <td id="cellTdRep_1" class="affiCell"><input type="text" id="cellInputRep_1" readOnly="1" value="<?php echo($noteOctave[ord(substr($noterep, 0 , 1))]);?>" size="4" class="fondSaisieDisabled" /></td>
<?php for ($i = 2; $i <= 16; $i++){ ?>
               <td id="cellTdNot_<?php echo($i . "\"");

// Neutralisation des cellules (colonnes).
if ($i > $colonnes) {echo(" class=\"disparait\""); } else {echo(" class=\"affiCell\""); };

?>><input type="text" value="<?php echo($noteOctave[ord(substr($noterep, ($i - 1) , 1))]);?>" id="cellInputRep_<?php echo($i);?>" onFocus="a=0; cellActive=this; re1(cellActive)" size="4" class="fondSaisie" /></td>
<?php }; ?>
               </td>
              </tr>
             </table>
            </td>
           </tr>
           <tr><td><hr></td></tr>
           <tr>
            <td valign="top">
             <b><?php echo($langue[24][$langueActive]); ?>:</b><br />
             <select id="listeTessi" onChange="javaScript:te2(cellActive)" onBlur="javaScript:memoCell(cellActive)" class="fondSaisie">
<?php
for ($i = 0; $i <= 121; $i++)
{
 if (isset($nomTessi[$i]))
 {
  echo("              <option value=\"" . $i . "\"");
  if ($i == 49) {echo(" selected"); };
  echo(">" . $nomTessi[$i] . "</option>\n");
 };
};
?>
             </select>

             <br /><br />
             <center>
              <input type="button" value="<?php echo($langue[25][$langueActive]); ?>" onClick="javaScript:if (cellActive.id.indexOf('cellInputRep') != -1) {re2(cellActive); } else {te2(cellActive); };" class="bouton" />
             </center>
            </td>
            <td valign="top">
             <table border="0">
<?php for ($j = 1; $j <= 16; $j++){ ?>
              <tr id="ligne_<?php echo($j . "\"");

// Neutralisation des lignes vides (ceci est fait pour éviter les <tr></tr> vide qui prennent quand même de la place même quand les <td></td> sont neutralisés.
if ($j > $lignes) {echo(" class=\"disparait\""); } else {echo(" class=\"affiLigne\""); };
echo(">\n");

for ($i = 65; $i <= 80; $i++){ ?>
               <td id="cellTdTessi_<?php echo(chr($i) . $j . "\"");

// Neutralisation des cellules (colonnes).
if ((($i - 64) > $colonnes) || ($j > $lignes)) {echo(" class=\"disparait\""); } else {echo(" class=\"affiCell\""); };
$noCell = (($j - 1) * 16) + ($i - 64);
?>><input type="text" value="<?php echo($nomTessi[ord(substr($comprep, ($noCell - 1), 1))]);?>" id="cellInputTessi_<?php echo($noCell);?>" onFocus="javaScript:cellActive=this; te1(cellActive)" size="4" class="fondSaisie" /></td>
<?php }; ?>
               <td background="img/pix.gif" bgcolor="<?php echo($couleur[$j]); ?>"> </td>
              </tr>
<?php }; ?>
             </table>
            </td>
           </tr>
          </table>
         </td>
        </tr>
       </table> <!-- Fin de la table de la sélection des reprises -->
      </form>

      <br /><br /><h2><font color="#008000"><?php echo($langue[8][$langueActive]); ?>:</font></h2><br />

      <!-- Table des commandes et résultats -->
      <table border="5" cellpadding="14" cellspacing="0" bgcolor="#f5e9cf" background="img/ingres.jpg" width="85%">
       <tr>
        <td>
         <table border="0" cellpadding="0" cellspacing="0" width="100%">
          <tr valign="top">
           <td align="center" width="48%">
            <fieldset>
             <legend title="Organ Definition Language (XML)"><?php echo($langue[26][$langueActive]); ?></legend>
             <form name="form_04" ENCTYPE="multipart/form-data" method="POST" action="pleinjeu.php?l=<?php echo($listeLangue[$langueActive]); ?>">
              <input type="hidden" name="MAX_FILE_SIZE" value="50000" />
              <input type="file" name="XMLfichier" size="20" title="Organ Definition Language (XML)" class="fondSaisie" /><br /><br />
              <input type="button" value="<?php echo($langue[28][$langueActive]); ?>" onClick="javaScript:controle(document.form_04.XMLfichier, 3, '');" title="Organ Definition Language (XML)" class="bouton" />
             </form>
            </fieldset>
           </td>
           <td width="4%"> </td>
           <td width="48%">
            <fieldset>
             <legend><?php echo($langue[27][$langueActive]); ?></legend>
             <form name="form_05">
              <table border="0" cellpadding="0" cellspacing="0" width="100%">
               <tr valign="top">
                <td width="25%">
                 <input type="button" value="<?php echo($langue[29][$langueActive]); ?>" onClick="javaScript:debit()" class="bouton" />
                </td>
                <td width="10%"> </td>
                <td nowrap>
                 <input name="formatSortie" type="radio" value="1" id="html" class="fondSaisie" checked />    
                 <label for="html" style="cursor:pointer;" title="Hyper Text Markup Language">H.T.M.L.</label><br />
                 <input name="formatSortie" type="radio" value="2" id="rtf" class="fondSaisie" />    
                 <label for="rtf" style="cursor:pointer;" title="Rich Text Format">R.T.F.</label><br />
                 <input name="formatSortie" type="radio" value="3" id="txt" class="fondSaisie" />    
                 <label for="txt" style="cursor:pointer;" title="TXT"><?php echo($langue[30][$langueActive]); ?></label><br />
                 <input name="formatSortie" type="radio" value="4" id="odl" class="fondSaisie" />    
                 <label for="odl" style="cursor:pointer;" title="Organ Definition Language (XML)">O.D.L.</label>
                </td>
               </tr>
              </table>
             </form>
            </fieldset>
           </td>
          </tr>
          <tr>
           <td colspan="3" align="center">
            <br />
            <input type="button" value="<?php echo($langue[32][$langueActive]); ?>" onClick="javaScript:ouvre('aide');" class="bouton" />
                 
            <input type="button" value="<?php echo($langue[31][$langueActive]); ?>" onClick="javaScript:recharge();" class="bouton" />      
           </td>
          </tr>
         </table>
        </td>
       </tr>
      </table> <!-- Fin de la table des commandes et résultats -->

      <br /><br /><br /><br />
      <table border="0" cellpadding="0" cellspacing="0"  title="S.M.C.J. me direxit"><tr><td><pre><b><font color="#000080">
    ____  ____  ____  ____   
   /\   \/\   \/\   \/\   \  
  /  \___\ \___\ \___\ \___\ 
  \  / __/_/   / /   / /   / 
   \/_/\   \__/\/___/\/___/  
     /  \___\ <a href="./src/code.php" target="_blank" style="text-decoration:none" alt="Code source" title="Code source">  </a> /  \___\    
     \  / __/_<a href="./src/code.php" target="_blank" style="text-decoration:none" alt="Code source" title="Code source">  </a>_\  /   /    
      \/_/\   \/\ \/___/     
        /  \__/  \___\       
        \  / _\  /   /       
         \/_/\ \/___/        
           /  \___\          
           \  /   /          
            \/___/           
</font></b></pre></td></tr></table>

      <!-- C'est le seul formulaire (très léger) qui est envoyé. -->
      <form name="form_06" method="post" action="pleinjeu.php?l=<?php echo($listeLangue[$langueActive]); ?>" target="_blank">
       <!-- Contient les cases à cocher de form_01, les données générales de form_02 et le type de sortie de form_05. -->
       <input type="hidden" name="t1" value="" />
       <!-- Contient les notes de reprises de form_03. -->
       <input type="hidden" name="t2" value="<?php echo base64_encode($noterep); ?>" />
       <!-- Contient la composition de form_03. -->       
       <input type="hidden" name="t3" value="<?php echo base64_encode($comprep); ?>" />
      </form>
     </td> <!-- Fin de la cellule de droite -->
    </tr>
   </table>

<?php
 }  // Fin de la condition d'affichage du formulaire.
 else
 {  // Début de l'affichage des résultats.
?>

  <!-- Début du code du tableau de composition -->
  <div id="tableauCompo" onClick="cacheBlock(this);" style="cursor:pointer;" title="<?php echo($langue[49][$langueActive]); ?>">
   <table border="5" width="75%" cellpadding="0" cellspacing="0" bgcolor="#f5e9cf" background="img/ingres.jpg">
    <caption><p><b><?php echo($langue[45][$langueActive]); ?></b></p><br /></caption>
<?php
 titreTab();
 for ($i = 1; $i <= $nbRan; $i++)
 {
  echo ("    <tr align=\"center\" valign=\"bottom\">\n");
  for ($j = 1; $j <= $nbRep; $j++)
  {
   $chaine = $nomTessi[$tessi[($i - 1)][($j - 1)]];
   echo("     <td> <font color=\"" . $couleur[$i] . "\">" . expoTessi($chaine) . "</font></td>\n");
  };
  echo ("    </tr>\n");
 };
 titreTab();
?>
   </table>
   <br /><br />
  </div>
  <!-- Fin du code du tableau de composition -->

  <!-- Début du code du pseudo-graphique -->
  <div id="tableauASCII" onClick="cacheBlock(this);" style="cursor:pointer;" title="<?php echo($langue[49][$langueActive]); ?>">
   <table border="5" width="75%" cellpadding="15" cellspacing="0" bgcolor="#f5e9cf" background="img/ingres.jpg">
    <caption><p><b><?php echo($langue[46][$langueActive]); ?></b></p><br /></caption><tr><td align="center">
    <table border="0" cellpadding="0" cellspacing="0">
     <tr><td><font size="2"><b><pre>
<?php
 debitASCII();
?>
     </pre></b></font></td></tr>
    </table>
   </td></tr></table>
   <br /><br />
  </div>
  <!-- Fin du code du pseudo-graphique -->
  
  <!-- Début du code du tableau de débit -->
  <div id="tableauDebit" onClick="cacheBlock(this);" style="cursor:pointer;" title="<?php echo($langue[49][$langueActive]); ?>">
   <table border="5" width="75%" cellpadding="0" cellspacing="0" bgcolor="#f5e9cf" background="img/ingres.jpg">
    <caption><p><b><?php echo($langue[47][$langueActive]); ?></b></p><br /></caption>
    <tr>
     <td> </td><?php
 for ($i = (($premOct * 12) + 1); $i <= (($dernOct * 12) + 1); $i += 12)
 {
  echo("<th> " . $nomTessi[$i] . " </th>");
 }
 for ($i = 1; $i <= 12; $i++)
 {
  echo("    </tr>\n    <tr align=\"center\"><th align=\"left\"> " . $affiNote[$notNot][$i] . " </th>");
  for ($j = $premOct; $j <= $dernOct; $j++)
  {
   $a = ord(substr($cell[($j * 12) + $i], 0, 1)); if ($a == 0) {$a = " ";}
   echo("<td>" . $a . "</td>");
  };
 };
?>
    </tr>
   </table>
   <br /><br />
  </div>
  <!-- Fin du code du tableau de débit -->

  <!-- Début du tableau de l'image graphique -->
  <div id="tableauGraphique" onClick="cacheBlock(this);" style="cursor:pointer;" title="<?php echo($langue[49][$langueActive]); ?>">
   <br />
   <table border="5" cellpadding="0" cellspacing="0" bgcolor="#f5e9cf" background="img/ingres.jpg">
    <tr>
<?php $chaine = "pleinjeuGraph.php?haut=" . $haut . "&bas=" . $bas . "&t1=" . $t1 . "&t2=" . $t2 . "&t3=" . $t3; ?>
     <td><img width="<?php echo($l_img); ?>" height="<?php echo($h_img); ?>" border="0" alt="<?php echo($nomJeu); ?>" title="<?php echo($nomJeu); ?>" src="<?php echo($chaine); ?>"></td>
    </tr>
   </table>
   <br /><br />
  </div>
  <!-- Fin du tableau de l'image graphique -->

  <p align="center"><b><?php echo($langue[48][$langueActive] . " <font color=\"#ff0000\">" . $nbTuy); ?></font>.</b></p>
  <br /><br />
<?php
 }; // Fin de la condition de l'affichage des résultats.
?>
  </center>

  <br /><br />

 </body>
</html>

<?php
 }; // Fin de la condition sur la sortie HTML.

 switch ($traitementFormSort) // Formats de sortie autre qu'HTML
 {
  case 2 :          // Sortie RTF.
   header("Content-type:application/rtf");
   header("Content-Disposition:attachment; filename=\"" . $nomJeu . " " . $nbRanRom[$nbRan] . ".rtf\"");
?>
{\rtf1\ansi\ansicpg1252\deff0\deftab720
{\fonttbl
{\f0\fswiss MS Sans Serif;}
{\f1\froman\fcharset2 Symbol;}
{\f2\froman Times New Roman;}
{\f3\fmodern Courier New;}
}
{\colortbl;
<?php
 for ($i = 1; $i <= 16; $i++)
 {
  echo("\\red" . base_convert(substr($couleur[$i], 1, 2), 16, 10) . "\\green" . base_convert(substr($couleur[$i], 3, 2), 16, 10) . "\\blue" . base_convert(substr($couleur[$i], 5, 2), 16, 10) . ";\n");
 };
?>
}
\par\plain\qc\f2\fs32\cf1\i\b <?php echo($nomJeu . " " . $nbRanRom[$nbRan]); ?>
\par\plain\qj\f2\fs24\ 
<?php
 // RTF-RTF-RTF-RTF-RTF - Début de l'affichage du tableau de composition - RTF-RTF-RTF-RTF-RTF
 echo("\par\plain\qj\\f2\cf1\n");
 echo("\par\plain\qj\li1136\\f2\\fs24\b " . str_replace(" ", "\~", $langue[45][$langueActive]));
 echo("\par\pard\plain\qj\\f2\\fs24\cf1\n");

 titreTab();
 for ($i = 1; $i <= $nbRan; $i++)
 {
  echo ("\par\plain\qj\\f2\\fs24\cf$i");
  for ($j = 1; $j <= $nbRep; $j++)
  {
   $chaine = $nomTessi[$tessi[($i - 1)][($j - 1)]]; echo("\\tab " . expoTessi($chaine));
  };
  echo ("\n");
 };
 titreTab();
 echo("\par\pard\plain\qj\\f2\\fs24\cf1 \n\par \n");
 // RTF-RTF-RTF-RTF-RTF - Fin de l'affichage du tableau de composition - RTF-RTF-RTF-RTF-RTF

 // RTF-RTF-RTF-RTF-RTF - Début de l'affichage du pseudo-graphique - RTF-RTF-RTF-RTF-RTF
 echo("\par\plain\qj\li1136\\f2\\fs24\b " . str_replace(" ", "\~", $langue[46][$langueActive]));
 echo("\par \n\par \n\pard\li1136\\f3\\fs12\b");
 debitASCII();
 echo("\par\li0\plain\\f2\\fs24 \n");
 // RTF-RTF-RTF-RTF-RTF - Fin de l'affichage du pseudo-graphique - RTF-RTF-RTF-RTF-RTF

 // RTF-RTF-RTF-RTF-RTF - Début de l'affichage du tableau de débit - RTF-RTF-RTF-RTF-RTF
 echo("\par\plain\qj\\f2\cf1");
 $chaine = str_replace(" ", "\~", $langue[47][$langueActive]); $chaine = str_replace("é", "\\'e9", $chaine);
 echo("\par\plain\qj\li1136\\f2\\fs24\b " . $chaine);
 echo("\par\pard\plain\qj\\f2\\fs24\cf1");

 echo("\par\plain\qj\\f2\\fs24\cf1\b"); $tabulateur = 1136;               // Premier tabulateur à deux centimètres.
 for ($i = (($premOct * 12) + 1); $i <= (($dernOct * 12) + 1); $i += 12)
 {
  echo("\\tx$tabulateur"); $tabulateur += 852;                            // Tabulateur tous les 1.5 centimètres.
 };
 echo("\\tx$tabulateur\\tab ");

 for ($i = (($premOct * 12) + 1); $i <= (($dernOct * 12) + 1); $i += 12)
 {
  echo("\\tab " . $nomTessi[$i]);
 };
 for ($i = 1; $i <= 12; $i++)
 {
  echo("\par\plain\qj\\f2\\fs24\cf1\b\\tab " . utf8_decode( $affiNote[$notNot][$i] ) . "\plain\\f2\\fs24\cf1");
  for ($j = $premOct; $j <= $dernOct; $j++)
  {
   $a = ord(substr($cell[($j * 12) + $i], 0, 1)); if ($a == 0) {$a = "-";}
   echo("\\tab " . $a);
  };
  echo("\n");
 };
 echo("\par\pard\plain\\f2\\fs24\cf1");
 // RTF-RTF-RTF-RTF-RTF - Fin de l'affichage du tableau de débit - RTF-RTF-RTF-RTF-RTF

 echo("\par\plain\qc\\f2\\fs24\b " . str_replace(" ", "\~", $langue[48][$langueActive]) . " \plain\\f2\\fs24\cf2\b " . $nbTuy . "\plain\\f2\\fs24.\n\par\n");
?>
\par
\par
\par }
<?php
  break;            // Fin de la sortie RTF.

  case 3 :          // Sortie TXT.
   header("Content-type:application/txt");
   header("Content-Disposition:attachment; filename=\"" . $nomJeu . " " . $nbRanRom[$nbRan] . ".txt\"");

   echo("\n\n             " . $nomJeu . " " . $nbRanRom[$nbRan] . "\n\n");

   // TXT-TXT-TXT-TXT-TXT - Début de l'affichage du tableau de composition - TXT-TXT-TXT-TXT-TXT
   echo("             " . str_replace(" ", " ", $langue[45][$langueActive]) . "\n\n");
   titreTab();
   for ($i = 1; $i <= $nbRan; $i++)
   {
    for ($j = 1; $j <= $nbRep; $j++) {echo("\t" . $nomTessi[$tessi[($i - 1)][($j - 1)]]); };
    echo ("\n");
   };
   titreTab(); echo("\n\n");
   // TXT-TXT-TXT-TXT-TXT - Fin de l'affichage du tableau de composition - TXT-TXT-TXT-TXT-TXT

   // TXT-TXT-TXT-TXT-TXT - Début de l'affichage du pseudo-graphique - TXT-TXT-TXT-TXT-TXT
   echo("             " . str_replace(" ", " ", $langue[46][$langueActive]) . "\n\n");
   debitASCII();
   echo("\n\n");
   // TXT-TXT-TXT-TXT-TXT - Fin de l'affichage du pseudo-graphique - TXT-TXT-TXT-TXT-TXT


   // TXT-TXT-TXT-TXT-TXT - Début de l'affichage du tableau de débit - TXT-TXT-TXT-TXT-TXT
   $chaine = str_replace(" ", " ", $langue[47][$langueActive]); $chaine = str_replace("é", "é", $chaine);
   echo("             " . $chaine . "\n\n\t");
   for ($i = (($premOct * 12) + 1); $i <= (($dernOct * 12) + 1); $i += 12) {echo("\t" . $nomTessi[$i]); };
   echo("\n");
 
   for ($i = 1; $i <= 12; $i++)
   {
    echo("\t" . $affiNote[$notNot][$i]);
    for ($j = $premOct; $j <= $dernOct; $j++)
    {
     $a = ord(substr($cell[($j * 12) + $i], 0, 1)); if ($a == 0) {$a = "-";}
     echo("\t" . $a);
    };
    echo("\n");
   };
   // TXT-TXT-TXT-TXT-TXT - Fin de l'affichage du tableau de débit - TXT-TXT-TXT-TXT-TXT

  break;            // Fin de la sortie TXT.

  case 4 :          // Sortie XML.
   header("Content-type:application/xml");
   header("Content-Disposition:attachment; filename=\"" . $nomJeu . " " . $nbRanRom[$nbRan] . ".odl\"");
   echo ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
?>
<ODL version="0.1">
 <KB name="<?php echo($nomJeu); ?>">
  <PRESENT_NOTE>
   <?php echo(substr($noteCoche, 0, 61) . "\n"); ?>
  </PRESENT_NOTE>
 </KB>
 <MIXTURE name="<?php echo($nomJeu); ?>" def_kb="<?php echo($nomJeu); ?>">
<?php
for ($j = 0; $j < $nbRan; $j++)
{ ?>
  <RANK>
<?php
 for ($i = 0; $i < $nbRep; $i++)
 {
  echo("   <BREAK pos=\"" . $repri[$i] . "\" range=\"" . $tessi[$j][$i] . "\" />\n");
 }; ?>
  </RANK>
<?php
}; ?>
 </MIXTURE>
</ODL>

<?php
  break;           // Fin de la sortie XML
 };

?>
   


pleinjeuGraph.php.

<?php

 // ***************************************************
 // *** Image graphique de plein jeu au format PNG. ***
 // ***************************************************

 // Les constantes déterminées dans ce fichier include sont partagées par le script principal (./pleinjeu.php).
 include("./pleinjeu.inc.php");

   $t1 = isset($_GET ['t1'])   ? $_GET ['t1']   : "";
   $t2 = isset($_GET ['t2'])   ? $_GET ['t2']   : "";
   $t3 = isset($_GET ['t3'])   ? $_GET ['t3']   : "";
 $haut = isset($_GET ['haut']) ? $_GET ['haut'] : 0;
  $bas = isset($_GET ['bas'])  ? $_GET ['bas']  : 0;

 // Analyse de la chaîne pour mettre les fractions des tessitures en exposant.
 function expoTessi($im, $x, $y, $chaine, $coul)
 {
  $place = strpos($chaine, "'");
  if (($place >= 1) && ($place != (strlen($chaine) - 1)))
  {
   imagestring ($im, 2, $x, $y, substr($chaine, 0, ($place + 1)), $coul);
   imagestring ($im, 1, ($x + 17), ($y - 2), substr($chaine, ($place + 1)), $coul);
  }
  else
  {
   imagestring ($im, 2, $x, $y, substr($chaine, 0, ($place + 1)), $coul);
  }
 }

 // +--------------------------------------------------------------+
 // | Récupération des variables à partir des chaînes transférées. |
 // +--------------------------------------------------------------+

 $chaine = base64_decode($t1);                                          // Décodage de la chaîne $t1.

 $noteCoche = "";                                                       // Notes du clavier.
 for ($i = 0; $i <= 7; $i++)
 {
  $chaine1 = decbin(ord(substr($chaine, $i, 1))); while (strlen($chaine1) < 8) {$chaine1 = "0" . $chaine1;}
  $noteCoche .= $chaine1;
 };
    $nbNot = strlen(rtrim(substr($noteCoche, 0, 61), "0"));             // Nombre de notes

    $nbRan =    decodeVal(substr($chaine,  8,                      2)); // Nombre de rangs.
    $nbRep =    decodeVal(substr($chaine, 10,                      2)); // Nombre de reprises.
   $notNot =    decodeVal(substr($chaine, 12,                      2)); // Notation des notes.
   $notOct =    decodeVal(substr($chaine, 14,                      2)); // Notation des octaves.
    $l_img =    decodeVal(substr($chaine, 16,                      2)); // Largeur de l'image graphique.
    $h_img =    decodeVal(substr($chaine, 18,                      2)); // Hauteur de l'image graphique.
 $formSort =    decodeVal(substr($chaine, 20,                      2)); // Format de sortie.
   $nomJeu = stripslashes(substr($chaine, 22, (strlen($chaine) - 22))); // Nom du jeu (255 octets maximum).

 // Valeurs des notes de reprises (index à 1 au contraire de pleinjeu.php).
 $chaine = base64_decode($t2);                                          // Décodage de la chaîne $t2.
 for ($i = 1; $i <= 16; $i++) {$repri[$i] = ord(substr($chaine, ($i - 1), 1)); };

 // Valeurs des tessitures (index à 1 au contraire de pleinjeu.php).
 $chaine = base64_decode($t3);                                          // Décodage de la chaîne $t3.
 for ($i = 1; $i <= 16; $i++)
 {
  for ($j = 1; $j <= 16; $j++) {$tessi[$i][$j] = ord(substr($chaine, ((($i - 1) * 16) + ($j - 1)), 2)); };
 };

 $nomFichier = $nomJeu . " " . $nbRanRom[$nbRan];
 header("Content-Type:image/png"); 
 header("Content-Disposition:filename=\"" . $nomFichier . ".png\"");

 // +----------------------------+
 // | Construction du graphique. +
 // +----------------------------+
 $im = imagecreate($l_img, $h_img); $l_img--; $h_img--; 

 // Détermination des couleurs.
 $fond = imagecolorallocate($im, 0xf5, 0xe9, 0xcf); imagecolortransparent($im, $fond);
 for ($i = 1; $i <= 16; $i++)
 {
  $couleur[$i] = imagecolorallocate($im, base_convert(substr($couleur[$i], 1, 2), 16, 10), base_convert(substr($couleur[$i], 3, 2), 16, 10), base_convert(substr($couleur[$i], 5, 2), 16, 10));
 };

 imagefill($im, 0, 0, $fond);

 // Marge des reprises et des tessitures et police de caractère employée.
 $mt = 50; $mr = 40; $police = 2; 

 // Largeur et hauteur du graphique ($lg et $hg).
 // On relève $haut pour pouvoir faire suivre les lignes sans rupture même si c'est de la triche.
 $haut++; $lg = ($l_img - $mt); $hg = ($h_img - $mr);

 // Nombre de tessitures présentes dans le graphique.
 $nbtessi = ($haut - $bas) + 1;

 // Largeur et hauteur PAR DEFAUT de chaque cellule du graphique ($lc et $hc).
 $lc = floor($lg / $nbNot); $hc = floor($hg / $nbtessi);
 for ($i = 1; $i <= $nbNot; $i++) {$x[$i] = $lc;}
 for ($i = 1; $i <= $nbtessi; $i++) {$y[$i] = $hc;}

 // Détermine et dispatche l'erreur.
 $lc_err = floor($lg % $nbNot);  $hc_err = floor($hg % $nbtessi);
 $j = 1; for ($i = 1; $i <= $lc_err; $i++) {$x[$j]++; $j += floor($nbNot / $lc_err);}
 $j = 1; for ($i = 1; $i <= $hc_err; $i++) {$y[$j]++; $j += floor($nbtessi / $hc_err);}

 // Positionne les X et les Y de manière progressive.
 $x[1] += ($mt - $lc - 1); for ($i = 2; $i <= $nbNot;   $i++) {$x[$i] += $x[$i - 1];}
 $y[1] += ($mr - $hc - 1); for ($i = 2; $i <= $nbtessi; $i++) {$y[$i] += $y[$i - 1];}

 // En voiture...
 $repri[$nbRep + 1]  = $nbNot + 1;                         // Pour pouvoir passer la dernière reprise.
 for ($i = 1; $i <= $nbRan; $i++)                          // Boucle des rangs. 
 {
  for ($j = 1; $j <= $nbRep; $j++)                         // Boucle des reprises.
  {
   if ($tessi[$i][$j] != 0)                                // Cas des reprises vides (trous).
   {
    $vrainote = $tessi[$i][$j] + $repri[$j] - 1;           // Première note RÉELLE de la reprise.

    $decal = 0;                                            // Compte les doublures qui vont provoquer un décalage
    for ($k = 1; $k < $i; $k++)
    {
     if (($tessi[$k][$j] + $repri[$j] - 1) == $vrainote) {$decal++;}
    }

    $nbNotRep = $repri[$j + 1] - $repri[$j];               // Nombre de notes dans la reprise.
    if ($j == $nbRep) {$nbNotRep--;}                       // Dernière reprise plus courte d'une note.

    $x1 = $x[$repri[$j]];              $y1 = $y[($haut - $vrainote) + 1] - $decal;
    $x2 = $x[$repri[$j] + $nbNotRep];  $y2 = $y[($haut - $vrainote) - $nbNotRep + 1] - $decal;

    // Trace la reprise.
    imageline ($im, $x1, $y1, $x2, $y2, $couleur[$i]);
   }
  }
 }

 // Marque des tessitures plus graves au milieu de graphique.
 for ($i = 1; $i <= $nbRep; $i++)                         // Boucle des reprises.
 {
  $plusgrave = 121;                                       // Analyse la reprise la plus grave.
  for ($j = 1; $j <= $nbRan; $j++)                        // Boucle des rangs.
  {
   if ($plusgrave > $tessi[$j][$i]) {$plusgrave = $tessi[$j][$i];}
  }

  if ($plusgrave < $bas)
  {
   $vrainote = $plusgrave + $repri[$i] - 1;               // Première note RÉELLE de la reprise.
   // Plantage sur y1 à revoir ; original : $y1 = $y[($haut - $vrainote) + 1];
   $x1 = $x[$repri[$i]];  $y1 = $y[$bas];
   expoTessi($im, ($x1 - 10), ($y1 + 4), $nomTessi[$plusgrave], $couleur[1]);
  }
 }

 // Trace le cadre général.
 imagerectangle ($im, $x[1], $y[1], $x[$nbNot], $y[$nbtessi], $couleur[1]);
 imagestring ($im, 3, $mt, 5, $nomJeu . " " . $nbRanRom[$nbRan], $couleur[1]);

 // Lignes des reprises
 $repri[$nbRep + 1]--;                                    // Pour pouvoir afficher
 for ($i = 1; $i <= ($nbRep + 1); $i++)                   // la dernière note.
 {
  $chaine = $note[$notNot][(($repri[$i] - 1) % 12) + 1];

  // Passe le nom des notes en minuscules.
  if (($notOct == 2) && ($repri[$i] > 12)) {$chaine = strtolower($chaine);}

  if ($notOct == 1)                                       // Notation numérique.
  {
   $chaine .= (floor($repri[$i] / 12) + 1);
  }
  else                                                    // Notation allemande des octaves.
  {
   if (($repri[$i] >= 12) && ($repri[$i] < 25))           // Affiche le null.
   {
    $chaine .= "o";                                       // On attend que PHP gère l'UTF8.
   }
   if ($repri[$i] >= 25)                                  // Affiche les guillemets.
   {
    for ($j = 1; $j <= (floor($repri[$i] / 12) - 1); $j++) {$chaine .= "'";}
   }
  }

  // Retrait à gauche plus important pour la dernière note.
  if ($i == ($nbRep +1)) {$j = (6 * $notOct);} else {$j = 0;}

  imagestring ($im, $police, ($x[$repri[$i]] - $j), ($y[1] - 15), $chaine, $couleur[1]);
  imageline ($im, $x[$repri[$i]], $y[1], $x[$repri[$i]], $y[$nbtessi], $couleur[1]);
 }

 // Lignes des tessitures
 for ($i = 1; $i <= $nbtessi; $i++)
 {
  if (((($i - $haut) % 12) == 0 ) || ((($i + 7- $haut) % 12) == 0 ))
  {
   expoTessi($im, 10, ($y[$i] - 10), $nomTessi[($haut - $i + 1)], $couleur[1]);
   imageline ($im, $x[1], $y[$i], $x[$nbNot], $y[$i], $couleur[1]);
  }
 }

 imagepng($im); imagedestroy($im);

/*
 // Cadrillage éventuel (très utile pour la programmation).
 $gris = imagecolorallocate($im, 191, 191, 191);
 imagerectangle ($im, $mt, $mr, $l_img, $h_img, $gris);
 // Lignes verticales
 for ($i = 1; $i <= $nbNot; $i++) {imageline ($im, $x[$i], $mr, $x[$i], $h_img, $gris);}
 // Lignes horizontales
 for ($i = 1; $i <= $nbtessi; $i++) {imageline ($im, $mt, $y[$i], $l_img, $y[$i], $gris);}
*/

?>