#include <stdio.h>
#include<stdlib.h>
#include<string.h>
#include <windows.h>
typedef struct {
char Nom[20] ;
char Prenom [20];
int Note ;
}Etudiant;
typedef struct cellule {
Etudiant Etu ;
struct cellule * Next ;
}Cellule;
Etudiant Saisir()
{ Etudiant E;
printf("\n SAISI D'UN ETUDIANT : \n"); return E ;
}
void Afficher(Etudiant E)
{
printf(" Etudiant : %s %s %d \n",E.
Nom,E.
Prenom, E.
Note); }
void Add()
{ FILE * Fiche ;
char Nomf[20];
int cpt;
int Nbre; // Nbre d'etudiants a ajouter
Etudiant E ;
puts(" Nom de fichier à utiliser pour ajout ?"); puts(" Nbre d'etudiants a ajouter ?"); // Ouverture du fichier en ajout s'il existe sinon creation
Fiche
= fopen(Nomf
, "a+"); for(cpt=0 ; cpt<Nbre ;cpt++)
{
printf(" SAISI DE L'ELEVE %d : \n",cpt
+1); E = Saisir();
fwrite(&E
, sizeof(Etudiant
), 1 , Fiche
); }
}
void Load()
{ FILE * Fiche ;
char Nomf[20];
Etudiant E ;
puts(" Nom de fichier à Lire ?"); //Ouverture du fichier en lecture
Fiche
= fopen(Nomf
, "r"); if(Fiche==NULL)
{ puts(" Ce fichier n'existe pas !!!") ; return ;
}
while ( fread(&E
,sizeof(Etudiant
),1,Fiche
) !=0 ) {Afficher(E);
}
}
void SearchFirst()
{ FILE * Fiche ;
char Nomf[20];
char NomE[20];
int Found=0 ;
Etudiant E ;
puts(" Nom de fichier à Lire ?"); //Ouverture du fichier en lecture
Fiche
= fopen(Nomf
, "r"); if(Fiche==NULL)
{ puts(" Ce fichier n'existe pas !!!") ; return ;
}
puts(" Nom à rechercher ?"); while ( fread(&E
,sizeof(Etudiant
),1,Fiche
)!=0 && Found
==0) {
{
printf (" \n LA FICHE EST : \n"); Afficher(E);
Found=1;
}
}
if(Found==0)
printf("CET ETUDIANT N'EXISTE PAS !!!\n"); }
void Update()
{ FILE * Fiche ;
char Nomf[20];
char NomE[20]; // Nom de l'étudiant à rechercher
Etudiant E ;
puts(" Nom de fichier dans lequel on effectue la recherche ?"); puts(" Nom de l'étudiant à rechercher ?"); //Ouverture du fichier en lecture et autre
Fiche
= fopen(Nomf
, "r+"); if(Fiche==NULL)
{ puts(" Ce fichier n'existe pas !!!") ; return ;
}
while ( fread(&E
,sizeof(Etudiant
),1,Fiche
)!=0) { // Je recule de sizeof(Etudiant) octets
fseek(Fiche
, -sizeof(Etudiant
), SEEK_CUR
); puts(" Nouveau prenom "); printf(" La nouvelle note ?"); fwrite(&E
,sizeof(Etudiant
),1,Fiche
); return ;
}
}
printf("L'étudiant recherché n'existe pas !!!\n");
}
Etudiant* Upload(int * Nbre)
{ FILE * Fiche ;
char Nomf[20];
Etudiant * Liste ,E ;
int Nb=0 ;
puts(" Nom de fichier à charger ?"); // Ouverture du fichier en Lecture/Ecriture
Fiche
= fopen(Nomf
, "r+"); if(Fiche==NULL)
{ puts(" Ce fichier n'existe pas !!!") ; return NULL;
}
// On doit parcourir le fichier pour compter le nbre d'étudiants
while( fread(&E
,sizeof(Etudiant
),1, Fiche
) ) Nb++;
(*Nbre)=Nb ; // Mise a jour de la taille
// Allocation de l'espace nécessaire pour Nb étudiants
Liste
= (Etudiant
*) malloc(Nb
*sizeof(Etudiant
)); // Se repositionner au début
//je charge les Nb étudiants ds Liste
fread(Liste
, sizeof(Etudiant
), Nb
, Fiche
); // Mise à jour de nbre d'étudiants
return Liste ;
}
void Affichetable(Etudiant* Tab , int taille)
{
int i ;
puts(" LISTE DES ETUDIANTS "); for(i=0 ; i < taille ;i++)
{
Afficher(Tab[i]);
puts("===================================="); }
}
Cellule * Create(Etudiant E)
{
Cellule * Nouveau ;
Nouveau
= (Cellule
*) malloc(sizeof(Cellule
)); Nouveau->Etu = E ;
Nouveau->Next = NULL ;
return Nouveau ;
}
Cellule * AjoutDebut(Cellule *L,Etudiant E)
{ Cellule*p;
if(!L)
return Create(E);
p=Create(E);
p->Next=L;
return p;
}
Cellule * AjoutFin(Cellule *L , Etudiant E)
{ Cellule *p ;
if(!L)
return Create(E);
for(p=L ; p->Next!=NULL ; p=p->Next);
p->Next = Create(E);
return L ;
}
Cellule *DeleteFirst(Cellule *L)
{
if(!L)
return L->Next;
return NULL;
}
Cellule* UploadToList()
{ FILE * Fiche ;
char Nomf[20];
Cellule * Liste=NULL ;
Etudiant E ;
puts(" Nom de fichier à charger ?"); // Ouverture du fichier en Lecture
Fiche
= fopen(Nomf
, "r"); if(Fiche==NULL)
{ puts(" Ce fichier n'existe pas !!!") ; return NULL;
}
while( fread(&E
,sizeof(Etudiant
),1, Fiche
) ) {
Liste = AjoutFin(Liste, E);
}
return Liste ;
}
void AfficherListe(Cellule * L)
{
Cellule * p ;
if(!L)
{
puts(" LA LISTE EST VIDE "); return ;
}
puts(" LA LISTE CHAINEE DES ETUDIANTS EST "); for(p=L ; p; p=p->Next)
{
Afficher(p->Etu);
puts("======================================"); }
}
void StockerListe(Cellule * L)
{ FILE * Fiche ;
char Nomf[20];
Cellule * p ;
puts(" Nom de fichier à charger ?"); // Ouverture du fichier en ecriture
Fiche
= fopen(Nomf
, "w"); for(p=L ; p ; p=p->Next)
{
fwrite(&(p
->Etu
),sizeof(Etudiant
),1,Fiche
); }
}
void Delete()
{ Cellule* L=NULL, *p=NULL,*q=NULL ;
L= UploadToList();
char name[20];
puts(" Nom a supprimer"); if(L)
{
L= L->Next;
else // si name ne se trouve pas au debut
for(q
=L
, p
=L
->Next
; p
&& strcmp(p
->Etu.
Nom,name
)!=0 ; q
=p
, p
=p
->Next
); if(p!=NULL) // strcmp(p->Etu.Nom,name)==0
q->Next = p->Next;
else
puts(" Ce nom n'est pas dans la liste"); }
StockerListe(L);
}
Cellule * InsererCroissant( Cellule * L)
{ // On insere E dans la liste L triee croissante elle peut etre vide
Etudiant E ;
Cellule* Nouveau,*p,*q ;
E=Saisir();
Nouveau=Create(E);
if(!L)
return Nouveau;
if(strcmp(Nouveau
->Etu.
Nom,L
->Etu.
Nom)<=0) { Nouveau->Next = L;
return Nouveau;
}
// Ajoiut s'effectuera au dela de debut
for(q
=L
, p
=L
->Next
; p
&& strcmp(Nouveau
->Etu.
Nom,p
->Etu.
Nom)>0 ;q
=p
, p
=p
->Next
); // Point virgule /* for(q=L, p=L->Next ; p ;q=p , p=p->Next)
{
if (strcmp(Nouveau->Etu.Nom,p->Etu.Nom)<=0 ) break ;
}*/
q->Next = Nouveau;
Nouveau->Next = p ;
return L ;
}
Cellule * InsertCroissant( Cellule * L, Etudiant E)
{ // On insere E dans la liste L triee croissante elle peut etre vide
Cellule * Nouveau,*p,*q ;
Nouveau=Create(E);
if(!L)
return Nouveau;
if(strcmp(Nouveau
->Etu.
Nom,L
->Etu.
Nom)<=0) { Nouveau->Next = L;
return Nouveau;
}
// Ajouut s'effectuera au dela de debut
for(q
=L
, p
=L
->Next
; p
&& strcmp(Nouveau
->Etu.
Nom,p
->Etu.
Nom)>0 ;q
=p
, p
=p
->Next
); // Point virgule /* for(q=L, p=L->Next ; p ;q=p , p=p->Next)
{
if (strcmp(Nouveau->Etu.Nom,p->Etu.Nom)<=0 ) break ;
}*/
q->Next = Nouveau;
Nouveau->Next = p ;
return L ;
}
Cellule * InsertDecroissant(Cellule * L, Etudiant E)
{
Cellule * Nouveau,*p,*q ;
Nouveau=Create(E);
if(!L)
return Nouveau;
if(strcmp(Nouveau
->Etu.
Nom,L
->Etu.
Nom)>=0) {
Nouveau->Next=L;
return Nouveau;
}
for(q
=L
, p
=L
->Next
; p
&& strcmp(Nouveau
->Etu.
Nom,p
->Etu.
Nom)<0 ;q
=p
, p
=p
->Next
); q->Next = Nouveau;
Nouveau->Next = p ;
return L ;
}
Cellule* TriCroissant(Cellule * L)
{
Cellule *LT=NULL , *p=NULL;
for(p=L;p;p=p->Next)
{
LT=InsertCroissant(LT,p->Etu);
}
return LT;
}
Cellule * TriDecroissant(Cellule *L)
{
Cellule *LT=NULL , *p=NULL;
for(p=L;p;p=p->Next)
{
LT=InsertDecroissant(LT,p->Etu);
}
return LT;
}
Cellule *Renverser(Cellule * L)
{
Cellule *p, *q, *LI=NULL;
p=L;
while(p!=NULL) // a least there is a next
{
q=p->Next;
p->Next=LI;
LI=p;
p=q;
}
return LI;
}
int Taille(Cellule * L)
{
Cellule *p;
int i=0;
for(p=L,i=0;p;i++,p=p->Next);
return i;
}
Cellule * Position( Cellule *L, int pos)
{
int taille=Taille(L),i;
Cellule *p;
if(pos>taille)
return NULL;// Erreur
for(i=1 , p=L; i<pos ;i++ , p=p->Next);
return p;
}
Cellule* Creer() // Elle creee un seul etudiant
{
Cellule * Nouveau;
Nouveau
= (Cellule
*)malloc(sizeof(Cellule
)); Nouveau->Etu= Saisir();
Nouveau->Next=NULL;
return Nouveau;
}
// Cette fonction sert a inserer un etudiant dans une position precise si elle existe
Cellule * InsererPosition(Cellule *L,int pos)
{ int i ;
Cellule *p, *q, *Nouveau;
int taille=Taille(L); // la taille de la liste
if(pos<0 || pos>taille)
{
printf("la position %d n'existe pas \n",pos
); return L;
}
Nouveau=Creer(); // insertion
if(pos==1)
{
Nouveau->Next=L; // premiere cellule reservée pour le nouveau etudiant et le reste pour le reste de la liste
return Nouveau;
}
for(i=1,p=L;i<pos;i++,p=q,p=p->Next);
q->Next= Nouveau ;
Nouveau->Next=p;
return L ;
}
Cellule * ajouterAvantNom(Cellule * L,char tab[20])
{
Cellule *p, *q, *Nouveau;
Etudiant E;
Nouveau=Create(Saisir(E));
if (strcmp(L
->Etu.
Nom,tab
)==0) { Nouveau->Next=L;
return Nouveau;
}
for(p
=L
,q
=L
->Next
;q
&&strcmp(q
->Etu.
Nom,tab
)!=0;p
=q
,q
=q
->Next
); p->Next=Nouveau;
Nouveau->Next=q;
return L;
}
Cellule * ajouterApresNom(Cellule * L,char tab[20])
{
Cellule *p=NULL, *q=NULL, *Nouveau=NULL;
Etudiant E;
for(p
=L
,q
=p
->Next
;q
&&strcmp(p
->Etu.
Nom,tab
)!=0;p
=q
,q
=q
->Next
); Nouveau=Create(Saisir(E));
p->Next=Nouveau;
Nouveau->Next=q;
return L;
}
int Menu()
{ int choix ;
printf("\n 1----> Ajout Debut \n"); printf(" 2 ----> Ajout Fin: \n"); printf(" 3 ----> Ajout Avant un nom \n"); printf(" 4 ----> Ajout Après un nom \n"); printf(" 5 ----> DeleteFirst \n"); printf(" 6 ----> DeleteAll \n"); printf(" 7 ----> Afficher Liste \n"); printf(" 8 ----> Le nom d'une position \n"); printf(" 9 ----> Ajout d'un nom dans une position \n"); printf(" 10 ----> Inserer Croissant \n"); printf(" 11 ----> Tri Croissant \n"); printf(" 12 ----> Tri DeCroissant \n"); printf(" 13 ----> Renverser \n"); printf(" 14 ----> Le nom d'une position \n"); return choix ;
}
int main()
{ Cellule *GINF1=NULL, *Res;
int b;
Etudiant E;
char nom[20];
int choix, pos;
do
{
choix=Menu();
switch (choix) {
case 1:
E=Saisir();
GINF1=AjoutDebut(GINF1,E);
break;
case 2:
E=Saisir();
GINF1=AjoutFin(GINF1,E);
break;
case 3:
printf("le nom Avant lequel on va ajouter\n"); GINF1=ajouterAvantNom(GINF1,nom);
break;
case 4:
printf("le nom apres lequel on va ajouter\n"); GINF1=ajouterApresNom(GINF1,nom);
break;
case 5:
GINF1=DeleteFirst(GINF1);
break;
case 6:
GINF1=NULL;
break;
case 7:
AfficherListe(GINF1);
break;
case 8:
Res= Position(GINF1,pos);
if(Res!=NULL)
{
Afficher(Res->Etu);
}else
{
puts("ceci n'existe pas"); }
break;
case 9:
printf("La position s'il vois plait \n"); Res=Position(GINF1,pos);
if(Res!=NULL)
{
InsererPosition(Res,pos);
}else
{
puts("ceci n'existe pas"); }
break;
case 10:
GINF1=InsererCroissant(GINF1);
break;
case 11:
GINF1=TriCroissant(GINF1);
break;
case 12:
GINF1=TriDecroissant(GINF1);
break;
case 13:
GINF1=Renverser(GINF1);
break;
default :
printf("ce chois n est pas valide\n"); break;
}
printf("voulez vous continuer ??\n1.oui 2.non\n Choix : "); }while(b!=2);
return 0 ;
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlPHN0ZGxpYi5oPgojaW5jbHVkZTxzdHJpbmcuaD4KI2luY2x1ZGUgPHdpbmRvd3MuaD4KdHlwZWRlZiBzdHJ1Y3QgewogICAgY2hhciBOb21bMjBdIDsKICAgIGNoYXIgUHJlbm9tIFsyMF07CiAgICBpbnQgTm90ZSA7Cn1FdHVkaWFudDsKdHlwZWRlZiBzdHJ1Y3QgY2VsbHVsZSB7CiAgICBFdHVkaWFudCBFdHUgOwogICAgc3RydWN0IGNlbGx1bGUgKiBOZXh0IDsKfUNlbGx1bGU7CkV0dWRpYW50IFNhaXNpcigpCnsgIEV0dWRpYW50IEU7CiAgICBwcmludGYoIlxuIFNBSVNJIEQnVU4gRVRVRElBTlQgOiBcbiIpOwogICAgcHJpbnRmKCIgTm9tIDogIik7CiAgICBzY2FuZigiJXMiLEUuTm9tKTsKICAgIHByaW50ZigiIFByw6lub20gOiAiKTsKICAgIHNjYW5mKCIlcyIsRS5QcmVub20pOwogICAgcHJpbnRmKCIgTm90ZSA6ICIpOwogICAgc2NhbmYoIiVkIiwmKEUuTm90ZSkpOwogICAgcmV0dXJuIEUgOwp9CnZvaWQgQWZmaWNoZXIoRXR1ZGlhbnQgRSkKewogICAgcHJpbnRmKCIgRXR1ZGlhbnQgOiAlcyAgICVzICAgJWQgXG4iLEUuTm9tLEUuUHJlbm9tLCBFLk5vdGUpOwp9CnZvaWQgQWRkKCkKeyAgRklMRSAqIEZpY2hlIDsKICAgIGNoYXIgTm9tZlsyMF07CiAgICBpbnQgY3B0OwogICAgaW50IE5icmU7IC8vIE5icmUgZCdldHVkaWFudHMgYSBham91dGVyCiAgICBFdHVkaWFudCBFIDsKICAgIHB1dHMoIiBOb20gZGUgZmljaGllciDDoCB1dGlsaXNlciBwb3VyIGFqb3V0ID8iKTsKICAgIHNjYW5mKCIlcyIsTm9tZik7CiAgICBwdXRzKCIgTmJyZSBkJ2V0dWRpYW50cyBhIGFqb3V0ZXIgPyIpOwogICAgc2NhbmYoIiVkIiwmTmJyZSk7CiAgICAvLyBPdXZlcnR1cmUgZHUgZmljaGllciBlbiBham91dCBzJ2lsIGV4aXN0ZSBzaW5vbiBjcmVhdGlvbgogICAgRmljaGUgPSBmb3BlbihOb21mICwgImErIik7CiAgICBmb3IoY3B0PTAgOyBjcHQ8TmJyZSA7Y3B0KyspCiAgICB7CiAgICAgICAgcHJpbnRmKCIgU0FJU0kgREUgTCdFTEVWRSAlZCA6IFxuIixjcHQrMSk7CiAgICAgICAgRSA9IFNhaXNpcigpOwogICAgICAgIGZ3cml0ZSgmRSAsIHNpemVvZihFdHVkaWFudCksIDEgLCBGaWNoZSk7CiAgICB9CiAgICBmY2xvc2UoRmljaGUpOwp9CnZvaWQgTG9hZCgpCnsgICBGSUxFICogRmljaGUgOwogICAgY2hhciBOb21mWzIwXTsKICAgIEV0dWRpYW50IEUgOwogICAgcHV0cygiIE5vbSBkZSBmaWNoaWVyIMOgIExpcmUgPyIpOwogICAgc2NhbmYoIiVzIixOb21mKTsKICAgIC8vT3V2ZXJ0dXJlIGR1IGZpY2hpZXIgZW4gbGVjdHVyZQogICAgRmljaGUgPSBmb3BlbihOb21mICwgInIiKTsKICAgIGlmKEZpY2hlPT1OVUxMKQogICAgeyBwdXRzKCIgQ2UgZmljaGllciBuJ2V4aXN0ZSBwYXMgISEhIikgOwogICAgICAgIHJldHVybiA7CiAgICB9CiAgICB3aGlsZSAoIGZyZWFkKCZFLHNpemVvZihFdHVkaWFudCksMSxGaWNoZSkgIT0wICkKICAgIHtBZmZpY2hlcihFKTsKICAgIH0KICAgIGZjbG9zZShGaWNoZSk7Cn0Kdm9pZCBTZWFyY2hGaXJzdCgpCnsgICBGSUxFICogRmljaGUgOwogICAgY2hhciBOb21mWzIwXTsKICAgIGNoYXIgTm9tRVsyMF07CiAgICBpbnQgRm91bmQ9MCA7CiAgICBFdHVkaWFudCBFIDsKICAgIHB1dHMoIiBOb20gZGUgZmljaGllciDDoCBMaXJlID8iKTsKICAgIHNjYW5mKCIlcyIsTm9tZik7CiAgICAvL091dmVydHVyZSBkdSBmaWNoaWVyIGVuIGxlY3R1cmUKICAgIEZpY2hlID0gZm9wZW4oTm9tZiAsICJyIik7CiAgICBpZihGaWNoZT09TlVMTCkKICAgIHsgICBwdXRzKCIgQ2UgZmljaGllciBuJ2V4aXN0ZSBwYXMgISEhIikgOwogICAgICAgIHJldHVybiA7CiAgICB9CiAgICBwdXRzKCIgTm9tIMOgIHJlY2hlcmNoZXIgPyIpOwogICAgc2NhbmYoIiVzIixOb21FKTsKICAgIHdoaWxlICggZnJlYWQoJkUsc2l6ZW9mKEV0dWRpYW50KSwxLEZpY2hlKSE9MCAmJiBGb3VuZD09MCkKICAgIHsKICAgICAgICBpZihzdHJjbXAoRS5Ob20sTm9tRSk9PTApCiAgICAgICAgewogICAgICAgICAgICBwcmludGYgKCIgXG4gTEEgRklDSEUgRVNUIDogXG4iKTsKICAgICAgICAgICAgQWZmaWNoZXIoRSk7CiAgICAgICAgICAgIEZvdW5kPTE7CiAgICAgICAgfQoKICAgIH0KICAgIGlmKEZvdW5kPT0wKQogICAgICAgIHByaW50ZigiQ0VUIEVUVURJQU5UIE4nRVhJU1RFIFBBUyAhISFcbiIpOwogICAgZmNsb3NlKEZpY2hlKTsKfQp2b2lkIFVwZGF0ZSgpCnsgICBGSUxFICogRmljaGUgOwogICAgY2hhciBOb21mWzIwXTsKICAgIGNoYXIgTm9tRVsyMF07IC8vIE5vbSBkZSBsJ8OpdHVkaWFudCDDoCByZWNoZXJjaGVyCiAgICBFdHVkaWFudCBFIDsKICAgIHB1dHMoIiBOb20gZGUgZmljaGllciBkYW5zIGxlcXVlbCBvbiBlZmZlY3R1ZSBsYSByZWNoZXJjaGUgID8iKTsKICAgIHNjYW5mKCIlcyIsTm9tZik7CiAgICBwdXRzKCIgTm9tIGRlIGwnw6l0dWRpYW50IMOgIHJlY2hlcmNoZXIgPyIpOwogICAgc2NhbmYoIiVzIixOb21FKTsKICAgIC8vT3V2ZXJ0dXJlIGR1IGZpY2hpZXIgZW4gbGVjdHVyZSBldCBhdXRyZQogICAgRmljaGUgPSBmb3BlbihOb21mICwgInIrIik7CiAgICBpZihGaWNoZT09TlVMTCkKICAgIHsgICBwdXRzKCIgQ2UgZmljaGllciBuJ2V4aXN0ZSBwYXMgISEhIikgOwogICAgICAgIHJldHVybiA7CiAgICB9CiAgICB3aGlsZSAoIGZyZWFkKCZFLHNpemVvZihFdHVkaWFudCksMSxGaWNoZSkhPTApCiAgICB7ICAgICAgICBpZihzdHJjbXAoRS5Ob20sTm9tRSk9PSAwICkKICAgIHsgIC8vIEplIHJlY3VsZSBkZSBzaXplb2YoRXR1ZGlhbnQpIG9jdGV0cwogICAgICAgIGZzZWVrKEZpY2hlLCAtc2l6ZW9mKEV0dWRpYW50KSwgU0VFS19DVVIpOwogICAgICAgIHB1dHMoIiBOb3V2ZWF1IHByZW5vbSAiKTsKICAgICAgICBwcmludGYoIiBQcmVub20gOiAiKTsKICAgICAgICBzY2FuZigiJXMiLEUuUHJlbm9tKTsKICAgICAgICBwcmludGYoIiBMYSBub3V2ZWxsZSBub3RlID8iKTsKICAgICAgICBzY2FuZigiJWQiLCYoRS5Ob3RlKSk7CiAgICAgICAgZndyaXRlKCZFLHNpemVvZihFdHVkaWFudCksMSxGaWNoZSk7CiAgICAgICAgcHJpbnRmKCIgVXBkYXRlIG9rICAiKTsKICAgICAgICBmY2xvc2UoRmljaGUpOwogICAgICAgIHJldHVybiA7CiAgICB9CiAgICB9CgoKICAgIHByaW50ZigiTCfDqXR1ZGlhbnQgcmVjaGVyY2jDqSBuJ2V4aXN0ZSBwYXMgISEhXG4iKTsKICAgIGZjbG9zZShGaWNoZSk7Cgp9CiBFdHVkaWFudCogVXBsb2FkKGludCAqIE5icmUpCnsgICAgRklMRSAqIEZpY2hlIDsKICAgIGNoYXIgTm9tZlsyMF07CiAgICBFdHVkaWFudCAqIExpc3RlICxFIDsKICAgIGludCBOYj0wIDsKICAgIHB1dHMoIiBOb20gZGUgZmljaGllciDDoCBjaGFyZ2VyICAgPyIpOwogICAgc2NhbmYoIiVzIixOb21mKTsKICAgIC8vIE91dmVydHVyZSBkdSBmaWNoaWVyIGVuIExlY3R1cmUvRWNyaXR1cmUKICAgIEZpY2hlID0gZm9wZW4oTm9tZiwgInIrIik7CiAgICBpZihGaWNoZT09TlVMTCkKICAgIHsgICBwdXRzKCIgQ2UgZmljaGllciBuJ2V4aXN0ZSBwYXMgISEhIikgOwogICAgICAgIHJldHVybiBOVUxMOwogICAgfQogICAgLy8gT24gZG9pdCBwYXJjb3VyaXIgbGUgZmljaGllciBwb3VyIGNvbXB0ZXIgbGUgbmJyZSBkJ8OpdHVkaWFudHMKICAgIHdoaWxlKCBmcmVhZCgmRSxzaXplb2YoRXR1ZGlhbnQpLDEsIEZpY2hlKSApCiAgICAgICAgTmIrKzsKICAgICgqTmJyZSk9TmIgOyAvLyBNaXNlIGEgam91ciBkZSBsYSB0YWlsbGUKICAgIC8vIEFsbG9jYXRpb24gZGUgbCdlc3BhY2UgbsOpY2Vzc2FpcmUgcG91ciBOYiDDqXR1ZGlhbnRzCiAgICBMaXN0ZSA9IChFdHVkaWFudCopIG1hbGxvYyhOYipzaXplb2YoRXR1ZGlhbnQpKTsKICAgIC8vIFNlIHJlcG9zaXRpb25uZXIgYXUgZMOpYnV0CiAgICByZXdpbmQoRmljaGUpOwogICAgLy9qZSBjaGFyZ2UgbGVzIE5iIMOpdHVkaWFudHMgZHMgTGlzdGUKICAgIGZyZWFkKExpc3RlICwgc2l6ZW9mKEV0dWRpYW50KSwgTmIgLCBGaWNoZSk7CiAgICAvLyBNaXNlIMOgIGpvdXIgZGUgbmJyZSBkJ8OpdHVkaWFudHMKCiAgICBmY2xvc2UoRmljaGUpOwogICAgcmV0dXJuIExpc3RlIDsKCn0Kdm9pZCBBZmZpY2hldGFibGUoRXR1ZGlhbnQqIFRhYiAsIGludCB0YWlsbGUpCnsKICAgIGludCBpIDsKICAgIHB1dHMoIiBMSVNURSBERVMgRVRVRElBTlRTICIpOwogICAgZm9yKGk9MCA7IGkgPCB0YWlsbGUgO2krKykKICAgIHsKICAgICAgICBBZmZpY2hlcihUYWJbaV0pOwogICAgICAgIHB1dHMoIj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSIpOwogICAgfQp9CkNlbGx1bGUgKiBDcmVhdGUoRXR1ZGlhbnQgRSkKewogICAgQ2VsbHVsZSAqIE5vdXZlYXUgOwogICAgTm91dmVhdSA9IChDZWxsdWxlKikgbWFsbG9jKHNpemVvZihDZWxsdWxlKSk7CiAgICBOb3V2ZWF1LT5FdHUgPSBFIDsKICAgIE5vdXZlYXUtPk5leHQgPSBOVUxMIDsKICAgIHJldHVybiBOb3V2ZWF1IDsKfQpDZWxsdWxlICogQWpvdXREZWJ1dChDZWxsdWxlICpMLEV0dWRpYW50IEUpCnsgQ2VsbHVsZSpwOwogIGlmKCFMKQogICAgICByZXR1cm4gQ3JlYXRlKEUpOwogIHA9Q3JlYXRlKEUpOwogIHAtPk5leHQ9TDsKICByZXR1cm4gcDsKfQpDZWxsdWxlICogQWpvdXRGaW4oQ2VsbHVsZSAqTCAsIEV0dWRpYW50IEUpCnsgQ2VsbHVsZSAqcCA7CiAgICBpZighTCkKICAgICAgICByZXR1cm4gQ3JlYXRlKEUpOwogICAgZm9yKHA9TCA7IHAtPk5leHQhPU5VTEwgOyBwPXAtPk5leHQpOwogICAgcC0+TmV4dCA9IENyZWF0ZShFKTsKICAgIHJldHVybiBMIDsKfQoKQ2VsbHVsZSAqRGVsZXRlRmlyc3QoQ2VsbHVsZSAqTCkKewogIGlmKCFMKQogICByZXR1cm4gTC0+TmV4dDsKICBwcmludGYoImxpc3RlIFZJREUiKTsKICByZXR1cm4gTlVMTDsKfQpDZWxsdWxlKiBVcGxvYWRUb0xpc3QoKQp7ICAgIEZJTEUgKiBGaWNoZSA7CiAgICBjaGFyIE5vbWZbMjBdOwogICAgQ2VsbHVsZSAqIExpc3RlPU5VTEwgOwogICAgRXR1ZGlhbnQgRSA7CiAgICBwdXRzKCIgTm9tIGRlIGZpY2hpZXIgw6AgY2hhcmdlciAgID8iKTsKICAgIHNjYW5mKCIlcyIsTm9tZik7CiAgICAvLyBPdXZlcnR1cmUgZHUgZmljaGllciBlbiBMZWN0dXJlCiAgICBGaWNoZSA9IGZvcGVuKE5vbWYsICJyIik7CiAgICBpZihGaWNoZT09TlVMTCkKICAgIHsgICBwdXRzKCIgQ2UgZmljaGllciBuJ2V4aXN0ZSBwYXMgISEhIikgOwogICAgICAgIHJldHVybiBOVUxMOwogICAgfQpmc2VlawogICAgd2hpbGUoIGZyZWFkKCZFLHNpemVvZihFdHVkaWFudCksMSwgRmljaGUpICkKICAgIHsKICAgICAgICBMaXN0ZSA9IEFqb3V0RmluKExpc3RlLCBFKTsKICAgIH0KCiAgICBmY2xvc2UoRmljaGUpOwogICAgcmV0dXJuIExpc3RlIDsKCn0KCnZvaWQgQWZmaWNoZXJMaXN0ZShDZWxsdWxlICogTCkKewogICAgQ2VsbHVsZSAqIHAgOwogICAgaWYoIUwpCiAgICB7CiAgICAgICAgcHV0cygiIExBIExJU1RFIEVTVCBWSURFICIpOwogICAgICAgIHJldHVybiA7CiAgICB9CiAgICBwdXRzKCIgTEEgTElTVEUgQ0hBSU5FRSBERVMgRVRVRElBTlRTIEVTVCAiKTsKICAgIGZvcihwPUwgOyBwOyBwPXAtPk5leHQpCiAgICB7CiAgICAgICAgQWZmaWNoZXIocC0+RXR1KTsKICAgICAgICBwdXRzKCI9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSIpOwogICAgfQp9CnZvaWQgU3RvY2tlckxpc3RlKENlbGx1bGUgKiBMKQp7ICAgIEZJTEUgKiBGaWNoZSA7CiAgICAgY2hhciBOb21mWzIwXTsKICAgIENlbGx1bGUgKiBwIDsKICAgIHB1dHMoIiBOb20gZGUgZmljaGllciDDoCBjaGFyZ2VyICAgPyIpOwogICAgc2NhbmYoIiVzIixOb21mKTsKICAgIC8vIE91dmVydHVyZSBkdSBmaWNoaWVyIGVuIGVjcml0dXJlCiAgICBGaWNoZSA9IGZvcGVuKE5vbWYsICJ3Iik7CiAgICBmb3IocD1MIDsgcCA7IHA9cC0+TmV4dCkKICAgIHsKICAgICAgICBmd3JpdGUoJihwLT5FdHUpLHNpemVvZihFdHVkaWFudCksMSxGaWNoZSk7CiAgICB9CiAgICBmY2xvc2UoRmljaGUpOwp9CnZvaWQgRGVsZXRlKCkKeyAgQ2VsbHVsZSogTD1OVUxMLCAqcD1OVUxMLCpxPU5VTEwgOwogICAgTD0gVXBsb2FkVG9MaXN0KCk7CiAgICBjaGFyIG5hbWVbMjBdOwogICAgcHV0cygiIE5vbSBhIHN1cHByaW1lciIpOwogICAgc2NhbmYoIiVzIixuYW1lKTsKICAgIGlmKEwpCiAgICB7CiAgICAgICAgaWYoIXN0cmNtcChMLT5FdHUuTm9tLG5hbWUpICkKICAgICAgICAgICBMPSBMLT5OZXh0OwogICAgICAgIGVsc2UgLy8gc2kgbmFtZSBuZSBzZSB0cm91dmUgcGFzIGF1IGRlYnV0CiAgIGZvcihxPUwgLCBwPUwtPk5leHQgOyBwICYmIHN0cmNtcChwLT5FdHUuTm9tLG5hbWUpIT0wIDsgcT1wICwgcD1wLT5OZXh0KTsKICAgICBpZihwIT1OVUxMKSAvLyBzdHJjbXAocC0+RXR1Lk5vbSxuYW1lKT09MAogICAgICAgICBxLT5OZXh0ID0gcC0+TmV4dDsKICAgIGVsc2UKICAgICAgICBwdXRzKCIgQ2Ugbm9tIG4nZXN0IHBhcyBkYW5zIGxhIGxpc3RlIik7CiAgICB9CiAgICBTdG9ja2VyTGlzdGUoTCk7Cgp9CkNlbGx1bGUgKiBJbnNlcmVyQ3JvaXNzYW50KCBDZWxsdWxlICogTCkKeyAvLyBPbiBpbnNlcmUgRSBkYW5zIGxhIGxpc3RlIEwgdHJpZWUgY3JvaXNzYW50ZSBlbGxlIHBldXQgZXRyZSB2aWRlCiAgICBFdHVkaWFudCBFIDsKICAgIENlbGx1bGUqIE5vdXZlYXUsKnAsKnEgOwogICAgRT1TYWlzaXIoKTsKICAgIE5vdXZlYXU9Q3JlYXRlKEUpOwogICAgaWYoIUwpCiAgICAgICAgcmV0dXJuIE5vdXZlYXU7CgogICAgaWYoc3RyY21wKE5vdXZlYXUtPkV0dS5Ob20sTC0+RXR1Lk5vbSk8PTApCiAgICB7IE5vdXZlYXUtPk5leHQgPSBMOwogICAgICAgIHJldHVybiBOb3V2ZWF1OwogICAgfQogICAgLy8gQWpvaXV0IHMnZWZmZWN0dWVyYSBhdSBkZWxhIGRlIGRlYnV0CiBmb3IocT1MLCBwPUwtPk5leHQgOyBwICYmIHN0cmNtcChOb3V2ZWF1LT5FdHUuTm9tLHAtPkV0dS5Ob20pPjAgO3E9cCAsIHA9cC0+TmV4dCk7IC8vIFBvaW50IHZpcmd1bGUKICAgIC8qIGZvcihxPUwsIHA9TC0+TmV4dCA7IHAgO3E9cCAsIHA9cC0+TmV4dCkKICAgICB7CiAgICAgICAgIGlmIChzdHJjbXAoTm91dmVhdS0+RXR1Lk5vbSxwLT5FdHUuTm9tKTw9MCApIGJyZWFrIDsKICAgICB9Ki8KICAgIHEtPk5leHQgPSBOb3V2ZWF1OwogICAgTm91dmVhdS0+TmV4dCA9IHAgOwogICAgcmV0dXJuIEwgOwp9CgpDZWxsdWxlICogSW5zZXJ0Q3JvaXNzYW50KCBDZWxsdWxlICogTCwgRXR1ZGlhbnQgIEUpCnsgLy8gT24gaW5zZXJlIEUgZGFucyBsYSBsaXN0ZSBMIHRyaWVlIGNyb2lzc2FudGUgZWxsZSBwZXV0IGV0cmUgdmlkZQogICAgQ2VsbHVsZSAqIE5vdXZlYXUsKnAsKnEgOwogICAgTm91dmVhdT1DcmVhdGUoRSk7CiAgICBpZighTCkKICAgICAgICByZXR1cm4gTm91dmVhdTsKCiAgICBpZihzdHJjbXAoTm91dmVhdS0+RXR1Lk5vbSxMLT5FdHUuTm9tKTw9MCkKICAgIHsgTm91dmVhdS0+TmV4dCA9IEw7CiAgICAgICAgcmV0dXJuIE5vdXZlYXU7CiAgICB9CiAgICAvLyBBam91dXQgcydlZmZlY3R1ZXJhIGF1IGRlbGEgZGUgZGVidXQKIGZvcihxPUwsIHA9TC0+TmV4dCA7IHAgJiYgc3RyY21wKE5vdXZlYXUtPkV0dS5Ob20scC0+RXR1Lk5vbSk+MCA7cT1wICwgcD1wLT5OZXh0KTsgLy8gUG9pbnQgdmlyZ3VsZQogICAgLyogZm9yKHE9TCwgcD1MLT5OZXh0IDsgcCA7cT1wICwgcD1wLT5OZXh0KQogICAgIHsKICAgICAgICAgaWYgKHN0cmNtcChOb3V2ZWF1LT5FdHUuTm9tLHAtPkV0dS5Ob20pPD0wICkgYnJlYWsgOwogICAgIH0qLwogICAgcS0+TmV4dCA9IE5vdXZlYXU7CiAgICBOb3V2ZWF1LT5OZXh0ID0gcCA7CiAgICByZXR1cm4gTCA7Cn0KCgpDZWxsdWxlICogSW5zZXJ0RGVjcm9pc3NhbnQoQ2VsbHVsZSAqIEwsIEV0dWRpYW50ICBFKQp7CiAgQ2VsbHVsZSAqIE5vdXZlYXUsKnAsKnEgOwogIE5vdXZlYXU9Q3JlYXRlKEUpOwogIGlmKCFMKQogICAgICByZXR1cm4gTm91dmVhdTsKCiAgaWYoc3RyY21wKE5vdXZlYXUtPkV0dS5Ob20sTC0+RXR1Lk5vbSk+PTApCiAgewogICAgICBOb3V2ZWF1LT5OZXh0PUw7CiAgICAgIHJldHVybiBOb3V2ZWF1OwogIH0KZm9yKHE9TCwgcD1MLT5OZXh0IDsgcCAmJiBzdHJjbXAoTm91dmVhdS0+RXR1Lk5vbSxwLT5FdHUuTm9tKTwwIDtxPXAgLCBwPXAtPk5leHQpOwogIHEtPk5leHQgPSBOb3V2ZWF1OwogIE5vdXZlYXUtPk5leHQgPSBwIDsKICByZXR1cm4gTCA7Cn0KCgpDZWxsdWxlKiBUcmlDcm9pc3NhbnQoQ2VsbHVsZSAqIEwpCiAgewogICAgQ2VsbHVsZSAqTFQ9TlVMTCAsICpwPU5VTEw7CiAgICBmb3IocD1MO3A7cD1wLT5OZXh0KQogICAgewogICAgICBMVD1JbnNlcnRDcm9pc3NhbnQoTFQscC0+RXR1KTsKICAgIH0KICAgIHJldHVybiBMVDsKICB9CkNlbGx1bGUgKiBUcmlEZWNyb2lzc2FudChDZWxsdWxlICpMKQp7CiAgQ2VsbHVsZSAqTFQ9TlVMTCAsICpwPU5VTEw7CiAgZm9yKHA9TDtwO3A9cC0+TmV4dCkKICB7CiAgICBMVD1JbnNlcnREZWNyb2lzc2FudChMVCxwLT5FdHUpOwogIH0KICByZXR1cm4gTFQ7Cn0KQ2VsbHVsZSAqUmVudmVyc2VyKENlbGx1bGUgKiBMKQp7CiAgQ2VsbHVsZSAqcCwgKnEsICpMST1OVUxMOwogIHA9TDsKICB3aGlsZShwIT1OVUxMKSAvLyBhIGxlYXN0IHRoZXJlIGlzIGEgbmV4dAogIHsKICAgIHE9cC0+TmV4dDsKICAgIHAtPk5leHQ9TEk7CiAgICBMST1wOwogICAgcD1xOwogIH0KICByZXR1cm4gTEk7Cn0KaW50ICAgVGFpbGxlKENlbGx1bGUgKiBMKQp7CiAgQ2VsbHVsZSAqcDsKICBpbnQgaT0wOwogIGZvcihwPUwsaT0wO3A7aSsrLHA9cC0+TmV4dCk7CiAgcmV0dXJuIGk7Cn0KCkNlbGx1bGUgKiBQb3NpdGlvbiggQ2VsbHVsZSAqTCwgaW50IHBvcykKewogIGludCB0YWlsbGU9VGFpbGxlKEwpLGk7CiAgQ2VsbHVsZSAqcDsKICBpZihwb3M+dGFpbGxlKQogIHJldHVybiBOVUxMOy8vIEVycmV1cgogIGZvcihpPTEgLCBwPUw7IGk8cG9zIDtpKysgLCBwPXAtPk5leHQpOwogIHJldHVybiBwOwp9CkNlbGx1bGUqIENyZWVyKCkgIC8vIEVsbGUgY3JlZWUgdW4gc2V1bCBldHVkaWFudAp7CiAgQ2VsbHVsZSAqIE5vdXZlYXU7CiAgTm91dmVhdSA9IChDZWxsdWxlKiltYWxsb2Moc2l6ZW9mKENlbGx1bGUpKTsKICBOb3V2ZWF1LT5FdHU9IFNhaXNpcigpOwogIE5vdXZlYXUtPk5leHQ9TlVMTDsKICByZXR1cm4gTm91dmVhdTsKfQovLyBDZXR0ZSBmb25jdGlvbiBzZXJ0IGEgaW5zZXJlciB1biBldHVkaWFudCBkYW5zIHVuZSBwb3NpdGlvbiBwcmVjaXNlIHNpIGVsbGUgZXhpc3RlCkNlbGx1bGUgKiBJbnNlcmVyUG9zaXRpb24oQ2VsbHVsZSAqTCxpbnQgcG9zKQp7IGludCBpIDsKICBDZWxsdWxlICpwLCAqcSwgKk5vdXZlYXU7CiAgaW50IHRhaWxsZT1UYWlsbGUoTCk7IC8vIGxhIHRhaWxsZSBkZSBsYSBsaXN0ZQogIGlmKHBvczwwIHx8IHBvcz50YWlsbGUpCiAgewogICAgcHJpbnRmKCJsYSBwb3NpdGlvbiAlZCBuJ2V4aXN0ZSBwYXMgXG4iLHBvcyApOwogICAgcmV0dXJuIEw7CiAgfQogIE5vdXZlYXU9Q3JlZXIoKTsgLy8gaW5zZXJ0aW9uCiAgaWYocG9zPT0xKQogIHsKICAgIE5vdXZlYXUtPk5leHQ9TDsgLy8gcHJlbWllcmUgY2VsbHVsZSByZXNlcnbDqWUgcG91ciBsZSBub3V2ZWF1IGV0dWRpYW50IGV0IGxlIHJlc3RlIHBvdXIgbGUgcmVzdGUgZGUgbGEgbGlzdGUKICAgIHJldHVybiBOb3V2ZWF1OwogIH0KICBmb3IoaT0xLHA9TDtpPHBvcztpKysscD1xLHA9cC0+TmV4dCk7CiAgcS0+TmV4dD0gTm91dmVhdSA7CiAgTm91dmVhdS0+TmV4dD1wOwogIHJldHVybiBMIDsKCn0KQ2VsbHVsZSAqIGFqb3V0ZXJBdmFudE5vbShDZWxsdWxlICogTCxjaGFyIHRhYlsyMF0pCnsKICBDZWxsdWxlICpwLCAqcSwgKk5vdXZlYXU7CiAgRXR1ZGlhbnQgRTsKICBOb3V2ZWF1PUNyZWF0ZShTYWlzaXIoRSkpOwogIGlmIChzdHJjbXAoTC0+RXR1Lk5vbSx0YWIpPT0wKSB7CiAgICBOb3V2ZWF1LT5OZXh0PUw7CiAgICByZXR1cm4gTm91dmVhdTsKICB9CiAgZm9yKHA9TCxxPUwtPk5leHQ7cSYmc3RyY21wKHEtPkV0dS5Ob20sdGFiKSE9MDtwPXEscT1xLT5OZXh0KTsKICBwLT5OZXh0PU5vdXZlYXU7CiAgTm91dmVhdS0+TmV4dD1xOwogIHJldHVybiBMOwp9CgpDZWxsdWxlICogYWpvdXRlckFwcmVzTm9tKENlbGx1bGUgKiBMLGNoYXIgdGFiWzIwXSkKewogIENlbGx1bGUgKnA9TlVMTCwgKnE9TlVMTCwgKk5vdXZlYXU9TlVMTDsKICBFdHVkaWFudCBFOwogIGZvcihwPUwscT1wLT5OZXh0O3EmJnN0cmNtcChwLT5FdHUuTm9tLHRhYikhPTA7cD1xLHE9cS0+TmV4dCk7CiAgTm91dmVhdT1DcmVhdGUoU2Fpc2lyKEUpKTsKICBwLT5OZXh0PU5vdXZlYXU7CiAgTm91dmVhdS0+TmV4dD1xOwogIHJldHVybiBMOwp9CgppbnQgTWVudSgpCnsgICBpbnQgY2hvaXggOwogICAgcHJpbnRmKCJcbiAgICAxLS0tLT4gICAgQWpvdXQgRGVidXQgICAgXG4iKTsKICAgIHByaW50ZigiICAgIDIgLS0tLT4gICBBam91dCBGaW46IFxuIik7CiAgICBwcmludGYoIiAgICAzIC0tLS0+ICAgQWpvdXQgIEF2YW50IHVuIG5vbSAgICBcbiIpOwogICAgcHJpbnRmKCIgICAgNCAtLS0tPiAgIEFqb3V0ICBBcHLDqHMgdW4gbm9tICAgXG4iKTsKICAgIHByaW50ZigiICAgIDUgLS0tLT4gICBEZWxldGVGaXJzdCBcbiIpOwogICAgcHJpbnRmKCIgICAgNiAtLS0tPiAgIERlbGV0ZUFsbCBcbiIpOwogICAgcHJpbnRmKCIgICAgNyAtLS0tPiAgIEFmZmljaGVyIExpc3RlIFxuIik7CiAgICBwcmludGYoIiAgICA4IC0tLS0+ICAgTGUgbm9tIGQndW5lIHBvc2l0aW9uIFxuIik7CiAgICBwcmludGYoIiAgICA5IC0tLS0+ICAgQWpvdXQgZCd1biBub20gZGFucyB1bmUgcG9zaXRpb24gXG4iKTsKICAgIHByaW50ZigiICAgMTAgLS0tLT4gICBJbnNlcmVyIENyb2lzc2FudCBcbiIpOwogICAgcHJpbnRmKCIgICAxMSAtLS0tPiAgIFRyaSBDcm9pc3NhbnQgXG4iKTsKICAgIHByaW50ZigiICAgMTIgLS0tLT4gICBUcmkgRGVDcm9pc3NhbnQgXG4iKTsKICAgIHByaW50ZigiICAgMTMgLS0tLT4gICBSZW52ZXJzZXIgXG4iKTsKICAgIHByaW50ZigiICAgMTQgLS0tLT4gICBMZSBub20gZCd1bmUgcG9zaXRpb24gXG4iKTsKICAgIHNjYW5mKCIlZCIsJmNob2l4KTsKICAgIHJldHVybiBjaG9peCA7Cn0KaW50IG1haW4oKQp7ICBDZWxsdWxlICpHSU5GMT1OVUxMLCAqUmVzOwogIGludCBiOwogIEV0dWRpYW50IEU7CiAgY2hhciBub21bMjBdOwogIGludCBjaG9peCwgcG9zOwogIGRvCiAgewogICAgc3lzdGVtKCJjbHMiKTsKICAgIGNob2l4PU1lbnUoKTsKICAgIHN3aXRjaCAoY2hvaXgpIHsKICAgICAgY2FzZSAxOgogICAgICAgICAgICAgIEU9U2Fpc2lyKCk7CiAgICAgICAgICAgICAgR0lORjE9QWpvdXREZWJ1dChHSU5GMSxFKTsKICAgICAgICAgICAgICBicmVhazsKICAgICAgY2FzZSAyOgogICAgICAgICAgICAgIEU9U2Fpc2lyKCk7CiAgICAgICAgICAgICAgR0lORjE9QWpvdXRGaW4oR0lORjEsRSk7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgMzoKICAgICAgICAgICAgICBwcmludGYoImxlIG5vbSBBdmFudCBsZXF1ZWwgb24gdmEgYWpvdXRlclxuIik7CiAgICAgICAgICAgICAgc2NhbmYoIiVzIixub20pOwogICAgICAgICAgICAgIEdJTkYxPWFqb3V0ZXJBdmFudE5vbShHSU5GMSxub20pOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICBjYXNlIDQ6CiAgICAgICAgICAgICAgcHJpbnRmKCJsZSBub20gYXByZXMgbGVxdWVsIG9uIHZhIGFqb3V0ZXJcbiIpOwogICAgICAgICAgICAgIHNjYW5mKCIlcyIsbm9tKTsKICAgICAgICAgICAgICBHSU5GMT1ham91dGVyQXByZXNOb20oR0lORjEsbm9tKTsKICAgICAgICAgICAgICBicmVhazsKICAgICAgY2FzZSA1OgogICAgICAgICAgICAgIEdJTkYxPURlbGV0ZUZpcnN0KEdJTkYxKTsKICAgICAgICAgICAgICBicmVhazsKICAgICAgY2FzZSA2OgogICAgICAgICAgICAgIEdJTkYxPU5VTEw7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgNzoKICAgICAgICAgICAgICBBZmZpY2hlckxpc3RlKEdJTkYxKTsKICAgICAgICAgICAgICBicmVhazsKICAgICAgY2FzZSA4OgogICAgICAgICAgICAgIHByaW50ZigibGEgcG9zdGl0b24gc3ZwXG4iKTsKICAgICAgICAgICAgICBzY2FuZigiJWRcbiIsJnBvcyApOwogICAgICAgICAgICAgIFJlcz0gUG9zaXRpb24oR0lORjEscG9zKTsKICAgICAgICAgICAgICAgIGlmKFJlcyE9TlVMTCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgQWZmaWNoZXIoUmVzLT5FdHUpOwogICAgICAgICAgICAgICAgfWVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgcHV0cygiY2VjaSBuJ2V4aXN0ZSBwYXMiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBicmVhazsKCiAgICAgIGNhc2UgOToKICAgICAgICAgICAgICBwcmludGYoIkxhIHBvc2l0aW9uIHMnaWwgdm9pcyBwbGFpdCBcbiIpOwogICAgICAgICAgICAgIHNjYW5mKCIlZFxuIixwb3MgKTsKICAgICAgICAgICAgICBSZXM9UG9zaXRpb24oR0lORjEscG9zKTsKICAgICAgICAgICAgICBpZihSZXMhPU5VTEwpCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgSW5zZXJlclBvc2l0aW9uKFJlcyxwb3MpOwogICAgICAgICAgICAgIH1lbHNlCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcHV0cygiY2VjaSBuJ2V4aXN0ZSBwYXMiKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgMTA6CiAgICAgICAgICAgICAgR0lORjE9SW5zZXJlckNyb2lzc2FudChHSU5GMSk7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgMTE6CiAgICAgICAgICAgICAgR0lORjE9VHJpQ3JvaXNzYW50KEdJTkYxKTsKICAgICAgICAgICAgICBicmVhazsKICAgICAgY2FzZSAxMjoKICAgICAgICAgICAgICBHSU5GMT1UcmlEZWNyb2lzc2FudChHSU5GMSk7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgMTM6CiAgICAgICAgICAgICAgR0lORjE9UmVudmVyc2VyKEdJTkYxKTsKICAgICAgICAgICAgICBicmVhazsKICAgICAgZGVmYXVsdCA6CiAgICAgICAgICAgICAgICBwcmludGYoImNlIGNob2lzIG4gZXN0IHBhcyB2YWxpZGVcbiIpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICB9CiAgICBwcmludGYoInZvdWxleiB2b3VzIGNvbnRpbnVlciA/P1xuMS5vdWkgICAyLm5vblxuIENob2l4IDogIik7CiAgICBzY2FuZigiJWQiLCZiKTsKICB9d2hpbGUoYiE9Mik7CiAgICByZXR1cm4gMCA7Cn0K