<?php
/* Fichier PHP: "gestioncommentaires.php"
+------------------------------------------------------------------------------+
| Extension pour une fonction "ajout de commentaires" |
| Tedheu 2009, version 1.0 (fr), mise à jour le 09 novembre 2009 |
| Module script PHP de gestion des commentaires |
| fonctionne de paire avec le module JavaScript "commentaires.js" |
+------------------------------------------------------------------------------+
*/
/*========= Paramètres de personnalisation ===================================*/
// Chaque message a un parametre de validation (index 'v' du tableau $Message)
// avec une valeur de 0 le message est stocké mais ne sera pas affiché
// avec une valeur de 1 le message est stocké et sera affiché
// avec une valeur de -1 le message sera retiré du fichier de stockage
$validmesdef= 1; // validation par défaut des messages
//
/*========= Variables (initialisation) =======================================*/
$jeton= NULL; // normalement communiqué par variables GET
$sujet= NULL; // normalement communiqué par variables GET
$action= NULL; // normalement communiqué par variables GET
//---
$entetedef= '|=== Fichier de commentaires, T² 09 novembre 2009 - version 1.0 ===|'."\n";
$nouveau= false; // message pas nouveau par défaut
$imesnou= -1; // indice nouveau message mis à -1
//--- messages => tableau de tableaux
// le visteur envoi un commentaire avec d'autres informations l'ensemble forme un message
$Message['*']= array(); // * > jeton $Message['s']= array(); // s > sujet $Message['v']= array(); // v > validation, -1, 0 ou 1 , 0 > non validé, -1 > rejeté $Message['i']= array(); // i > numéro IP $Message['d']= array(); // d > date du jour $Message['h']= array(); // h > heure $Message['n']= array(); // n > nom $Message['c']= array(); // c > commentaire $Message['r']= array(); // r > réservé pour usage futur //--- deux actions possibles: lecture, écriture
$Actionliste= array('lecture','ecriture'); //--- données pour traitement de sécurisation
$tagspermis= '<b><i><u><a><br><small><img>';
$Evenements= array('onAbort','onBlur','onChange','onClick','onDbclick','onDragdrop','onError','onFocus','onKeydown','onKeypress','onKeyup','onLoad','onMouseOver','onMouseOut','onReset','onResize','onSelect','onSubmit','onUnload'); foreach ($Evenements as $evenement){$Clefs[]= '/'.$evenement.'/i';}
$Car_nr= array("\n\r","\r\n","\n","\r"); $Carspe= array('&','ç','¨','£','µ','§','²','³','¤','¿','±'); array_push($Carspe,'à','â','ä','ã','é','è','ê','ë','î','ï','ô','ö','õ','ù','û','ü'); array_push($Carspe,'Â','Ä','Ã','Ê','Ë','Î','Ï','Ô','Ö','Õ','Û','Ü'); //-----------------------------------------------------------------------------/
/*========= Récupération d'informations ======================================*/
//--- informations générales
$ipc=$_SERVER['REMOTE_ADDR']; // numéro IP du visiteur
//--- variables passées par méthode GET
(!empty($_GET['sujet']))?
$sujet=$_GET['sujet']: $sujet='aucun'; (!empty($_GET['action']))?
$action=$_GET['action']: $action='rien'; (!empty($_GET['jeton']))?
$jeton= $_GET['jeton']: $jeton= '0'; //--- traitements des informations GET entrantes
if (!in_array($action,$Actionliste)) $action='rien'; $jeton= preg_replace('/[^0-9]/','',$jeton); // que des chiffres //-----------------------------------------------------------------------------/
/*========= Validation de la requête =========================================*/
$valide= true;
if ($sujet=='aucun') $valide= false;
if ($action=='rien') $valide= false;
if ($jeton=='0') $valide= false;
if (!$valide) {
// arret du script par sécurité si requête non valide
}
/*========= Créations de fichiers si inexistants =============================*/
$nomfichier_verrou= 'verrou_'.$sujet_r.'.txt';
$nomfichier_messag= 'messages_'.$sujet_r.'.txt';
$pf0=fopen($nomfichier_messag,'w'); }
//-----------------------------------------------------------------------------/
//
/*========= Mode écriture ($action= 'ecriture') ==============================*/
if ($action=='ecriture'){
$nouveau= true; // on suppose un nouveau message
//
//=== variables passées par méthode POST ----------------------------------/
(!empty($_POST['nom']))?
$nom= $_POST['nom']: $nom= 'inconnu'; (!empty($_POST['message']))?
$commentaire= $_POST['message']: $commentaire= ''; //--- traitements des informations POST entrantes
$commentaire= strip_tags($commentaire,$tagspermis); $commentaire= str_replace($Carspe,$Carchgs,$commentaire); $commentaire= str_replace($Car_nr,'<br>',$commentaire); $commentaire= preg_replace('/\\\/','',$commentaire); // plus d'anti-slash //-------------------------------------------------------------------------/
//=== accès au fichier des messages en lecture/écriture -------------------/
//--- mise en place du verrou -------------------------
$deb= time(); $tempo= 2; $erreur= ''; do{
$verrou= file($nomfichier_verrou); if (count($verrou)==0) break; }while((time()-$deb)<=$tempo); if (count($verrou)!=0){ // (le verrou est resté bloqué) $erreur.= '-- blocage-verrou --';
$erreur.= ' -- deblocage-force --';
$pfv=fopen($nomfichier_verrou,'w'); }
}
else{ // (si pas d'erreur fermeture du verrou)
$pfv=fopen($nomfichier_verrou,'w'); }
if ($erreur!='') die('ERREUR: '.$erreur); //-----------------------------------------------------
//--- lecture du fichier de messages ligne par ligne
$pf1= fopen($nomfichier_messag,'r'); $n=-1;
while (!feof($pf1)) $ligne[++$n]=fgets($pf1,1024); $nlgn= $n;
//-------------------------------------------------------------------------/
//=== analyse du contenu et traitement ------------------------------------/
$entete=$ligne[0]; // la première ligne est une entête
$imesnou= 0; // indice nouveau message = 0
if ($nouveau){
$Message['*'][0]= $jeton;
$Message['s'][0]= $sujet;
$Message['v'][0]= $validmesdef;
$Message['i'][0]= $ipc;
$Message['d'][0]= $jour;
$Message['h'][0]= $heure;
$Message['n'][0]= $nom;
$Message['c'][0]= $commentaire;
$Message['r'][0]= 'RFU';
}
//--- traitement ligne par ligne
$imes= 1;
$jeton_tst= false; $ipc_tst= false; $heure_tst= false;
for ($ilgn=1; $ilgn<=$nlgn; $ilgn++){
$clef= substr($ligne[$ilgn],0,3); switch($clef){
case '\\*\\': // jeton
$Message['*'][$imes]= $contenu;
($jeton==$contenu)? $jeton_tst= true: $jeton_tst= false; break;
case '\\s\\':
$Message['s'][$imes]= $contenu;
case '\\v\\':
$Message['v'][$imes]= $contenu;
case '\\i\\':
$Message['i'][$imes]= $contenu;
($ipc==$contenu)? $ipc_tst= true: $ipc_tst= false; break;
case '\\d\\':
$Message['d'][$imes]= $contenu;
($jour==$contenu)? $d_tst= true: $d_tst= false; break;
case '\\h\\':
$Message['h'][$imes]= $contenu;
($mindif<=5)? $heure_tst= true: $heure_tst= false;
if ($heudif!=0) $heure_tst= false;
break;
case '\\n\\':
$Message['n'][$imes]= $contenu; break;
case '\\c\\':
$Message['c'][$imes]= $contenu; break;
case '\\r\\':
$Message['r'][$imes]= $contenu; break;
case '\\-\\':
// fin de message
if ($nouveau AND $jeton_tst AND $ipc_tst AND $heure_tst){
// le même que le nouveau
$imesnou= $imes; // indice nouveau message
$Message['h'][$imes]= $heure;
$Message['n'][$imes]= $nom;
$Message['c'][$imes]= $commentaire;
}
$imes++; // au suivant
$jeton_tst= false; $ipc_tst= false; $heure_tst= false;
break;
}
}
$nmes= $imes-1;
//--- réduction des messages si le champ $commentaire est vide
if ($commentaire==''){
$Message['v'][$imesnou]= -1;
$nouveau= 0;
}
//-------------------------------------------------------------------------/
//=== reecriture du fichier de messages -----------------------------------/
$pf2=fopen($nomfichier_messag,'w'); ($nouveau AND ($imesnou==0))? $imesdeb=0: $imesdeb=1;
for ($imes=$imesdeb; $imes<=$nmes; $imes++){
if ($Message['v'][$imes]== -1) continue; // '-1'> le message est effacé
fwrite($pf2,'\\*\\'.$Message['*'][$imes]."\n"); fwrite($pf2,'\\s\\'.$Message['s'][$imes]."\n"); fwrite($pf2,'\\v\\'.$Message['v'][$imes]."\n"); fwrite($pf2,'\\i\\'.$Message['i'][$imes]."\n"); fwrite($pf2,'\\d\\'.$Message['d'][$imes]."\n"); fwrite($pf2,'\\h\\'.$Message['h'][$imes]."\n"); fwrite($pf2,'\\n\\'.$Message['n'][$imes]."\n"); fwrite($pf2,'\\c\\'.$Message['c'][$imes]."\n"); fwrite($pf2,'\\r\\'.$Message['r'][$imes]."\n"); fwrite($pf2,'\\-\\----------'."\n"); }
//-------------------------------------------------------------------------/
//=== libération du verrou ------------------------------------------------/
$pfv=fopen($nomfichier_verrou,'w'); //-------------------------------------------------------------------------/
}// $action== 'ecriture'
//
/*========= Mode lecture ($action= 'lecture') ================================*/
if ($action=='lecture'){
$nouveau= false; // pas de nouveau message
//--- lecture du fichier de messages lignes par lignes
$pf1= fopen($nomfichier_messag,'r'); $n=-1;
while (!feof($pf1)) $ligne[++$n]=fgets($pf1,1024); $nlgn= $n;
//-------------------------------------------------------------------------/
//=== analyse du contenu et traitement ------------------------------------/
$entete=$ligne[0]; // la première ligne est une entête
//--- traitement ligne par ligne
$imes= 1;
for ($ilgn=1; $ilgn<=$nlgn; $ilgn++){
$clef= substr($ligne[$ilgn],0,3); $contenu= substr($ligne[$ilgn],3); switch($clef){
case '\\v\\':
$Message['v'][$imes]= $contenu; break;
case '\\d\\':
$Message['d'][$imes]= $contenu; break;
case '\\h\\':
$Message['h'][$imes]= $contenu; break;
case '\\n\\':
$Message['n'][$imes]= $contenu; break;
case '\\c\\':
$Message['c'][$imes]= $contenu; break;
case '\\-\\': // fin de message
$imes++; // au suivant
break;
}
}
$nmes= $imes-1;
}// $action== 'lecture'
//-----------------------------------------------------------------------------//
/*========= Affichage ========================================================*/
if ($nouveau){
$imes= $imesnou;
echo('<hr><fieldset>');
echo('<legend>Votre nouveau message est enregistré : <i>( vous pouvez encore le modifier )</i></legend>');
echo(' Nom: '.$Message['n'][$imes].'<br>');
echo($Message['c'][$imes]);
echo('</fieldset>');
}
//
echo('<hr>');
for ($imes=1; $imes<=$nmes; $imes++){
if ($Message['v'][$imes]== 0) continue; // '0'> le message n'est pas affiché
if ($imes != $imesnou){
echo('<b>Nom :</b> '.$Message['n'][$imes].' ');
echo('<b>Date :</b> '.$Message['d'][$imes].' '.$Message['h'][$imes].'<br>');
echo($Message['c'][$imes].'<br>');
echo('<hr>'."\n");
}
}
//-----------------------------------------------------------------------------/
?>
PD9waHAKLyogRmljaGllciBQSFA6ICJnZXN0aW9uY29tbWVudGFpcmVzLnBocCIKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKfCBFeHRlbnNpb24gcG91ciB1bmUgZm9uY3Rpb24gImFqb3V0IGRlIGNvbW1lbnRhaXJlcyIgfAp8IFRlZGhldSAyMDA5LCB2ZXJzaW9uIDEuMCAoZnIpLCBtaXNlIMOgIGpvdXIgbGUgMDkgbm92ZW1icmUgMjAwOSB8CnwgTW9kdWxlIHNjcmlwdCBQSFAgZGUgZ2VzdGlvbiBkZXMgY29tbWVudGFpcmVzIHwKfCBmb25jdGlvbm5lIGRlIHBhaXJlIGF2ZWMgbGUgbW9kdWxlIEphdmFTY3JpcHQgImNvbW1lbnRhaXJlcy5qcyIgfAorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKwoqLwovKj09PT09PT09PSBQYXJhbcOodHJlcyBkZSBwZXJzb25uYWxpc2F0aW9uID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ki8KLy8gQ2hhcXVlIG1lc3NhZ2UgYSB1biBwYXJhbWV0cmUgZGUgdmFsaWRhdGlvbiAoaW5kZXggJ3YnIGR1IHRhYmxlYXUgJE1lc3NhZ2UpCi8vIGF2ZWMgdW5lIHZhbGV1ciBkZSAwIGxlIG1lc3NhZ2UgZXN0IHN0b2Nrw6kgbWFpcyBuZSBzZXJhIHBhcyBhZmZpY2jDqQovLyBhdmVjIHVuZSB2YWxldXIgZGUgMSBsZSBtZXNzYWdlIGVzdCBzdG9ja8OpIGV0IHNlcmEgYWZmaWNow6kKLy8gYXZlYyB1bmUgdmFsZXVyIGRlIC0xIGxlIG1lc3NhZ2Ugc2VyYSByZXRpcsOpIGR1IGZpY2hpZXIgZGUgc3RvY2thZ2UKJHZhbGlkbWVzZGVmPSAxOyAvLyB2YWxpZGF0aW9uIHBhciBkw6lmYXV0IGRlcyBtZXNzYWdlcwovLwovKj09PT09PT09PSBWYXJpYWJsZXMgKGluaXRpYWxpc2F0aW9uKSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0qLwokamV0b249IE5VTEw7IC8vIG5vcm1hbGVtZW50IGNvbW11bmlxdcOpIHBhciB2YXJpYWJsZXMgR0VUCiRzdWpldD0gTlVMTDsgLy8gbm9ybWFsZW1lbnQgY29tbXVuaXF1w6kgcGFyIHZhcmlhYmxlcyBHRVQKJGFjdGlvbj0gTlVMTDsgLy8gbm9ybWFsZW1lbnQgY29tbXVuaXF1w6kgcGFyIHZhcmlhYmxlcyBHRVQKLy8tLS0KJGVudGV0ZWRlZj0gJ3w9PT0gRmljaGllciBkZSBjb21tZW50YWlyZXMsIFTCsiAwOSBub3ZlbWJyZSAyMDA5IC0gdmVyc2lvbiAxLjAgPT09fCcuIlxuIjsKJG5vdXZlYXU9IGZhbHNlOyAvLyBtZXNzYWdlIHBhcyBub3V2ZWF1IHBhciBkw6lmYXV0CiRpbWVzbm91PSAtMTsgLy8gaW5kaWNlIG5vdXZlYXUgbWVzc2FnZSBtaXMgw6AgLTEKLy8tLS0gbWVzc2FnZXMgPT4gdGFibGVhdSBkZSB0YWJsZWF1eAovLyBsZSB2aXN0ZXVyIGVudm9pIHVuIGNvbW1lbnRhaXJlIGF2ZWMgZCdhdXRyZXMgaW5mb3JtYXRpb25zIGwnZW5zZW1ibGUgZm9ybWUgdW4gbWVzc2FnZQokTWVzc2FnZT0gYXJyYXkoKTsKJE1lc3NhZ2VbJyonXT0gYXJyYXkoKTsgLy8gKiA+IGpldG9uCiRNZXNzYWdlWydzJ109IGFycmF5KCk7IC8vIHMgPiBzdWpldAokTWVzc2FnZVsndiddPSBhcnJheSgpOyAvLyB2ID4gdmFsaWRhdGlvbiwgLTEsIDAgb3UgMSAsIDAgPiBub24gdmFsaWTDqSwgLTEgPiByZWpldMOpCiRNZXNzYWdlWydpJ109IGFycmF5KCk7IC8vIGkgPiBudW3DqXJvIElQCiRNZXNzYWdlWydkJ109IGFycmF5KCk7IC8vIGQgPiBkYXRlIGR1IGpvdXIKJE1lc3NhZ2VbJ2gnXT0gYXJyYXkoKTsgLy8gaCA+IGhldXJlCiRNZXNzYWdlWyduJ109IGFycmF5KCk7IC8vIG4gPiBub20KJE1lc3NhZ2VbJ2MnXT0gYXJyYXkoKTsgLy8gYyA+IGNvbW1lbnRhaXJlCiRNZXNzYWdlWydyJ109IGFycmF5KCk7IC8vIHIgPiByw6lzZXJ2w6kgcG91ciB1c2FnZSBmdXR1cgovLy0tLSBkZXV4IGFjdGlvbnMgcG9zc2libGVzOiBsZWN0dXJlLCDDqWNyaXR1cmUKJEFjdGlvbmxpc3RlPSBhcnJheSgnbGVjdHVyZScsJ2Vjcml0dXJlJyk7Ci8vLS0tIGRvbm7DqWVzIHBvdXIgdHJhaXRlbWVudCBkZSBzw6ljdXJpc2F0aW9uCiR0YWdzcGVybWlzPSAnPGI+PGk+PHU+PGE+PGJyPjxzbWFsbD48aW1nPic7CiRFdmVuZW1lbnRzPSBhcnJheSgnb25BYm9ydCcsJ29uQmx1cicsJ29uQ2hhbmdlJywnb25DbGljaycsJ29uRGJjbGljaycsJ29uRHJhZ2Ryb3AnLCdvbkVycm9yJywnb25Gb2N1cycsJ29uS2V5ZG93bicsJ29uS2V5cHJlc3MnLCdvbktleXVwJywnb25Mb2FkJywnb25Nb3VzZU92ZXInLCdvbk1vdXNlT3V0Jywnb25SZXNldCcsJ29uUmVzaXplJywnb25TZWxlY3QnLCdvblN1Ym1pdCcsJ29uVW5sb2FkJyk7CmZvcmVhY2ggKCRFdmVuZW1lbnRzIGFzICRldmVuZW1lbnQpeyRDbGVmc1tdPSAnLycuJGV2ZW5lbWVudC4nL2knO30KJENhcl9ucj0gYXJyYXkoIlxuXHIiLCJcclxuIiwiXG4iLCJcciIpOwokQ2Fyc3BlPSBhcnJheSgnJicsJ8OnJywnwqgnLCfCoycsJ8K1JywnwqcnLCfCsicsJ8KzJywnwqQnLCfCvycsJ8KxJyk7CmFycmF5X3B1c2goJENhcnNwZSwnw6AnLCfDoicsJ8OkJywnw6MnLCfDqScsJ8OoJywnw6onLCfDqycsJ8OuJywnw68nLCfDtCcsJ8O2Jywnw7UnLCfDuScsJ8O7Jywnw7wnKTsKYXJyYXlfcHVzaCgkQ2Fyc3BlLCfDgicsJ8OEJywnw4MnLCfDiicsJ8OLJywnw44nLCfDjycsJ8OUJywnw5YnLCfDlScsJ8ObJywnw5wnKTsKYXJyYXlfcHVzaCgkQ2Fyc3BlLCfDsScsJ8ORJyk7CmZvcmVhY2ggKCRDYXJzcGUgYXMgJGNhcil7JENhcmNoZ3NbXT0gaHRtbGVudGl0aWVzKCRjYXIpO30KYXJyYXlfcHVzaCgkQ2Fyc3BlLCclJywnXicpOwphcnJheV9wdXNoKCRDYXJjaGdzLCclJywnXicpOwovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLwovKj09PT09PT09PSBSw6ljdXDDqXJhdGlvbiBkJ2luZm9ybWF0aW9ucyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSovCi8vLS0tIGluZm9ybWF0aW9ucyBnw6luw6lyYWxlcwokaXBjPSRfU0VSVkVSWydSRU1PVEVfQUREUiddOyAvLyBudW3DqXJvIElQIGR1IHZpc2l0ZXVyCiRqb3VyPSBkYXRlKCdkLm0uWScpOwokaGV1cmU9IGRhdGUoJ0g6aScpOwovLy0tLSB2YXJpYWJsZXMgcGFzc8OpZXMgcGFyIG3DqXRob2RlIEdFVAooIWVtcHR5KCRfR0VUWydzdWpldCddKSk/ICRzdWpldD0kX0dFVFsnc3VqZXQnXTogJHN1amV0PSdhdWN1bic7CighZW1wdHkoJF9HRVRbJ2FjdGlvbiddKSk/ICRhY3Rpb249JF9HRVRbJ2FjdGlvbiddOiAkYWN0aW9uPSdyaWVuJzsKKCFlbXB0eSgkX0dFVFsnamV0b24nXSkpPyAkamV0b249ICRfR0VUWydqZXRvbiddOiAkamV0b249ICcwJzsKLy8tLS0gdHJhaXRlbWVudHMgZGVzIGluZm9ybWF0aW9ucyBHRVQgZW50cmFudGVzCiRzdWpldD0gc3Vic3RyKHN0cmlwX3RhZ3MoJHN1amV0KSwwLDMwKTsKJHN1amV0X3I9IHN1YnN0cihzdHJpcF90YWdzKCRzdWpldCksMCwxMCk7CmlmICghaW5fYXJyYXkoJGFjdGlvbiwkQWN0aW9ubGlzdGUpKSAkYWN0aW9uPSdyaWVuJzsKJGpldG9uPSBwcmVnX3JlcGxhY2UoJy9bXjAtOV0vJywnJywkamV0b24pOyAvLyBxdWUgZGVzIGNoaWZmcmVzCiRqZXRvbj0gc3Vic3RyKCRqZXRvbiwwLDEwKTsKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS8KLyo9PT09PT09PT0gVmFsaWRhdGlvbiBkZSBsYSByZXF1w6p0ZSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSovCiR2YWxpZGU9IHRydWU7CmlmICgkc3VqZXQ9PSdhdWN1bicpICR2YWxpZGU9IGZhbHNlOwppZiAoJGFjdGlvbj09J3JpZW4nKSAkdmFsaWRlPSBmYWxzZTsKaWYgKCRqZXRvbj09JzAnKSAkdmFsaWRlPSBmYWxzZTsKaWYgKCEkdmFsaWRlKSB7Ci8vIGFycmV0IGR1IHNjcmlwdCBwYXIgc8OpY3VyaXTDqSBzaSByZXF1w6p0ZSBub24gdmFsaWRlCmV4aXQ7Cn0KLyo9PT09PT09PT0gQ3LDqWF0aW9ucyBkZSBmaWNoaWVycyBzaSBpbmV4aXN0YW50cyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PSovCiRub21maWNoaWVyX3ZlcnJvdT0gJ3ZlcnJvdV8nLiRzdWpldF9yLicudHh0JzsKJG5vbWZpY2hpZXJfbWVzc2FnPSAnbWVzc2FnZXNfJy4kc3VqZXRfci4nLnR4dCc7CmlmICghZmlsZV9leGlzdHMoJG5vbWZpY2hpZXJfdmVycm91KSkgdG91Y2goJG5vbWZpY2hpZXJfdmVycm91KTsKaWYgKCFmaWxlX2V4aXN0cygkbm9tZmljaGllcl9tZXNzYWcpKXsKJHBmMD1mb3Blbigkbm9tZmljaGllcl9tZXNzYWcsJ3cnKTsKZndyaXRlKCRwZjAsJGVudGV0ZWRlZik7CmZjbG9zZSgkcGYwKTsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLwovLwovKj09PT09PT09PSBNb2RlIMOpY3JpdHVyZSAoJGFjdGlvbj0gJ2Vjcml0dXJlJykgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ki8KaWYgKCRhY3Rpb249PSdlY3JpdHVyZScpewokbm91dmVhdT0gdHJ1ZTsgLy8gb24gc3VwcG9zZSB1biBub3V2ZWF1IG1lc3NhZ2UKLy8KLy89PT0gdmFyaWFibGVzIHBhc3PDqWVzIHBhciBtw6l0aG9kZSBQT1NUIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0vCighZW1wdHkoJF9QT1NUWydub20nXSkpPyAkbm9tPSAkX1BPU1RbJ25vbSddOiAkbm9tPSAnaW5jb25udSc7CighZW1wdHkoJF9QT1NUWydtZXNzYWdlJ10pKT8gJGNvbW1lbnRhaXJlPSAkX1BPU1RbJ21lc3NhZ2UnXTogJGNvbW1lbnRhaXJlPSAnJzsKLy8tLS0gdHJhaXRlbWVudHMgZGVzIGluZm9ybWF0aW9ucyBQT1NUIGVudHJhbnRlcwokbm9tPSBzdHJpcF90YWdzKCRub20pOwokbm9tPSBzdHJfcmVwbGFjZSgkQ2FyX25yLCcnLCRub20pOwokbm9tPSBodG1sZW50aXRpZXMoc3Vic3RyKCRub20sMCwyMCkpOwokY29tbWVudGFpcmU9IHN0cmlwX3RhZ3MoJGNvbW1lbnRhaXJlLCR0YWdzcGVybWlzKTsKJGNvbW1lbnRhaXJlPSBwcmVnX3JlcGxhY2UoJENsZWZzLCdub25lJywkY29tbWVudGFpcmUpOwokY29tbWVudGFpcmU9IHN0cl9yZXBsYWNlKCRDYXJzcGUsJENhcmNoZ3MsJGNvbW1lbnRhaXJlKTsKJGNvbW1lbnRhaXJlPSBzdHJfcmVwbGFjZSgkQ2FyX25yLCc8YnI+JywkY29tbWVudGFpcmUpOwokY29tbWVudGFpcmU9IHByZWdfcmVwbGFjZSgnL1xcXC8nLCcnLCRjb21tZW50YWlyZSk7IC8vIHBsdXMgZCdhbnRpLXNsYXNoCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS8KLy89PT0gYWNjw6hzIGF1IGZpY2hpZXIgZGVzIG1lc3NhZ2VzIGVuIGxlY3R1cmUvw6ljcml0dXJlIC0tLS0tLS0tLS0tLS0tLS0tLS0vCi8vLS0tIG1pc2UgZW4gcGxhY2UgZHUgdmVycm91IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KJGRlYj0gdGltZSgpOyAkdGVtcG89IDI7ICRlcnJldXI9ICcnOwpkb3sKJHZlcnJvdT0gZmlsZSgkbm9tZmljaGllcl92ZXJyb3UpOwppZiAoY291bnQoJHZlcnJvdSk9PTApIGJyZWFrOwp9d2hpbGUoKHRpbWUoKS0kZGViKTw9JHRlbXBvKTsKaWYgKGNvdW50KCR2ZXJyb3UpIT0wKXsgLy8gKGxlIHZlcnJvdSBlc3QgcmVzdMOpIGJsb3F1w6kpCiRlcnJldXIuPSAnLS0gYmxvY2FnZS12ZXJyb3UgLS0nOwppZiAoKHRpbWUoKS10cmltKCR2ZXJyb3VbMF0pKT49MTApewokZXJyZXVyLj0gJyAtLSBkZWJsb2NhZ2UtZm9yY2UgLS0nOwokcGZ2PWZvcGVuKCRub21maWNoaWVyX3ZlcnJvdSwndycpOwpmd3JpdGUoJHBmdiwnJyk7CmZjbG9zZSgkcGZ2KTsKfQp9CmVsc2V7IC8vIChzaSBwYXMgZCdlcnJldXIgZmVybWV0dXJlIGR1IHZlcnJvdSkKJHBmdj1mb3Blbigkbm9tZmljaGllcl92ZXJyb3UsJ3cnKTsKZndyaXRlKCRwZnYsdGltZSgpKTsKZmNsb3NlKCRwZnYpOwp9CmlmICgkZXJyZXVyIT0nJykgZGllKCdFUlJFVVI6ICcuJGVycmV1cik7Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8tLS0gbGVjdHVyZSBkdSBmaWNoaWVyIGRlIG1lc3NhZ2VzIGxpZ25lIHBhciBsaWduZQokcGYxPSBmb3Blbigkbm9tZmljaGllcl9tZXNzYWcsJ3InKTsKJG49LTE7CndoaWxlICghZmVvZigkcGYxKSkgJGxpZ25lWysrJG5dPWZnZXRzKCRwZjEsMTAyNCk7CmZjbG9zZSgkcGYxKTsKJG5sZ249ICRuOwovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0vCi8vPT09IGFuYWx5c2UgZHUgY29udGVudSBldCB0cmFpdGVtZW50IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS8KJGVudGV0ZT0kbGlnbmVbMF07IC8vIGxhIHByZW1pw6hyZSBsaWduZSBlc3QgdW5lIGVudMOqdGUKJGltZXNub3U9IDA7IC8vIGluZGljZSBub3V2ZWF1IG1lc3NhZ2UgPSAwCmlmICgkbm91dmVhdSl7CiRNZXNzYWdlWycqJ11bMF09ICRqZXRvbjsKJE1lc3NhZ2VbJ3MnXVswXT0gJHN1amV0OwokTWVzc2FnZVsndiddWzBdPSAkdmFsaWRtZXNkZWY7CiRNZXNzYWdlWydpJ11bMF09ICRpcGM7CiRNZXNzYWdlWydkJ11bMF09ICRqb3VyOwokTWVzc2FnZVsnaCddWzBdPSAkaGV1cmU7CiRNZXNzYWdlWyduJ11bMF09ICRub207CiRNZXNzYWdlWydjJ11bMF09ICRjb21tZW50YWlyZTsKJE1lc3NhZ2VbJ3InXVswXT0gJ1JGVSc7Cn0KLy8tLS0gdHJhaXRlbWVudCBsaWduZSBwYXIgbGlnbmUKJGltZXM9IDE7CiRqZXRvbl90c3Q9IGZhbHNlOyAkaXBjX3RzdD0gZmFsc2U7ICRoZXVyZV90c3Q9IGZhbHNlOwpmb3IgKCRpbGduPTE7ICRpbGduPD0kbmxnbjsgJGlsZ24rKyl7CiRjbGVmPSBzdWJzdHIoJGxpZ25lWyRpbGduXSwwLDMpOwokY29udGVudT0gc3RyX3JlcGxhY2UoJENhcl9uciwnJyxzdWJzdHIoJGxpZ25lWyRpbGduXSwzKSk7CnN3aXRjaCgkY2xlZil7CmNhc2UgJ1xcKlxcJzogLy8gamV0b24KJE1lc3NhZ2VbJyonXVskaW1lc109ICRjb250ZW51OwooJGpldG9uPT0kY29udGVudSk/ICRqZXRvbl90c3Q9IHRydWU6ICRqZXRvbl90c3Q9IGZhbHNlOyBicmVhazsKY2FzZSAnXFxzXFwnOgokTWVzc2FnZVsncyddWyRpbWVzXT0gJGNvbnRlbnU7CmNhc2UgJ1xcdlxcJzoKJE1lc3NhZ2VbJ3YnXVskaW1lc109ICRjb250ZW51OwpjYXNlICdcXGlcXCc6CiRNZXNzYWdlWydpJ11bJGltZXNdPSAkY29udGVudTsKKCRpcGM9PSRjb250ZW51KT8gJGlwY190c3Q9IHRydWU6ICRpcGNfdHN0PSBmYWxzZTsgYnJlYWs7CmNhc2UgJ1xcZFxcJzoKJE1lc3NhZ2VbJ2QnXVskaW1lc109ICRjb250ZW51OwooJGpvdXI9PSRjb250ZW51KT8gJGRfdHN0PSB0cnVlOiAkZF90c3Q9IGZhbHNlOyBicmVhazsKY2FzZSAnXFxoXFwnOgokTWVzc2FnZVsnaCddWyRpbWVzXT0gJGNvbnRlbnU7CiRtaW5kaWY9IHN1YnN0cigkaGV1cmUsMyw0KSAtIHN1YnN0cigkY29udGVudSwzLDQpOwooJG1pbmRpZjw9NSk/ICRoZXVyZV90c3Q9IHRydWU6ICRoZXVyZV90c3Q9IGZhbHNlOwokaGV1ZGlmPSBzdWJzdHIoJGhldXJlLDAsMikgLSBzdWJzdHIoJGNvbnRlbnUsMCwyKTsKaWYgKCRoZXVkaWYhPTApICRoZXVyZV90c3Q9IGZhbHNlOwpicmVhazsKY2FzZSAnXFxuXFwnOgokTWVzc2FnZVsnbiddWyRpbWVzXT0gJGNvbnRlbnU7IGJyZWFrOwpjYXNlICdcXGNcXCc6CiRNZXNzYWdlWydjJ11bJGltZXNdPSAkY29udGVudTsgYnJlYWs7CmNhc2UgJ1xcclxcJzoKJE1lc3NhZ2VbJ3InXVskaW1lc109ICRjb250ZW51OyBicmVhazsKY2FzZSAnXFwtXFwnOgovLyBmaW4gZGUgbWVzc2FnZQppZiAoJG5vdXZlYXUgQU5EICRqZXRvbl90c3QgQU5EICRpcGNfdHN0IEFORCAkaGV1cmVfdHN0KXsKLy8gbGUgbcOqbWUgcXVlIGxlIG5vdXZlYXUKJGltZXNub3U9ICRpbWVzOyAvLyBpbmRpY2Ugbm91dmVhdSBtZXNzYWdlCiRNZXNzYWdlWydoJ11bJGltZXNdPSAkaGV1cmU7CiRNZXNzYWdlWyduJ11bJGltZXNdPSAkbm9tOwokTWVzc2FnZVsnYyddWyRpbWVzXT0gJGNvbW1lbnRhaXJlOwp9CiRpbWVzKys7IC8vIGF1IHN1aXZhbnQKJGpldG9uX3RzdD0gZmFsc2U7ICRpcGNfdHN0PSBmYWxzZTsgJGhldXJlX3RzdD0gZmFsc2U7CmJyZWFrOwp9Cn0KJG5tZXM9ICRpbWVzLTE7Ci8vLS0tIHLDqWR1Y3Rpb24gZGVzIG1lc3NhZ2VzIHNpIGxlIGNoYW1wICRjb21tZW50YWlyZSBlc3QgdmlkZQppZiAoJGNvbW1lbnRhaXJlPT0nJyl7CiRNZXNzYWdlWyd2J11bJGltZXNub3VdPSAtMTsKJG5vdXZlYXU9IDA7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLwovLz09PSByZWVjcml0dXJlIGR1IGZpY2hpZXIgZGUgbWVzc2FnZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0vCiRwZjI9Zm9wZW4oJG5vbWZpY2hpZXJfbWVzc2FnLCd3Jyk7CmZ3cml0ZSgkcGYyLCRlbnRldGUpOwooJG5vdXZlYXUgQU5EICgkaW1lc25vdT09MCkpPyAkaW1lc2RlYj0wOiAkaW1lc2RlYj0xOwpmb3IgKCRpbWVzPSRpbWVzZGViOyAkaW1lczw9JG5tZXM7ICRpbWVzKyspewppZiAoJE1lc3NhZ2VbJ3YnXVskaW1lc109PSAtMSkgY29udGludWU7IC8vICctMSc+IGxlIG1lc3NhZ2UgZXN0IGVmZmFjw6kKZndyaXRlKCRwZjIsJ1xcKlxcJy4kTWVzc2FnZVsnKiddWyRpbWVzXS4iXG4iKTsKZndyaXRlKCRwZjIsJ1xcc1xcJy4kTWVzc2FnZVsncyddWyRpbWVzXS4iXG4iKTsKZndyaXRlKCRwZjIsJ1xcdlxcJy4kTWVzc2FnZVsndiddWyRpbWVzXS4iXG4iKTsKZndyaXRlKCRwZjIsJ1xcaVxcJy4kTWVzc2FnZVsnaSddWyRpbWVzXS4iXG4iKTsKZndyaXRlKCRwZjIsJ1xcZFxcJy4kTWVzc2FnZVsnZCddWyRpbWVzXS4iXG4iKTsKZndyaXRlKCRwZjIsJ1xcaFxcJy4kTWVzc2FnZVsnaCddWyRpbWVzXS4iXG4iKTsKZndyaXRlKCRwZjIsJ1xcblxcJy4kTWVzc2FnZVsnbiddWyRpbWVzXS4iXG4iKTsKZndyaXRlKCRwZjIsJ1xcY1xcJy4kTWVzc2FnZVsnYyddWyRpbWVzXS4iXG4iKTsKZndyaXRlKCRwZjIsJ1xcclxcJy4kTWVzc2FnZVsnciddWyRpbWVzXS4iXG4iKTsKZndyaXRlKCRwZjIsJ1xcLVxcLS0tLS0tLS0tLScuIlxuIik7Cn0KZmNsb3NlKCRwZjIpOwovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0vCi8vPT09IGxpYsOpcmF0aW9uIGR1IHZlcnJvdSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0vCiRwZnY9Zm9wZW4oJG5vbWZpY2hpZXJfdmVycm91LCd3Jyk7CmZ3cml0ZSgkcGZ2LCcnKTsKZmNsb3NlKCRwZnYpOwovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0vCn0vLyAkYWN0aW9uPT0gJ2Vjcml0dXJlJwovLwovKj09PT09PT09PSBNb2RlIGxlY3R1cmUgKCRhY3Rpb249ICdsZWN0dXJlJykgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0qLwppZiAoJGFjdGlvbj09J2xlY3R1cmUnKXsKJG5vdXZlYXU9IGZhbHNlOyAvLyBwYXMgZGUgbm91dmVhdSBtZXNzYWdlCi8vLS0tIGxlY3R1cmUgZHUgZmljaGllciBkZSBtZXNzYWdlcyBsaWduZXMgcGFyIGxpZ25lcwokcGYxPSBmb3Blbigkbm9tZmljaGllcl9tZXNzYWcsJ3InKTsKJG49LTE7CndoaWxlICghZmVvZigkcGYxKSkgJGxpZ25lWysrJG5dPWZnZXRzKCRwZjEsMTAyNCk7CmZjbG9zZSgkcGYxKTsKJG5sZ249ICRuOwovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0vCi8vPT09IGFuYWx5c2UgZHUgY29udGVudSBldCB0cmFpdGVtZW50IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS8KJGVudGV0ZT0kbGlnbmVbMF07IC8vIGxhIHByZW1pw6hyZSBsaWduZSBlc3QgdW5lIGVudMOqdGUKLy8tLS0gdHJhaXRlbWVudCBsaWduZSBwYXIgbGlnbmUKJGltZXM9IDE7CmZvciAoJGlsZ249MTsgJGlsZ248PSRubGduOyAkaWxnbisrKXsKJGNsZWY9IHN1YnN0cigkbGlnbmVbJGlsZ25dLDAsMyk7CiRjb250ZW51PSBzdWJzdHIoJGxpZ25lWyRpbGduXSwzKTsKJGNvbnRlbnU9IHN0cl9yZXBsYWNlKCRDYXJfbnIsJycsJGNvbnRlbnUpOwpzd2l0Y2goJGNsZWYpewpjYXNlICdcXHZcXCc6CiRNZXNzYWdlWyd2J11bJGltZXNdPSAkY29udGVudTsgYnJlYWs7CmNhc2UgJ1xcZFxcJzoKJE1lc3NhZ2VbJ2QnXVskaW1lc109ICRjb250ZW51OyBicmVhazsKY2FzZSAnXFxoXFwnOgokTWVzc2FnZVsnaCddWyRpbWVzXT0gJGNvbnRlbnU7IGJyZWFrOwpjYXNlICdcXG5cXCc6CiRNZXNzYWdlWyduJ11bJGltZXNdPSAkY29udGVudTsgYnJlYWs7CmNhc2UgJ1xcY1xcJzoKJE1lc3NhZ2VbJ2MnXVskaW1lc109ICRjb250ZW51OyBicmVhazsKY2FzZSAnXFwtXFwnOiAvLyBmaW4gZGUgbWVzc2FnZQokaW1lcysrOyAvLyBhdSBzdWl2YW50CmJyZWFrOwp9Cn0KJG5tZXM9ICRpbWVzLTE7Cn0vLyAkYWN0aW9uPT0gJ2xlY3R1cmUnCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0vLwoKLyo9PT09PT09PT0gQWZmaWNoYWdlID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ki8KaWYgKCRub3V2ZWF1KXsKJGltZXM9ICRpbWVzbm91OwplY2hvKCc8aHI+PGZpZWxkc2V0PicpOwplY2hvKCc8bGVnZW5kPlZvdHJlIG5vdXZlYXUgbWVzc2FnZSBlc3QgZW5yZWdpc3Ryw6kgOiA8aT4oIHZvdXMgcG91dmV6IGVuY29yZSBsZSBtb2RpZmllciApPC9pPjwvbGVnZW5kPicpOwplY2hvKCcgTm9tOiAnLiRNZXNzYWdlWyduJ11bJGltZXNdLic8YnI+Jyk7CmVjaG8oJE1lc3NhZ2VbJ2MnXVskaW1lc10pOwplY2hvKCc8L2ZpZWxkc2V0PicpOwp9Ci8vCmVjaG8oJzxocj4nKTsKZm9yICgkaW1lcz0xOyAkaW1lczw9JG5tZXM7ICRpbWVzKyspewppZiAoJE1lc3NhZ2VbJ3YnXVskaW1lc109PSAwKSBjb250aW51ZTsgLy8gJzAnPiBsZSBtZXNzYWdlIG4nZXN0IHBhcyBhZmZpY2jDqQppZiAoJGltZXMgIT0gJGltZXNub3UpewplY2hvKCc8Yj5Ob20gOjwvYj4gJy4kTWVzc2FnZVsnbiddWyRpbWVzXS4nICAnKTsKZWNobygnPGI+RGF0ZSA6PC9iPiAnLiRNZXNzYWdlWydkJ11bJGltZXNdLicgJy4kTWVzc2FnZVsnaCddWyRpbWVzXS4nPGJyPicpOwplY2hvKCRNZXNzYWdlWydjJ11bJGltZXNdLic8YnI+Jyk7CmVjaG8oJzxocj4nLiJcbiIpOwp9Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS8KPz4=