Index: /BAORadio/libindi/libindi/BAOControl.log
===================================================================
--- /BAORadio/libindi/libindi/BAOControl.log	(revision 504)
+++ /BAORadio/libindi/libindi/BAOControl.log	(revision 504)
@@ -0,0 +1,4 @@
+Lecture du fichier de configuration 'params' :
+
+Nom du serveur invalide !
+Le fichier de configuration 'params' contient des erreurs ou n'existe pas. Merci de vÃ©rifier.
Index: /BAORadio/libindi/libindi/BAOControl/.directory
===================================================================
--- /BAORadio/libindi/libindi/BAOControl/.directory	(revision 503)
+++ /BAORadio/libindi/libindi/BAOControl/.directory	(revision 504)
@@ -1,2 +1,5 @@
 [Dolphin]
-Timestamp=2010,11,5,22,3,10
+Timestamp=2010,11,8,3,1,35
+
+[Settings]
+ShowDotFiles=false
Index: /BAORadio/libindi/libindi/BAOControl/Makefile
===================================================================
--- /BAORadio/libindi/libindi/BAOControl/Makefile	(revision 503)
+++ /BAORadio/libindi/libindi/BAOControl/Makefile	(revision 504)
@@ -2,20 +2,26 @@
 #
 
-CC=g++
+CC = g++ 
+#CFLAGS = -g 
+#CXXFLAGS = -g
 
-BAOControl_objects =  baocontrol.o ClientSocket.o Socket.o filetools.o exception.o astro.o
+BAOcontrol_objects =  main.o baocontrol.o ClientSocket.o Socket.o filetools.o exception.o ../drivers/telescope/astro.o
 
 
-all : BAOControl
+all : BAOcontrol
 
 
-BAOControl: $(BAOControl_objects)
-	g++ -o BAOControl $(BAOControl_objects) -lpthread -lX11
+BAOcontrol: $(BAOcontrol_objects)
+	g++  -o BAOcontrol $(BAOcontrol_objects) -lpthread -lX11
 
-Socket: Socket.cpp
+Socket:  Socket.cpp
 ClientSocket: ClientSocket.cpp
-Astro: astro.cpp
+Astro: ../drivers/telescope/astro.cpp
 baocontrol: baocontrol.cpp
+main: main.cpp
 
 clean:
-	rm -f *.o *.cpp~ *.c~ *.h~ BAOControl
+	rm -f *.o *.cpp~ *.c~ *.h~ BAOcontrol
+
+install:
+	cp BAOcontrol /usr/bin
Index: /BAORadio/libindi/libindi/BAOControl/Socket.cpp
===================================================================
--- /BAORadio/libindi/libindi/BAOControl/Socket.cpp	(revision 503)
+++ /BAORadio/libindi/libindi/BAOControl/Socket.cpp	(revision 504)
@@ -42,9 +42,10 @@
    //  TIME_WAIT - argh
     int on = 1;
-
-    if ( setsockopt ( m_sock, SOL_SOCKET, SO_REUSEADDR, ( const char* ) &on, sizeof ( on ) ) == -1 ) return false;
-
-    if (setsockopt(m_sock, SOL_TCP, TCP_NODELAY, (const char*) &on, sizeof(on)) <0) return false;
-
+ 
+    if ( setsockopt( m_sock, SOL_SOCKET, SO_REUSEADDR, ( const char* ) &on, sizeof ( on ) ) == -1 ) return false;
+ 
+    if ( setsockopt(m_sock, SOL_TCP, TCP_NODELAY, (const char*) &on, sizeof(on)) <0) return false;
+    
+    
     return true;
 }
@@ -80,5 +81,5 @@
 
     if ( bind_return == -1 ) return false;
-    
+  
     return true;
 }
Index: /BAORadio/libindi/libindi/BAOControl/Socket.h
===================================================================
--- /BAORadio/libindi/libindi/BAOControl/Socket.h	(revision 503)
+++ /BAORadio/libindi/libindi/BAOControl/Socket.h	(revision 504)
@@ -13,7 +13,8 @@
 #include <arpa/inet.h>
 #include <iostream>
+#include "stdio.h"
 
 
-const int MAXHOSTNAME = 200;
+const int MAXHOSTNAME = 1000;
 const int MAXCONNECTIONS = 5;
 const int MAXRECV = 5000;
Index: ORadio/libindi/libindi/BAOControl/astro.cpp
===================================================================
--- /BAORadio/libindi/libindi/BAOControl/astro.cpp	(revision 503)
+++ 	(revision )
@@ -1,210 +1,0 @@
-#include "astro.h"
-
-////////////////////
-// Routines Astro //
-////////////////////
-
-Astro::Astro()
-{
-    Longitude=0.0;
-    Latitude=0.0;
-    Lst=0.0;
-    JJ=0.0;
-    CorP=0.0;
-    CorEP=0.0;
-    Annee=0.0;
-    Mois=0.0;
-    Jour=0.0;
-    Heu=0.0;
-    Min=0.0;
-    Sec=0.0;
-    ep=0.0;
-    hs=0.0;
-    UTCP=0.0;
-    tsl=0.0;
-}
-
-Astro::~Astro()
-{
-}
-
-
-//0<=Angle<=2*PI
-double Astro::VerifAngle(double Angle)
-{
-    Angle=fmod(Angle, Pi2);
-    if (Angle<0.0) Angle+=Pi2;
-
-    return(Angle);
-}
-
-
-//////////////////////////////////////////////////////////////////////
-//Nutation
-
-void Astro::Nutation()
-{
-    double T,L,LP,M,MP,O,L2,LP2,O2;
-
-    T=(JJ-2415020.0)/36525.0;
-
-    L=(279.6967+(36000.7689+0.000303*T)*T)*Pidiv180;
-    LP=(270.4342+(481267.8831-0.001133*T)*T)*Pidiv180;
-    M=(358.4758+(35999.0498-0.000150*T)*T)*Pidiv180;
-    MP=(296.1046+(477198.8491+0.009192*T)*T)*Pidiv180;
-    O=(259.1833+(-1934.1420+0.002078*T)*T)*Pidiv180;
-
-    L2=2.0*L;
-    LP2=2.0*LP;
-    O2=2.0*O;
-
-    CorP=-(17.2327+0.01737*T)*sin(O)
-         -(1.2729+0.00013*T)*sin(L2)
-         +0.2088*sin(O2)
-         -0.2037*sin(LP2)
-         +(0.1261-0.00031*T)*sin(M)
-         +0.0675*sin(MP)
-         -(0.0497-0.00012*T)*sin(L2+M)
-         -0.0342*sin(LP2-O)
-         -0.0261*sin(LP2+MP)
-         +0.0214*sin(L2-M)
-         -0.0149*sin(L2-LP2+MP)
-         +0.0124*sin(L2-O)
-         +0.0114*sin(LP2-MP);
-
-    CorEP=(9.2100+0.00091*T)*cos(O)
-          +(0.5522-0.00029*T)*cos(L2)
-          -0.0904*cos(O2)
-          +0.0884*cos(LP2)
-          +0.0216*cos(L2+M)
-          +0.0183*cos(LP2-O)
-          +0.0113*cos(LP2+MP)
-          -0.0093*cos(L2-M)
-          -0.0066*cos(L2-O);
-
-    CorP=CorP/3600.0*Pidiv180;
-    CorEP=CorEP/3600.0*Pidiv180;
-}
-
-
-//////////////////////////////////////////////////////////////////////
-// calcul Jour julien
-
-void Astro::CalculJJ(double Heure)
-{
-
-    long y, a, b, c, e, m;
-
-    long year = (long)Annee;
-    int month = (int)Mois;
-    double day = Jour + Heure;
-
-
-    y = year + 4800;
-
-    m = month;
-    if ( m <= 2 )
-    {
-        m += 12;
-        y -= 1;
-    }
-    e = (306 * (m+1))/10;
-
-    a = y/100;
-    if ( year <= 1582L )
-    {
-        if ( year == 1582L )
-        {
-            if ( month < 10 )
-                goto julius;
-            if ( month > 10)
-                goto gregor;
-            if ( day >= 15 )
-                goto gregor;
-        }
-julius:
-
-        b = -38;
-    }
-    else
-    {
-
-gregor:
-        b = (a/4) - a;
-    }
-
-    c = (36525L * y)/100;
-
-    JJ = b + c + e + day - 32167.5;
-}
-
-
-///////////////////////////////////////////////////////////////////////
-//ObliquitÃ©
-
-void Astro::Obliquite(double JJ)
-{
-    double T;
-
-    T = (JJ-2415020.0) / 36525.0;
-
-    ep = (23.452294+ (((0.000000503 * T ) - 0.00000164 ) * T - 0.0130125 ) * T ) * Pidiv180;
-}
-
-///////////////////////////////////////////////////////////////////////
-//Temps sidÃ©ral local
-
-double Astro::TSL(double JJ, double HeureSiderale, double Longitude)
-{
-    double rd,T;
-
-    T = (JJ - 2415020.0 ) / 36525.0;
-    rd = 0.276919398 + ( 100.0021359 + 0.000001075 * T ) * T;
-    rd += HeureSiderale;
-    rd *= Pi2;
-    rd += CorP * cos(ep);
-    rd -= Longitude;
-
-    return VerifAngle(rd);
-}
-
-
-void Astro::CalculTSL()
-{
-    hs=(Heu+Min/60.0+Sec/3600.0)/24.0;
-
-    hs-=UTCP/24.0;
-
-    CalculJJ(hs);
-
-    Obliquite(JJ);
-
-    Nutation();
-
-    tsl=TSL(JJ, hs, Longitude);
-}
-
-
-///////////////////////////////////////////////////////////////////////
-//Azimut et hauteur Ã  partir de AR et Dec
-
-void Astro::Azimut(double ts, double Latitude, double Ar, double De, double *azi, double *hau)
-{
-    double ah, ht, a1, az, zc, ac;
-
-    ah=ts-Ar;
-
-    zc=sin(Latitude)*sin(De)+cos(Latitude)*cos(De)*cos(ah);
-    ht=atan(zc/sqrt((-zc*zc)+1.0));
-
-    a1=cos(De)*sin(ah)/cos(ht);
-    ac=(-cos(Latitude)*sin(De)+sin(Latitude)*cos(De)*cos(ah))/cos(ht);
-    az=atan(a1/sqrt((-a1*a1)+1.0));
-    if (ac<0.0) az=Pi-az;
-
-    az=VerifAngle(Pi+az);
-
-    *azi=az;
-    *hau=ht;
-}
-
Index: ORadio/libindi/libindi/BAOControl/astro.h
===================================================================
--- /BAORadio/libindi/libindi/BAOControl/astro.h	(revision 503)
+++ 	(revision )
@@ -1,54 +1,0 @@
-// Definition of the Astro class
-// Franck RICHARD
-// BAORadio
-
-#ifndef Astro_class
-#define Astro_class
-
-#include "math.h"
-
-//////////////////////////////
-// Constantes MathÃ©matiques //
-//////////////////////////////
-
-#define Pi		3.14159265358979323846264338327
-#define Pidiv180	0.01745329251994329576923690768
-#define N180divPi	57.2957795130823208767981548141
-#define Pi2          	6.28318530717958647692528676655
-#define Pidiv2		1.57079632679489661923132169163
-
-
-class Astro
-{
-public:
-    Astro();
-    ~Astro();
-
-    double VerifAngle(double Angle);
-    void  Azimut(double ts, double Latitude, double Ar, double De, double *azi, double *hau);
-    void  CalculJJ(double Heure);
-    double TSL(double JJ,double HeureSiderale,double Longitude);
-    void Nutation();
-    void Obliquite(double JJ);
-    void CalculTSL();
-    
-    double Longitude;
-    double Latitude;
-    double Lst;
-    double JJ;
-    double CorP;
-    double CorEP;
-    double Annee;
-    double Mois;
-    double Jour;
-    double Heu;
-    double Min;
-    double Sec;
-    double ep;
-    double hs;
-    double UTCP;
-    double tsl;
-};
-
-
-#endif
Index: /BAORadio/libindi/libindi/BAOControl/baocontrol.cpp
===================================================================
--- /BAORadio/libindi/libindi/BAOControl/baocontrol.cpp	(revision 503)
+++ /BAORadio/libindi/libindi/BAOControl/baocontrol.cpp	(revision 504)
@@ -1,6 +1,9 @@
-/********************/
-/* BAOCONTROL       */
-/*                  */
-/********************/
+/******************************/
+/* BAOCONTROL                 */
+/*                            */
+/* Franck RICHARD             */
+/* franckrichard033@gmail.com */
+/* Juin 2011                  */
+/******************************/
 
 
@@ -8,38 +11,199 @@
 
 
-/* Affiche Ã  l'Ã©cran (si AfficheEcran==true) et sauvegarde dans le fichier 
-   BAOControl.log le message contenu dans la variable chaine */
-void Affiche(std::string chaine, bool AfficheEcran)
+
+/**************************************************************************************
+**Constructeur
+***************************************************************************************/
+
+BAOcontrol::BAOcontrol()
+{
+    float a1, a2, a3;
+
+    // Le choix de la couleur des caractÃšres est adaptÃ© pour une fenÃªtre de terminal
+    // ayant un fond blanc. pour un fond noir, mettre couleurs=2 dans le fichier params
+
+    ChoixCouleurs=1;
+
+
+    Affiche("\n\n\n\n\n \
+ ******************************************\n \
+ *             BAORadio Control           *\n \
+ * Laboratoire de l'AccÃ©lÃ©rateur LinÃ©aire *\n \
+ *                                        *\n \
+ *             v0.2  20/06/2011           *\n \
+ *        franckrichard033@gmail.com      *\n \
+ ******************************************\n\n\n", true);
+
+    //Initialisation des variables globales et des pointeurs
+
+
+    delaitransit  = 0;
+    delaitracking = 0;
+    lognum        = 0;
+    numAntenne    = 0;
+    numobjets     = 0;
+    runnum        = 1;
+
+    Pression      = 1013.0;
+    Temperature   = 10.0;
+
+    NoExit        = true;
+    Transit       = false;
+    run           = false;
+    exitrun       = false;
+
+    fd            = NULL;
+    client_socket = NULL;
+
+    // chaines de caractÃšres et tableaux
+
+    LatitudeChar  = "";
+    LongitudeChar = "";
+    Serveur       = "";
+    Port          = "";
+
+    Antennes 	  = new DefAntenne[MAXANTENNES];
+    objets        = new DefObjets[MAXOBJETS];
+
+    //on initalise aussi les tableaux
+
+    for (int i=0; i<MAXANTENNES; i++)
+    {
+        Antennes[i].ok=0;
+        Antennes[i].ip=0;
+    }
+
+    for (int i=0; i<MAXOBJETS; i++)
+    {
+        objets[i].JJ=0;
+        objets[i].exec=false;
+    }
+
+    // Chargement du fichier contenant les paramÃštres
+
+    if (!ChargementParametres("params"))
+    {
+        Erreur("Le fichier de configuration 'params' contient des erreurs ou n'existe pas.\n \
+        Merci de vÃ©rifier.\n\n");
+        exit(1);
+    }
+
+    // Conversion de la latitude et de la longitude en radians
+
+    Decomposition(LatitudeChar, 0, &a1, &a2, &a3);
+
+    double Latitude = (a1 + a2 / 60.0 + a3 / 3600.0) * Pidiv180;
+
+    Decomposition(LongitudeChar, 1, &a1, &a2, &a3);
+
+    double Longitude = Pi2 - ( a1 + a2 / 60.0 + a3 / 3600.0 ) * Pidiv180;
+
+    // Transfert de la latitude, longitude, pression, tempÃ©rature Ã  la classe Astro
+
+    DefinirLongitudeLatitude(Longitude, Latitude);
+
+    DefinirPressionTemp(Pression, Temperature);
+
+    // Ouverture du socket avec indi_BAO
+
+    client_socket = new ClientSocket("localhost", atoi(Port.c_str()) );
+
+    // On se connecte au pilote indi_BAO
+
+    Connect(true);
+}
+
+
+
+/**************************************************************************************
+** Destructeur
+***************************************************************************************/
+
+BAOcontrol::~BAOcontrol()
+{
+    // destruction des tableaux
+
+    delete [] Antennes;
+    delete [] objets;
+
+    // destruction de la fenÃªtre graphique, des caractÃšres
+
+    if (d!=NULL)
+    {
+        XFreeGC(d, noir);
+        XFreeGC(d, vert);
+        XFreeGC(d, rouge);
+        XFreeGC(d, gris);
+        XFreeFont(d, fd);
+        XDestroyWindow(d, w);
+        XCloseDisplay(d);
+    }
+
+    // destruction du socket
+
+    delete client_socket;
+}
+
+
+/**************************************************************************************
+** Affiche le message Ã  l'Ã©cran (si AfficheEcran==true) et le sauvegarde dans le fichier
+** BAOControl.log
+***************************************************************************************/
+
+void BAOcontrol::Affiche(string Message, bool AfficheEcran)
 {
     FILE *pFile = NULL;
 
-    pFile = fopen ("BAOControl.log", "a");
-
-    if (AfficheEcran) std::cout << chaine;
-    
-    fprintf (pFile, chaine.c_str());
-
-    os.str("");
-
-    fclose (pFile);
-}
-
-
-/*Affiche les messages d'erreur en rouge */
-void Erreur(std::string chaine)
-{
-    std::cout << red;
+    if ( (pFile = fopen ("BAOcontrol.log", "a")) != NULL)
+    {
+        if (AfficheEcran) cout << Message;
+
+        fprintf (pFile, Message.c_str());
+
+        fclose (pFile);
+    }
+}
+
+void BAOcontrol::Affiche(stringstream *Message, bool AfficheEcran)
+{
+    Affiche(Message->str(), AfficheEcran);
+
+    // on efface le buffer
+
+    Message->str("");
+}
+
+
+/**************************************************************************************
+** Affiche les messages d'erreur en rouge
+***************************************************************************************/
+
+void BAOcontrol::Erreur(string chaine)
+{
+    ChoixCouleurs==1 ? cout << red1  : cout << red2;
     Affiche(chaine, true);
-    std::cout << black;
-}
-
-
-/*initialise une fenÃªtre graphique */
-void initialiserFenetre()
+    ChoixCouleurs==1 ? cout << grey1 : cout << grey2;
+}
+
+void BAOcontrol::Erreur(stringstream *Message)
+{
+    Erreur(Message->str());
+
+    // on efface le buffer
+
+    Message->str("");
+}
+
+
+/**************************************************************************************
+** Initialise la fenÃªtre graphique
+***************************************************************************************/
+
+void BAOcontrol::initialiserFenetre()
 {
     XGCValues gcv;
-    XFontStruct * fd;
-    
-    /*contacte le serveur*/
+
+    // contacte le serveur graphique
+
     if ((d = XOpenDisplay(getenv("DISPLAY"))) == NULL)
     {
@@ -48,15 +212,18 @@
     }
 
-    /*crÃ©e une fenÃªtre*/
+    // crÃ©e une fenÃªtre
+
     w = XCreateSimpleWindow(d, RootWindow(d, DefaultScreen(d)),
-                            0, 0, larg, haut,
+                            0, 0, larg_fenetre, haut_fenetre,
                             2, BlackPixel(d, DefaultScreen(d)),
                             WhitePixel(d, DefaultScreen(d)));
-	
-    /* Creation du double buffer */
-    db = XCreatePixmap(d, w, larg, haut, DefaultDepth(d, DefaultScreen(d)));
-
-    /*chargement d'une police de caractÃšres*/
-    if ((fd=XLoadQueryFont(d, "fixed")) == NULL)
+
+    // CrÃ©ation du double buffer
+
+    db = XCreatePixmap(d, w, larg_fenetre, haut_fenetre, DefaultDepth(d, DefaultScreen(d)));
+
+    // Chargement de la police de caractÃšres
+
+    if ((fd = XLoadQueryFont(d, "fixed")) == NULL)
     {
         Erreur("Impossible de charger la police fixed\n\n");
@@ -64,5 +231,6 @@
     }
 
-    /*crÃ©ation d'un contexte graphique*/
+    // CrÃ©ation des couleurs
+
     gcv.font = fd->fid;
     gcv.foreground = BlackPixel(d, DefaultScreen(d));
@@ -78,77 +246,108 @@
     gris = XCreateGC(d, w, GCFont | GCForeground, &gcv);
 
-    /*affiche la fenÃªtre */
+    // Affichage de fenÃªtre
+
     XMapWindow(d, w);
 }
 
 
-/* Dessine les Ã©lÃ©ments de la fenÃªtre graphique */
-void Dessiner()
-{
-    char chaine[100];
+/**************************************************************************************
+** Dessine les Ã©lÃ©ments dans la fenÃªtre graphique
+***************************************************************************************/
+
+void BAOcontrol::Dessiner()
+{
+    char *chaine;
     GC color;
 
-    /* On efface la fenÃªtre */
+    chaine = new char [100];
+
+    // On efface la fenÃªtre
+
     XSetForeground(d, noir, WhitePixel(d, DefaultScreen(d)));
-    XFillRectangle(d, db, noir, 0, 0, larg, haut);
+    XFillRectangle(d, db, noir, 0, 0, larg_fenetre, haut_fenetre);
     XSetForeground(d, noir, BlackPixel(d, DefaultScreen(d)));
 
-    /* Affichage de la date et de l'heure */
-    int h=astro->Heu;
-    int m=astro->Min;
-    int s=astro->Sec;
-    int j=astro->Jour;
-    
+    // On rÃ©cupÃšre la date et l'heure contenue dans la classe astro (et le jour julien)
+
+    double h  = GetHeure();
+    double mi = GetMin();
+    double s  = GetSec();
+    double a  = GetAnnee();
+    double m  = GetMois();
+    double j  = GetJour();
+    double JJ = GetJJ();
+
+    // on Ã©vite les affichages de l'heure du genre 12:56:60 ou 24:00:00
+
     if (s==60) {
-        s=0;
-        m++;
-        if (m==60) {
-            m=0;
+        s = 0;
+        mi++;
+        if (mi == 60) {
+            mi = 0;
             h++;
-            if (h==24) {
-                h=0;
+            if (h == 24) {
+                h = 0;
                 j++;
             }
         }
-    }    
-    
-    sprintf(chaine, "%02i:%02i:%02i TU    %02i/%02.0f/%04.0f    JJ=%10.5f",
-            h, m, s, j, astro->Mois, astro->Annee, astro->JJ);
+    }
+
+    //affichage de la date et de l'heure
+
+    sprintf(chaine, "%02.0f:%02.0f:%02.1f TU    %02.0f/%02.0f/%04.0f    JJ=%10.5f",
+            h, mi, s, j, m, a, JJ);
 
     XDrawString(d, db, noir, 10, 10, chaine, strlen(chaine));
 
+    //En cas d'exÃ©cution d'un fichier de mouvements, on affiche la prochaine Ã©tape
+
     if (run)
     {
-        sprintf(chaine, "Prochaine etape dans %4.1fs", (objets[runnum].JJ-astro->JJ)*3600.0*24.0);
-
-        if ((objets[runnum].JJ-astro->JJ)*3600.0*24.0 >= 0.0) XDrawString(d, db, noir, 350, 10, chaine, strlen(chaine));
-    }
-
-    /*affichage des cercles d'Ã©tat*/
+        sprintf(chaine, "Prochaine etape dans %4.1fs", (objets[runnum].JJ - JJ) * 3600.0 * 24.0);
+
+        if ((objets[runnum].JJ - JJ) * 3600.0 * 24.0 >= 0.0)
+            XDrawString(d, db, noir, 350, 10, chaine, strlen(chaine));
+    }
+
+    // affichage des cercles d'Ã©tat
+    // vert = l'antenne fonctionne
+    // rouge = problÃšme dÃ©tectÃ© sur l'antenne
+    // gris = antenne non connectÃ©e
+
     for (int i=0; i <20; i++)
     {
-        for (int j=0; j<5; j++)
-        {
-            switch(Antennes[20*j+i].ok)
-	    {
-	      case 1 : color=vert; break;
-	      case 2 : color=rouge; break;
-	      default: color=gris; break;
-	    }
+        for (int j=0; j<2; j++)
+        {
+            switch (Antennes[20*j+i].ok)
+            {
+            case 1 :
+                color=vert;
+                break;
+            case 2 :
+                color=rouge;
+                break;
+            default:
+                color=gris;
+                break;
+            }
+
             XFillArc(d, db ,color, 10+i*30, 20+j*30, 15, 15, 0, 360*64);
-            XDrawArc(d, db ,noir, 10+i*30, 20+j*30, 15, 15, 0, 360*64);
-        }
-    }
-
-
-    /*Affichage des messages d'erreur*/
-    if (lognum>15)
-    {
-        for (int i=lognum-1; i>lognum-16; i--)
+            XDrawArc(d, db ,noir,  10+i*30, 20+j*30, 15, 15, 0, 360*64);
+        }
+    }
+
+
+    // Affichage des messages d'indi_BAO
+    // gÃšre aussi le dÃ©filement
+
+    if (lognum>10)
+    {
+        for (int i=lognum-1; i>lognum-11; i--)
         {
             if ((logs[i].find("Err")!=string::npos)
                     || (logs[i].find("ALERTE")!=string::npos)) color=rouge;
             else color=vert;
-            XDrawString(d, db, color, 10, 15*12+(i-lognum+15)*12, logs[i].c_str(), strlen(logs[i].c_str()));
+            XDrawString(d, db, color, 10, 9*12+(i-lognum+10)*12, logs[i].c_str(), strlen(logs[i].c_str()));
         }
     }
@@ -160,17 +359,26 @@
                     || (logs[i].find("ALERTE")!=string::npos)) color=rouge;
             else color=vert;
-            XDrawString(d, db, color, 10, 15*12+i*12, logs[i].c_str(), strlen(logs[i].c_str()));
-        }
-    }
-    
-    XCopyArea(d, db, w, noir, 0, 0, larg, haut, 0, 0); 
-          
-    /* on force le rafraichissement de l'Ã©cran */
+            XDrawString(d, db, color, 10, 9*12+i*12, logs[i].c_str(), strlen(logs[i].c_str()));
+        }
+    }
+
+    // On affiche la copie de l'Ã©cran une fois que tout est dessinÃ©
+    // on Ã©vite ainsi les scientillements de la fenÃªtre
+
+    XCopyArea(d, db, w, noir, 0, 0, larg_fenetre, haut_fenetre, 0, 0);
+
+    // On force le rafraichissement de l'Ã©cran
+
     XFlush(d);
-}
-
-
-/* Gestion des messages concernant la fenÃªtre graphique */
-void rouler(char* reponse)
+
+    delete [] chaine;
+}
+
+
+/**************************************************************************************
+** Gestion des Ã©vÃ©nements affectant la fenÃªtre graphique
+***************************************************************************************/
+
+void BAOcontrol::rouler()
 {
     XEvent e;
@@ -181,5 +389,5 @@
         {
         default:
-            //std::cout << "J'ai reÃ§u un Ã©vÃšnement " <<  e.type << std::endl
+            //cout << "J'ai reÃ§u un Ã©vÃ©nement " <<  e.type << endl
             break;
         case Expose :
@@ -191,94 +399,159 @@
 
 
-/* RÃ©cupÃšre les messages envoyÃ©s par indi_BAO */
-void LireReponse()
-{
-    std::string reponse, decomp;
-    std::stringstream os;
+/**************************************************************************************
+** RÃ©cupÃšre les messages envoyÃ©s par indi_BAO
+***************************************************************************************/
+
+void BAOcontrol::LireReponse()
+{
+    string reponse, memreponse, decomp;
     bool test=false;
 
     *client_socket >> reponse;
-
-    if (reponse.find("message")!=string::npos)
-    {
-        /* on ne garde que la partie intÃ©ressante */
-        reponse=reponse.substr(reponse.find("message")+9);
-
-        reponse=reponse.substr(0, reponse.find("\""));
-
-	/*rÃ©cupÃšre l'adresse ip de l'antenne */
-        if (reponse.find(". (Antennes connectees")!=string::npos)
-        {
-            decomp=reponse.substr(0, reponse.find(". (Antennes connectees"));
-            decomp=decomp.substr(decomp.rfind(".")+1);
-
-	    /*si cette antenne est dÃ©jÃ  connectÃ©e, on change son Ã©tat */
-            for (int i=0; i<numAntenne; i++)
+    
+   // printf("%s\n", reponse.c_str());
+
+    do
+    {
+        if (reponse.find("message")!=string::npos)
+        {
+            // On ne garde que la partie intÃ©ressante
+            // La partie suivant "message="...
+            reponse = reponse.substr(reponse.find("message") + 9);
+
+            memreponse = reponse;
+
+            // ...jusqu'au "
+            reponse=reponse.substr(0, reponse.find("\""));
+
+            // On rÃ©cupÃšre l'adresse ip de l'antenne qui nous parle
+            // et on met Ã  jour le tabmeau des Ã©tats des antennes
+
+            if (reponse.find(". (Antennes connectees")!=string::npos)
             {
-                if (atoi(decomp.c_str()) == Antennes[i].ip)
+                decomp=reponse.substr(0, reponse.find(". (Antennes connectees"));
+                decomp=decomp.substr(decomp.rfind(".")+1);
+
+                // si cette antenne est dÃ©jÃ  connectÃ©e, on change son Ã©tat
+
+                for (int i=0; i<numAntenne; i++)
                 {
-                    Antennes[i].ok=1;
-                    test=true;
-		    break;
+                    if (atoi(decomp.c_str()) == Antennes[i].ip)
+                    {
+                        Antennes[i].ok=1;
+                        test=true;
+                        break;
+                    }
+                }
+
+                // ou si c'est une nouvelle antenne, on l'ajoute au tableau
+
+                if (!test)
+                {
+                    Antennes[numAntenne].ip = atoi(decomp.c_str());
+                    Antennes[numAntenne++].ok = 1;
                 }
             }
 
-            /*ou on ajoute son Ã©tat */
-            if (!test)
+            // erreur sur une antenne -> on change son Ã©tat dans la fenÃªtre
+
+            if  ((reponse.find("ALERTE antenne ")!=string::npos) ||
+                    (reponse.find("Erreur sur l antenne ")!=string::npos))
             {
-                Antennes[numAntenne].ip=atoi(decomp.c_str());
-                Antennes[numAntenne].ok=1;
-                numAntenne++;
-            }
-        }
-
-        /*erreur sur une antenne -> on change son Ã©tat dans la fenÃªtre */
-        if  ((reponse.find("ALERTE antenne ")!=string::npos) || (reponse.find("Erreur sur l antenne ")!=string::npos))
-        {
-            decomp=reponse.substr(0, reponse.find(" :"));
-            decomp=decomp.substr(decomp.rfind(".")+1);
-
-            for (int i=0; i<numAntenne; i++)
-            {
-                if (atoi(decomp.c_str()) == Antennes[i].ip)
+                decomp = reponse.substr(0, reponse.find(" :"));
+                decomp = decomp.substr(decomp.rfind(".") + 1);
+
+                for (int i=0; i<numAntenne; i++)
                 {
-                    Antennes[i].ok=2;
+                    if (atoi(decomp.c_str()) == Antennes[i].ip)
+                    {
+                        Antennes[i].ok = 2;  // Erreur sur l'antenne i
+                    }
                 }
             }
-        }
-
-        /* On sauvegarde le message dans le tableau log */
-        os << lognum << " : " << reponse;
-	
-	Affiche(os.str(), false);
-	Affiche("\n", false);
-
-        logs[lognum++]=os.str();
-	if (lognum>=MAXLOG-1) lognum=0;
+
+            // On sauvegarde le message dans le tableau logs
+
+            stringstream os;
+
+            os << lognum << " : " << reponse;
+
+            Affiche(os.str() + "\n", false);
+
+            if (lognum<MAXLOG-1) logs[lognum++] = os.str();
+
+            reponse = memreponse;
+        } 
+        else reponse="";
 	  
-	/*on actualise la fenÃªtre */
+
+    } while ( reponse !="" );
+
+     // on actualise la fenÃªtre
+
         Dessiner();
-    }
-
-    rouler((char *)reponse.c_str());
-}
-
-
-/* Est-ce que la rÃ©ponse du pilote indi_BAO
-est conforme Ã  ce que l'on attendait ? */
-bool VerifReponse(std::string reponseattendue)
-{
-    std::string reponse;
-
-    usleep(10000); // attendre 10 ms pour laisser le temps au pilote indi_BAO de rÃ©pondre
-
-    *client_socket >> reponse;
-
-    if (reponse.find(reponseattendue)==string::npos)
-    {   
-        //rÃ©ponse inconnue -> une erreur ?
-        os << "RÃ©ponse du pilote indi_BAO :" << std::endl << reponse
-                  << std::endl << std::endl << std::endl;
-	Erreur(os.str());	  
+
+    // on envoie un message pour actualiser la fenÃªtre graphique
+
+    rouler();
+}
+
+
+/**************************************************************************************
+** Est-ce que la rÃ©ponse du pilote indi_BAO est conforme Ã  ce que l'on attendait ?
+***************************************************************************************/
+
+bool BAOcontrol::VerifReponse(string reponseattendue)
+{
+    string reponse = "";
+    string memreponse = "";
+    int    duree = 0;
+    bool   test = false;
+
+    // TODO :La rÃ©ponse du driver ne vient pas tout de suite et on peut recevoir
+    // des messages intermÃ©diaires un peu Ã©tranges impliquant la fonction CONNECT, pourquoi ?
+    // LÃ  on lit les messages trois fois de suite pour essayer de voir passer le bon
+    // Essayer de voir si on ne peut pas faire mieux...
+
+    for (int i=0; i<3 ;i++)
+    {
+        do
+        {
+            usleep(1000); // attendre 1 ms pour laisser le temps au pilote indi_BAO de rÃ©pondre
+
+            *client_socket >> reponse;
+
+            duree++;
+        }
+        while (reponse.length() == 0 && duree<10 ); // on attend un message pendant 10 ms max
+
+        // on ajoute tous les messages reÃ§us dans memmreponse
+        // ->intÃ©ressant pour le debug
+
+        memreponse += reponse;
+
+        if (reponse.find(reponseattendue) != string::npos)
+        {
+            test = true;
+            break;
+        }
+    }
+
+    if (!test)
+    {
+        // rÃ©ponse inconnue -> une erreur ?
+
+        int pos = memreponse.find("message=");
+
+        if ( pos != string::npos )
+        {
+            memreponse = memreponse.substr(pos + 9);
+
+            memreponse = memreponse.substr(0, memreponse.find("\""));
+
+            Erreur("RÃ©ponse du pilote indi_BAO :" + memreponse + "\n\n");
+        }
+
+        return false;
     }
 
@@ -287,7 +560,9 @@
 
 
-/*RÃ©cupÃ©ration de la date et de l'heure 
- et calcul du jour julien et du tsl */
-void CalculJourJulien()
+/**************************************************************************************
+** Calcul du jour julien et du temps sidÃ©ral local
+***************************************************************************************/
+
+void BAOcontrol::Update()
 {
     struct tm date;
@@ -296,63 +571,122 @@
     struct timezone tz;
 
+    // On rÃ©cupÃšre la date et l'heure depuis l'horloge du systÃšme
+
     time(&t);
     date=*gmtime(&t);
     gettimeofday(&tv, &tz);
 
-    astro->Annee=(double)(date.tm_year+1900);
-    astro->Mois=(double)(date.tm_mon+1);
-    astro->Jour=(double)date.tm_mday;
-    astro->Heu=(double)date.tm_hour;
-    astro->Min=(double)date.tm_min;
-    astro->Sec=(double)date.tm_sec+tv.tv_usec/1.0E6;
-    astro->UTCP=0.0;//(double)date.tm_isdst;
-
-    //Calcul du temps sidÃ©ral local et du JJ
-
-    astro->CalculTSL();
-}
-
-
-/* gestion du thread permettant l'actualisation de la fenÃªtre graphique
- et la rÃ©cupÃ©ration des messages d'indi_BAO */
-void *my_thread_process (void * arg)
-{
+    double Annee = (double)date.tm_year + 1900.0;
+    double Mois  = (double)date.tm_mon + 1.0;
+    double Jour  = (double)date.tm_mday;
+    double Heu   = (double)date.tm_hour;
+    double Min   = (double)date.tm_min;
+    double Sec   = (double)date.tm_sec + tv.tv_usec / 1.0E6;
+    double UTCP  = 0.0;//(double)date.tm_isdst;
+
+    /*Annee=2011;
+    Mois=6;
+    Jour=17;
+    Heu=15;
+    Min=53.0;
+    Sec=00.0;*/
+
+    // On actualise la date et l'heure dans la classe Astro
+
+    DefinirDateHeure(Annee, Mois, Jour, Heu, Min, Sec);
+
+
+    // On lance le calcul
+
+    CalculTSL();
+}
+
+
+/**************************************************************************************
+** gestion du thread permettant
+** -l'exÃ©cution d'une liste de mouvements programmÃ©s
+** -l'actualisation de la fenÃªtre graphique
+** -la rÃ©cupÃ©ration des messages du pilote indi_BAO
+***************************************************************************************/
+
+void *BAOcontrol::my_thread_process ()
+{
+    stringstream os;
+
+    // Tant ue l'utilisateur n'a pas taper la commande 'exit'
     while (NoExit)
     {
-        CalculJourJulien();
-
-	//Execution d'un fichier de mouvements
+        //On actualise le jour julien et le temps sidÃ©ral local
+
+        Update();
+
+        // On rÃ©cupÃšre le jour julien
+
+        double JJ = GetJJ();
+
+
+        // Faut-il executer un fichier de mouvements ?
+        // il faut qu'il y ait plus d'un mouvement
+        // et exxecuter les commande dans ce test jusqu'au dernier mouvement
+
         if (run && numobjets>1 && runnum<numobjets)
         {
-	    /* On lance l'exÃ©cution des mouvements programmÃ©s */
-            if (astro->JJ>=objets[runnum].JJ && !objets[runnum].exec)
+            // On lance le mouvement numÃ©ro runnum si la date correspond au dÃ©but
+            // de son exÃ©cution et que ce mouvement n'a pas Ã©tÃ© encore rÃ©alisÃ©
+
+            if (JJ >= objets[runnum].JJ && !objets[runnum].exec)
             {
+                // petits messages pour l'utilisateur
+
                 if (runnum==1) Affiche("DÃ©but de l'exÃ©cution du fichier de mouvements\n\n", true);
-                os << "Suivi de l'objet nÂ°" << runnum << std::endl;
-		Affiche(os.str(), true);
+
+                os << "Suivi de l'objet nÂ°" << runnum << endl;
+                Affiche(&os, true);
+
+                // on indique que le mouvement est en cours d'exÃ©cution
+                //ou qu'il a Ã©tÃ© dÃ©jÃ  exÃ©cutÃ©
+
                 objets[runnum].exec=true;
 
-                Goto(objets[runnum].ad, objets[runnum].de, Transit);
+                //on envoie l'ordre goto correspondant
+
+                Goto(objets[runnum].ad, objets[runnum].de, Transit, J2000);
             }
 
-            /*on arrive Ã  la fin du mouvements i */
-            if (astro->JJ>=objets[runnum].JJ+objets[runnum].Duree/3600.0/24.0)
+
+            // On arrive Ã  la fin de l'exÃ©cution du mouvements runnum
+
+            if (JJ >= objets[runnum].JJ + objets[runnum].Duree / 3600.0 / 24.0 )
             {
+                // On interrompt le mouvement
+
                 Abort();
 
-		/*fin de la commande run */
-                if (runnum+1>=numobjets)
+                // S'il s'agit du dernier mouvement -> Fin de la commande run
+
+                if ( runnum + 1 >= numobjets )
                 {
                     Affiche("Fin de l'execution du fichier de mouvements\n\n", true);
-		    std::cout << std::endl << blue << ">";
+
+                    // on rÃ©affiche le prompt
+
+                    cout << endl;
+                    ChoixCouleurs==1 ? cout << blue1 : cout << blue2;
+                    cout << ">";
+
+                    // on rÃ©initiale toutes les variables impliquÃ©es dans la commande run
+
                     run=false;
                     runnum=1;
                     numobjets=1;
 
-		    /*on sort du programme dans le cas ./BAOControl -r fileName */
-                    if (exitrun) NoExit=false;
+                    // On sort du programme dans le cas BAOControl -r fileName
+
+                    NoExit=!exitrun;
                 }
                 else
                 {
+                    // on passe au mouvement suivant
+
                     runnum++;
                 }
@@ -360,10 +694,17 @@
         }
 
+        // on lit et affiche la rÃ©ponse des microcontrolleurs
+
         LireReponse();
 
         Dessiner();
 
-        usleep(100000); //100 ms
-    }
+        // pause de 100 ms
+
+        usleep(100000);
+    }
+
+    // l'utilisateur a tapÃ© exit... On sort du thread...
+
 
     pthread_exit (0);
@@ -371,103 +712,97 @@
 
 
-
-/* DÃ©composition et vÃ©rification des dates, heures, AD et dÃ©clinaisons 
- type = 0 -> DÃ©clinaison/latitude
- type = 1 -> longitude
- type = 2 -> AD ou heure
- type = 3 -> date */
-bool Decomposition(std::string chaine, char type, float *a1, float *a2, float *a3)
-{
-    std::string car, s;
-    int pos1, pos2;
-    float a, b, c;
-
-    if (type==3) car="/"; else car=":";
-    
-    /* Y a-t-il 2 caractÃšres : ou / Ã  la suite ? */
-    int test=0;
-    for (int i=0; i<chaine.length(); i++) if (chaine[i]==car[0]) test++;
-    if (test<2) return false;
-
-    s=chaine.substr(0, chaine.find(car));
-
-    a=atoi(s.c_str());
-     
-    s=chaine.substr(chaine.find(car)+1, chaine.rfind(car)-chaine.find(car)-1);
-    
-    b=atoi(s.c_str());
-
-    s=chaine.substr(chaine.rfind(car)+1);
-
-    c=atoi(s.c_str());
-
-    if (type <3)
-    {
-        if ((type==0) && (a>90.0 || a<-90.0)) return false;
-        if ((type==1) && (a>180.0 || a<-180.0)) return false;
-        if ((type==2) && (a>23.0 || a<0.0)) return false;
-        if (b<0.0 || b>59.0) return false;
-        if (c<0.0 || c>=60.0) return false;
-    }
-    else
-    {
-        if (a<0.0 || a>31.0) return false;
-        if (b<0.0 || b>12.0) return false;
-    }
-
-    if (a1!=NULL) *a1=a;
-    if (a2!=NULL) *a2=b;
-    if (a3!=NULL) *a3=c;
+void* LancementThread(BAOcontrol * appli)
+{
+    appli->my_thread_process();
+
+    return 0;
+}
+
+
+
+
+/**************************************************************************************
+** DÃ©crypte les commandes saisies par l'utilisateur
+** Exemples :
+** DecompositionCommande("goto 10:10:10 25:10:10", "goto", &chaine1, &chaine2)
+** retourne chaine1  = "10:10:10"
+**          chaine2  = "25:10:10"
+**
+** DecompositionCommande("goto messier 1","goto", &chaine1, NULL) (avec chaine2=NULLL)
+** retourne chaine1  = "messier 1"
+**          chaine2  = NULL
+***************************************************************************************/
+
+bool BAOcontrol::DecompositionCommande(string chaine, string commande, string *chaine1, string *chaine2)
+{
+    size_t pos = chaine.find(commande);
+
+    // si la commande est prÃ©sente dans chaine, on continue
+
+    if (pos != string::npos)
+    {
+        // on s'intÃ©resse aux caractÃšres qui suivent la commande
+
+        pos += commande.length();
+
+        chaine = chaine.substr(pos);
+
+        // on ignore les espaces superflus
+
+        while (chaine[0] == ' ') chaine = chaine.substr(1);
+
+        // si on veut prendre les deux arguments d'un commande
+
+        if (chaine2 != NULL)
+        {
+            // on prend le premier bloc jusqu'au prochain espace -> c'est la chaine1
+
+            *chaine1 = chaine.substr(0, chaine.find(" "));
+
+            // puis on prend le deuxiÃšme bloc -> c'est la chaine2
+            pos = chaine.find(" ");
+
+            if (pos != string::npos)
+            {
+                chaine = chaine.substr(pos + 1);
+
+                while (chaine[0] == ' ') chaine = chaine.substr(1);
+
+                *chaine2 = chaine.substr(0, chaine.find(" "));
+            }
+        }
+        else
+        {
+            // on prend tout d'un bloc aprÃšs la commande -> chaine 1
+            // utile pour une commande ty type goto m 42 qui doit retourner "m 42" dans une
+            // mÃªme chaine
+
+            *chaine1 = chaine;
+        }
+    }
 
     return true;
 }
 
-/* isole les diffÃ©rents Ã©lÃ©ments de la commande saisie par l'utilisateur */
-bool DecompositionCommande(std::string chaine, std::string commande, std::string *chaine1, std::string *chaine2)
-{
-    size_t pos;
-
-    pos = chaine.find(commande);
-
-    if (pos!=string::npos)
-    {
-        pos+=commande.length();
-
-        chaine=chaine.substr(pos);
-
-        while (chaine[0] == ' ') chaine=chaine.substr(1);
-
-        *chaine1=chaine.substr(0,chaine.find(" "));
-
-        if (chaine2!=NULL)
-        {
-            pos = chaine.find(" ");
-
-            if (pos!=string::npos)
-            {
-                chaine=chaine.substr(pos+1);
-
-                while (chaine[0] == ' ') chaine=chaine.substr(1);
-
-                *chaine2=chaine.substr(0, chaine.find(" "));
-            }
-        }
-    }
-
-    return true;
-}
-
-
-/*Envoie la longitude et la latitude du lieu d'observation au pilote indi_BAO */
-bool EncoyerCoordGeographiques()
-{
+
+
+/**************************************************************************************
+** Envoie la longitude et la latitude du lieu d'observation au pilote indi_BAO
+***************************************************************************************/
+
+bool BAOcontrol::EnvoyerCoordGeographiques()
+{
+    // la communication avec le pilote indi_BAO
+    // se fait par l'envoie de petit fichier xml
+    // d'oÃ¹ le cÃŽtÃ© complexe des commandes
+
     try
     {
         *client_socket << "<newNumberVector device=\"BAO\" name=\"GEOGRAPHIC_COORD\">";
         *client_socket << "<oneNumber name=\"LAT\">";
-        *client_socket << Latitude;
+        *client_socket << LatitudeChar;
         *client_socket << "</oneNumber>";
         *client_socket << "<oneNumber name=\"LONG\">";
-        *client_socket << Longitude;
+        *client_socket << LongitudeChar;
         *client_socket << "</oneNumber>";
         *client_socket << "</newNumberVector>";
@@ -475,5 +810,5 @@
         if (!VerifReponse("name=\"GEOGRAPHIC_COORD\" state=\"Ok\""))
         {
-            Erreur("ERREUR fct EncoyerCoordGeographiques : pas de rÃ©ponse du pilote indi_BAO.\n\n");
+            Erreur("ERREUR fct EnvoyerCoordGeographiques : pas de rÃ©ponse du pilote indi_BAO.\n\n");
 
             return false;
@@ -481,12 +816,13 @@
     }
 
+    // un problÃšme ?
+
     catch ( SocketException& e )
     {
-        os << "Exception was caught:" << e.description() << std::endl;
-        Erreur(os.str());
+        Erreur("Exception was caught:" + e.description() + "\n");
         return false;
     }
 
-    std::cout << "Les coordonnÃ©es gÃ©ographiques ont bien Ã©tÃ© envoyÃ©es au pilote indi_BAO"  << std::endl << std::endl;
+    Affiche("Les coordonnÃ©es gÃ©ographiques ont bien Ã©tÃ© envoyÃ©es au pilote indi_BAO\n\n", true);
 
     return true;
@@ -494,6 +830,10 @@
 
 
-/* Place les antennes en position de repos */
-bool Park()
+
+/**************************************************************************************
+** Place les antennes en position de repos
+***************************************************************************************/
+
+bool BAOcontrol::Park()
 {
     try
@@ -505,5 +845,5 @@
         *client_socket << "</newSwitchVector>";
 
-        if (!VerifReponse("Envoi de la commande Park"))
+        if (!VerifReponse("PARK OK"))
         {
             Erreur("La commande PARK a Ã©chouÃ©.\n\n");;
@@ -514,6 +854,5 @@
     catch ( SocketException& e)
     {
-        os << e.description() << "\n";
-	Erreur(os.str());
+        Erreur("Exception was caught:" + e.description() + "\n");
         return false;
     }
@@ -525,6 +864,10 @@
 
 
-/* Annule le mouvement en cours */
-bool Abort()
+
+/**************************************************************************************
+** Annule le mouvement en cours
+***************************************************************************************/
+
+bool BAOcontrol::Abort()
 {
     try
@@ -536,5 +879,5 @@
         *client_socket << "</newSwitchVector>";
 
-        if (!VerifReponse("name=\"ABORT_MOTION\" state=\"Ok\""))
+        if (!VerifReponse("ABORT OK"))
         {
             Erreur("L'annulation a Ã©chouÃ©.\n\n");
@@ -545,6 +888,5 @@
     catch ( SocketException& e)
     {
-        os << e.description() << "\n";
-	Erreur(os.str());
+        Erreur("Exception was caught:" + e.description() + "\n");
         return false;
     }
@@ -555,7 +897,76 @@
 }
 
-/*aller aux coordonnÃ©es ar et dec dans le mode transit ou tracking */
-bool Goto(std::string ar, std::string dec, bool Transit)
-{
+
+
+/**************************************************************************************
+** Diriger l'antenne vers les coordonnÃ©es ar et dec et suivre l'objet
+** en activant le mode transit ou tracking.
+** si J2000 == true, cela signifie que les coordonnÃ©es ar et dec sont donnÃ©es dans le
+** le systÃšme de coordonnÃ©es J2000 (Ã©cliptique et Ã©quinoxe du 1 janvier 2000 Ã  0 h TU)
+** Des calculs supplÃ©mentaires (prÃ©cession, nutation, abÃ©rration) sont alors nÃ©cessaires
+***************************************************************************************/
+
+bool BAOcontrol::Goto(string ar, string dec, bool Transit, bool J2000)
+{
+    float  ar1, ar2, ar3;
+    float  dec1, dec2, dec3;
+    double arf, decf;
+    double azi, hau;
+
+
+     /*
+     //Pour les tests
+     ar="05:39:14.8";
+     dec="23:19:24.1";
+     printf("JJ=%10.10f\n", GetJJ());
+     J2000=true;
+     */
+
+    // Conversion de l'AD et de la dÃ©clinaison en radians
+
+    Decomposition(ar, 2, &ar1, &ar2, &ar3);
+    Decomposition(dec, 0, &dec1, &dec2, &dec3);
+    
+    arf  = ( ar1  + ar2 / 60.0  + ar3 / 3600.0 ) * 15.0 * Pidiv180;
+    decf = ( fabs(dec1) + dec2 / 60.0 + dec3 / 3600.0 ) * Pidiv180;
+
+    if (dec[0]=='-') decf = -decf;
+
+    // calculs pupplÃ©mentaires pour se ramener
+    // Ã  l'Ã©poque de l'observation
+
+    if (J2000)
+    {
+        Precession(&arf, &decf);
+        NutationEtoile(&arf, &decf);
+        AberrationAnnuelle(&arf, &decf);
+    }
+
+    // on rÃ©Ã©crit l'ar et la dec dans le format d'indi_BAO
+
+    ar  = DHMS(arf * N180divPi, true);
+
+    dec = DHMS(decf * N180divPi, false);
+
+    // on en informe l'utilisateur
+
+    Affiche("CoordonnÃ©es apparentes de l'objet :\n", true);
+
+    Affiche("AD=" + ar  + "   Dec=" + dec +"\n", true);
+
+   
+    /*
+    //Tests
+    Azimut(arf, decf, &azi, &hau);
+
+    hau=RefractionAtmospherique(hau);
+
+    Affiche("CoordonnÃ©es rectangulaires liÃ©es au lieu d'observation :\n", true);
+
+    printf("Azimut = %s   Hauteur = %s\n", DHMS(azi*N180divPi,false).c_str(), DHMS(hau*N180divPi, false).c_str());
+    */
+
+    // On transmet les coordonnÃ©es au pilote BAO
+
     try
     {
@@ -597,18 +1008,20 @@
     catch ( SocketException& e)
     {
-        os << e.description() << "\n";
-	Erreur(os.str());
+        Erreur("Exception was caught:" + e.description() + "\n");
         return false;
     }
 
-    os << "Les nouvelles coordonnÃ©es AD=" << ar << "  DEC=" << dec << " ont Ã©tÃ© envoyÃ©es au pilote indi_BAO.\n\n";
-    Affiche(os.str(), true);
-
+    Affiche("Les nouvelles coordonnÃ©es AD=" + ar + " Dec=" + dec, true);
+    Affiche(" ont Ã©tÃ© envoyÃ©es au pilote indi_BAO.\n\n", true);
     return true;
 }
 
 
-/*se connecter ou se dÃ©connecter au pilote indi_BAO */
-bool Connect(bool connect)
+
+/**************************************************************************************
+** Se connecte ou se dÃ©connecte au pilote indi_BAO
+***************************************************************************************/
+
+bool BAOcontrol::Connect(bool connect)
 {
     try
@@ -645,6 +1058,5 @@
     catch ( SocketException& e )
     {
-        os << "Exception was caught:" << e.description() << std::endl;
-        Erreur(os.str());
+        Erreur("Exception was caught:" + e.description() + "\n");
         return false;
     }
@@ -654,9 +1066,9 @@
         Affiche("La connexion a Ã©tÃ© Ã©tablie avec le pilote indi_BAO.\n\n", true);
 
-        EncoyerCoordGeographiques();
+        EnvoyerCoordGeographiques();
     }
     else
     {
-        Affiche("Confirmation de la dÃ©connexion avec le pilote indi_BAO.\n\n", true);
+        Affiche("BAOcontrol s'est bien dÃ©connectÃ© du pilote indi_BAO.\n\n", true);
     }
 
@@ -665,180 +1077,241 @@
 
 
-/* Lecture des mouvements planifiÃ©s dans le fichier fileName */
-bool LectureFichierMouvements(char * fileName)
-{
-    char * section =(char * )malloc(80);
-    char * key = (char *)malloc(80);
-    char * chaine = (char *)malloc(80);
-    char * value;
-    
-    Astro * AstroJJ;
-    
+
+/**************************************************************************************
+** Lecture des mouvements planifiÃ©s contenus dans le fichier fileName
+***************************************************************************************/
+
+bool BAOcontrol::LectureFichierMouvements(string fileName)
+{
+    string section;
+    string key;
+    char * value   = NULL;
+
+    stringstream os;
     float a1, a2, a3, h;
 
     numobjets=1;
 
-    os << "Lecture du fichier " << fileName << std::endl << std::endl;
-    Affiche(os.str(), true);
-
-    strcpy(section, "objet 1");
-    strcpy(key, "date");
-
-    while ((readINI(section, key, &value, fileName)) && (numobjets<MAXOBJETS))
-    {
-        os << "object nÂ°" << numobjets << std::endl;
-	Affiche(os.str(), true);
-
-        strcpy(key, "date");
-
-        if ((readINI(section, key, &value, fileName)) && (Decomposition(value, 3, &a1, &a2, &a3)))
-        {
-            os << "Date du dÃ©but de l'observation : le " << value;
-	    Affiche(os.str(), true);
-
-	    AstroJJ = new Astro();
-	    
-            AstroJJ->Jour=a1;
-            AstroJJ->Mois=a2;
-            AstroJJ->Annee=a3;
-
-            AstroJJ->CalculJJ(0.0);
-
-            objets[numobjets].JJ=AstroJJ->JJ;
-	    
-	    delete AstroJJ;
+    Affiche("Lecture du fichier " + fileName +"\n\n", true);
+
+    //Lecture de la rubrique ParamÃštres
+
+    section = "parametres";
+    key     = "mode";
+
+    if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
+    {
+        Transit = ( strstr(value, "transit") != NULL);
+        delete [] value;
+
+        if (Transit) Affiche("Mode transit activÃ©.\n", true);
+        else Affiche("Mode tracking activÃ©.\n", true);
+    }
+    else
+    {
+        Erreur("Le parametre mode est incorrect.\n");
+        return false;
+    }
+
+    key = "J2000";
+
+    if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
+    {
+        J2000 = ( strstr(value, "on") != NULL);
+        delete [] value;
+
+        if (J2000) Affiche("Mode J2000 activÃ©.\n\n", true);
+        else Affiche("Mode J2000 dÃ©sactivÃ©.\n\n", true);
+    }
+    else
+    {
+        Erreur("Le parametre J2000 est incorrect.\n");
+        return false;
+    }
+
+    // Lecture de la liste des observations
+
+    section = "objet 1";
+    key     = "date";
+
+
+    while ((readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
+            && (numobjets<MAXOBJETS))
+    {
+        os << "object nÂ°" << numobjets << endl;
+        Affiche(&os, true);
+        delete [] value;
+        value = NULL;
+
+
+        // Lecture de la date et de l'heure de l'observation
+
+        key = "date";
+
+        if ((readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
+                && (Decomposition(value, 3, &a1, &a2, &a3)))
+        {
+            Affiche("Date du dÃ©but de l'observation : le " + (string)value, true);
+            delete [] value;
+            value = NULL;
+
+            objets[numobjets].JJ = CalculJJ(a3, a2, a1, 0.0);
         }
         else
         {
-            os << "La date de la rubrique [objet " << numobjets << "] est incorrecte !" << std::endl;
-	    Erreur(os.str());	    
+            os << "La date de la rubrique [objet " << numobjets << "] est incorrecte !" << endl;
+            Erreur(&os);
             return false;
         }
 
-        strcpy(key, "heure");
-
-        if ((readINI(section, key, &value, fileName)) && (Decomposition(value, 2, &a1, &a2, &a3)))
-        {
-            os << " Ã  " <<  value ;
-	    Affiche(os.str(), true);
-
-            objets[numobjets].JJ+=(a1+a2/60.0+a3/3600.0)/24.0;
-	    
-	    sprintf(chaine, " TU  -> JJ=%10.5f\n", objets[numobjets].JJ);
-	    
-	    Affiche(chaine, true);
-	    
-	    for (int i=1; i<numobjets; i++)
-	    {
-	      if (objets[i].JJ==objets[numobjets].JJ)
-	      {
-		os << "Attention, les observations des objets " << i << " et " << numobjets << " sont dÃ©finies Ã  la mÃªme date !\n";
-		Erreur(os.str());
-	      }
-	      
-	      if (objets[i].JJ+objets[i].Duree/3600/24.0>objets[numobjets].JJ)
-	      {
-		os << "Attention, les observations des objets " << i << " et " << numobjets << " se chevauchent !\n";
-		Erreur(os.str());
-	      }
-	    }
+        key = "heure";
+
+        if ((readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
+                && (Decomposition(value, 2, &a1, &a2, &a3)))
+        {
+            Affiche(" Ã  " + (string)value, true) ;
+            delete [] value;
+            value = NULL;
+
+
+            objets[numobjets].JJ += ( a1 + a2 / 60.0 + a3 / 3600.0 ) / 24.0;
+
+            os << " TU  -> JJ=" << fixed << objets[numobjets].JJ << scientific << endl;
+
+            Affiche(&os, true);
+
+            for (int i=1; i<numobjets; i++)
+            {
+                if (objets[i].JJ==objets[numobjets].JJ)
+                {
+                    os << "Attention, les observations des objets " << i << " et ";
+                    os << numobjets << " sont dÃ©finies Ã  la mÃªme date !" << endl;
+                    Erreur(&os);
+                }
+
+                if (objets[i].JJ+objets[i].Duree/3600/24.0>objets[numobjets].JJ)
+                {
+                    os << "Attention, les observations des objets " << i << " et " ;
+                    os << numobjets << " se chevauchent !" << endl;
+                    Erreur(&os);
+                }
+            }
         }
         else
         {
-            os << "L'heure de la rubrique [objet " << numobjets << "] est incorrecte !" << std::endl;
-	    Erreur(os.str());
+            os << "L'heure de la rubrique [objet " << numobjets << "] est incorrecte !" << endl;
+            Erreur(&os);
             return false;
         }
 
 
-
-
-        strcpy(key, "duree");
+        // Lecture de la durÃ©e de l'observation
+
+        key = "duree";
 
         objets[numobjets].Duree=0.0;
 
-        if (readINI(section, key, &value, fileName))
-        {
-           os << "DurÃ©e de l'observation : " << value << " secondes" << std::endl;
-	   Affiche(os.str(), true);
-
-           objets[numobjets].Duree=atof(value);
+        if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
+        {
+            Affiche("DurÃ©e de l'observation : " + (string)value + " secondes\n", true);
+            objets[numobjets].Duree=atof(value);
+            delete [] value;
+            value = NULL;
         }
         else
         {
-            os << "La duree d'observation de la rubrique [objet " << numobjets << "] est incorrecte !" << std::endl;
-	    Erreur(os.str());
+            os << "La duree d'observation de la rubrique [objet " << numobjets << "] est incorrecte !\n";
+            Erreur(&os);
             return false;
         }
 
-
-        strcpy(key, "ad");
-
-        strcpy(objets[numobjets].ad, "");
-
-        if ((readINI(section, key, &value, fileName)) && (Decomposition(value, 2, NULL, NULL, NULL)))
-        {
-            os << "Ascension droite de l'objet : " << value << std::endl;
-	    Affiche(os.str(), true);
-	    
-            strcpy(objets[numobjets].ad, value);
+        // Lecture de l'ascension droite de l'objet
+
+        key = "ad";
+
+        objets[numobjets].ad = "";
+
+        if ((readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
+                && (Decomposition(value, 2, NULL, NULL, NULL)))
+        {
+            Affiche("Ascension droite de l'objet : " + (string)value + "\n", true);
+            objets[numobjets].ad = value;
+            delete [] value;
+            value = NULL;
         }
         else
         {
-            os << "L'ascension droite de la rubrique [objet " << numobjets << "] est incorrecte !" << std::endl;
-	    Erreur(os.str());
+            os << "L'ascension droite de la rubrique [objet " << numobjets << "] est incorrecte !";
+            os << endl;
+            Erreur(&os);
             return false;
         }
 
-
-        strcpy(key, "de");
-
-        strcpy(objets[numobjets].de, "");
-
-        if ((readINI(section, key, &value, fileName)) && (Decomposition(value, 0, NULL, NULL, NULL)))
-        {
-            os << "DÃ©clinaison de l'objet : " << value << std::endl << std::endl;
-	    Affiche(os.str(), true);
-
-            strcpy(objets[numobjets].de, value);
+        // Lecture de la dÃ©clinaison de l'objet
+
+        key = "de";
+
+        objets[numobjets].de = "";
+
+        if ((readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
+                && (Decomposition(value, 0, NULL, NULL, NULL)))
+        {
+            Affiche("DÃ©clinaison de l'objet : " + (string)value + "\n\n", true);
+            objets[numobjets].de = value;
+            delete [] value;
+            value = NULL;
         }
         else
         {
-            os << "La dÃ©clinaison de la rubrique [objet " << numobjets << "] est incorrecte !" << std::endl;
-	    Erreur(os.str());
+            os << "La dÃ©clinaison de la rubrique [objet " << numobjets << "] est incorrecte !";
+            os << endl;
+            Erreur(&os);
             return false;
         }
 
-        objets[numobjets].exec=false;
+        objets[numobjets].exec = false;
+
+        // On passe Ã  l'objet suivant
 
         numobjets++;
 
-        sprintf(section, "objet %i", numobjets);
-
-    }
-    
+        os << "objet "<< numobjets;
+
+        section = os.str();
+        os.str("");
+    }
+
+    if (value) delete [] value;
 
     return true;
 }
 
-/*Execute le fichier de mouvements */
-bool Run(std::string fichier)
-{
-    bool exec=LectureFichierMouvements((char *)fichier.c_str());
-
-    CalculJourJulien();
-
-    if (exec && numobjets>1)
-    {
-        if (objets[numobjets-1].JJ+objets[numobjets-1].Duree/3600.0/24.0 < astro->JJ)
+
+
+/**************************************************************************************
+** Execute le fichier de mouvements
+***************************************************************************************/
+
+bool BAOcontrol::Run(string fichier)
+{
+    stringstream os;
+
+    bool exec = LectureFichierMouvements(fichier);
+
+    Update();
+
+    if ( exec && numobjets>1 )
+    {
+        // Si le chargement du fichier s'est bien dÃ©roulÃ© et qu'il y a plus d'un mouvement dedans
+
+        if (objets[numobjets-1].JJ + objets[numobjets-1].Duree / 3600.0 / 24.0 < GetJJ())
         {
             Erreur("Le fichier contient des dates qui sont toutes pÃ©rimÃ©es. ExÃ©cution annulÃ©e.\n\n");
-            if (exitrun) NoExit=false;
+            NoExit=!exitrun;
             return false;
         }
         else
         {
-            os << "Execution du fichier " << fichier << " en attente..." << std::endl << std::endl;
-            Affiche(os.str(), true);
+            Affiche("Execution du fichier " + fichier + " en attente...\n\n", true);
             run=true;
         }
@@ -846,7 +1319,6 @@
     else
     {
-        os << std::endl << "Le fichier " << fichier << " contient des erreurs ou n'existe pas...\n" << std::endl << std::endl;
-        Erreur(os.str());
-	if (exitrun) NoExit=false;
+        Erreur("\nLe fichier " + fichier + " contient des erreurs ou n'existe pas...\n\n\n");
+        NoExit=!exitrun;
         return false;
     }
@@ -856,30 +1328,168 @@
 
 
-/*identification des commandes entrÃ©es par l'utilisateur */
-void DecodageEntreesUtilisateur(std::string chaine)
-{
-    std::string ar, de, fichier;
-
-
-    if (chaine.find("goto")!=string::npos)
-    {
+
+/**************************************************************************************
+** DÃ©composition et vÃ©rification des dates, heures, AD et dÃ©clinaisons
+**
+** type = 0 -> DÃ©clinaison/latitude
+** type = 1 -> longitude
+** type = 2 -> AD ou heure
+** type = 3 -> date
+**
+** Exemple de Decomposition("15:23:12", 2, a, b, c) retourne a=15, b=23, c=12
+** si la chaine a un format incorrect, la fct retourne false
+***************************************************************************************/
+
+bool BAOcontrol::Decomposition(string chaine, char type, float *a1, float *a2, float *a3)
+{
+    string car, s;
+    float a, b, c;
+
+    // pour les heures et les coordonnÃ©es, on attend ":" comme caractÃšre sÃ©parateur, sinon
+    // on attend d'avoir des "/" pour une date
+
+    (type==3) ? car="/" : car=":";
+
+    // Y a-t-il 2 caractÃšres ':' ou '/' dans la chaine ?
+    // C'est indispensable dans tous les cas
+
+    int test=0;
+    for (int i=0; i<chaine.length(); i++) if (chaine[i] == car[0]) test++;
+    if (test<2) return false;
+
+    // Extraction des trois nombres
+
+    s = chaine.substr(0, chaine.find(car));
+
+    a = atoi(s.c_str());
+
+    s = chaine.substr(chaine.find(car)+1, chaine.rfind(car) - chaine.find(car) - 1);
+
+    b = atoi(s.c_str());
+
+    s = chaine.substr(chaine.rfind(car)+1);
+
+    c = Arrondi(atof(s.c_str())*100.0)/100.0;
+
+    //vÃ©rification de la cohÃ©rence des infos contenues dans la chaine
+
+    if (type < 3 )
+    {
+        // pour une dÃ©clinaison
+        if ((type==0) && (a>90.0  || a<-90.0)) return false;
+        // pour une AD
+        if ((type==1) && (a>360.0 || a<0.0  )) return false;
+        // pour une heure
+        if ((type==2) && (a>23.0  || a<0.0  )) return false;
+        // pour les minutes
+        if (b<0.0 || b>59.0 ) return false;
+        //pour les secondes
+        if (c<0.0 || c>=60.0) return false;
+    }
+    else
+    {
+        //pour les jours
+        if (a<0.0 || a>31.0) return false;
+        //pour les mois
+        if (b<0.0 || b>12.0) return false;
+    }
+
+    if (a1!=NULL) *a1 = a;
+    if (a2!=NULL) *a2 = b;
+    if (a3!=NULL) *a3 = c;
+
+    return true;
+}
+
+
+
+
+/**************************************************************************************
+** identification des commandes entrÃ©es par l'utilisateur
+** puis exÃ©cution des commandes
+***************************************************************************************/
+
+void BAOcontrol::DecodageEntreesUtilisateur(string chaine)
+{
+    string ar, de, objet, fichier;
+    stringstream os;
+
+    // Permet de savoir si la derniÃšre saisie de l'utilisateur
+    // est une commande valide
+    bool CommandeOK = false;
+
+
+    // Commande goto
+
+    if ( chaine.find("goto") != string::npos )
+    {
+        CommandeOK = true;
+
+        // L'utilisateur a fait suivre la commande goto de l'indication J2000
+
+        if (J2000 = (chaine.find("j2000") != string::npos))
+        {
+            Affiche("Prise en compte de la prÃ©cession, de la nutation et de l'aberration...\n", true);
+
+            // On je garde que la premiÃšre partie de la chaine avant J2000
+
+            chaine = chaine.substr(0, chaine.find("J2000"));
+        }
+
         if (DecompositionCommande(chaine, "goto", &ar, &de) && Decomposition(ar, 2, NULL, NULL, NULL) && Decomposition(de, 0, NULL, NULL, NULL))
         {
-            Goto(ar, de, Transit);
+            // L'utilisateur a indiquÃ© deux coordonnÃ©es valides -> on exÃ©cute le goto
+
+            Goto(ar, de, Transit, J2000);
         }
         else
         {
-            Erreur("Erreur goto : le format de la commande est goto AD DEC\n \
+            // L'utilisateur a indiquÃ© un nom d'objet aprÃšs le goto -> on lance la recherche sur internet
+            // puis on envoie les coordonnÃ©es de l'objet au pilote indi_BAO
+
+            if ((DecompositionCommande(chaine, "goto", &objet, NULL)) && (chaine.find(":") == string::npos))
+            {
+                Coordonnees reponse;
+		
+		if (objet != "sun")
+		{
+		    reponse = ServeurNED(objet);
+		    
+		    if (reponse.ar!="" && reponse.dec!="")  Goto(reponse.ar, reponse.dec, Transit, true);
+		}
+		else
+		{   
+		    printf(" lancement\n");
+		   
+		    CalculARDecSoleil(&reponse);
+		    
+		    printf("%s   %s \n", reponse.ar.c_str(), reponse.dec.c_str());
+		    
+		    Goto(reponse.ar, reponse.dec, Transit, false);
+		}                
+            }
+            else
+            {
+                Erreur("Erreur goto : le format de la commande est goto AD DEC\n \
                     L AD doit Ãªtre de la forme xx:yy:zz   (ex: 12:00:03 pour 12h 0m 3s)\n \
-                    La dÃ©clinaison doit Ãªtre de la forme +/-xx:yy:zz (ex: -12:50:01 pour -12Â° 50' 01'')\n\n");
-        }
-    }
-    
-    
-    if (chaine.find("abort")!=string::npos)
-    {
+                    La dÃ©clinaison doit Ãªtre de la forme +/-xx:yy:zz (ex: -12:50:01 pour -12Â° 50' 01'')\n\n \
+                    Il est egalement possible de faire suivre la commande d'un nom d'un objet\n \
+                    Exemple goto M 31 ou encore goto ngc145\n \
+                    Ne pas prÃ©ciser dans ce cas J2000.\n\n");
+            }
+        }
+    }
+
+    // Annulation du suivi en cours
+
+    if (chaine.find("abort") != string::npos)
+    {
+        CommandeOK = true;
+
         Abort();
 
-        if (chaine.find("run")!=string::npos)
+        // Annulation de l'exÃ©cution d'un fichier de mouvements
+
+        if (chaine.find("run") != string::npos)
         {
             run=false;
@@ -888,12 +1498,15 @@
 
             Affiche("Annulation de l'exÃ©cution du fichier de mouvements.\n\n", true);
-	    
-	    return;
-        }
-    }
-    
-
-    if (chaine.find("run")!=string::npos)
-    {
+
+            return;
+        }
+    }
+
+    // Lance l'exÃ©cution d'un fichier de mouvements
+
+    if (chaine.find("run") != string::npos)
+    {
+        CommandeOK = true;
+
         if (DecompositionCommande(chaine, "run", &fichier, NULL))
         {
@@ -905,179 +1518,532 @@
         }
     }
-    
-
-    if (chaine.find("connect")!=string::npos)
-    {
-        Connect(chaine.find("disconnect")==string::npos);
-    }
-        
-
-    if (chaine.find("transit")!=string::npos)
-    {
+
+    // se connecte/dÃ©connecte au serveur
+
+    if (chaine.find("connect") != string::npos)
+    {
+        CommandeOK = true;
+
+        Connect(chaine.find("disconnect") == string::npos);
+    }
+
+    // Active le mode de suivi "transit"
+
+    if (chaine.find("transit") != string::npos)
+    {
+        CommandeOK = true;
+
         Affiche("Mode transit activÃ©.\n\n", true);
 
         Transit=true;
     }
-    
-
-    if (chaine.find("tracking")!=string::npos)
-    {
+
+    // Active le mode de suivi "tracking"
+
+    if (chaine.find("tracking") != string::npos)
+    {
+        CommandeOK = true;
+
         Affiche("Mode tracking activÃ©.\n\n", true);
 
         Transit=false;
     }
-    
-
-    if (chaine.find("park")!=string::npos)
-    {
+
+    // Place les antennes en position de repos
+
+    if (chaine.find("park") != string::npos)
+    {
+        CommandeOK = true;
+
         Park();
     }
-    
-
-   
-    
-
-    if (chaine.find("help")!=string::npos)
-    {
-        std::cout << std::endl;
-
-        std::cout << "connect : connecte le pilote INDI" << std::endl;
-        std::cout << "disconnect : ferme la connexion avec le pilote INDI" << std::endl;
-        std::cout << "goto AD Dec : pointe l'objet aux coordonnÃ©es AD Dec" << std::endl;
-        std::cout << "transit : mode de suivi transit" << std::endl;
-        std::cout << "tracking : mode de suivi tracking" << std::endl;
-        std::cout << "run filename : execute le fichier filename" << std::endl;
-        std::cout << "abort run : annule l'exÃ©cution du fichier de mouvements" << std::endl;
-        std::cout << "abort : annule le mouvement en cours" << std::endl;
-        std::cout << "park : place les antennes en position de repos" << std::endl;
-        std::cout << "exit : sortir de BAOControl" << std::endl;
-
-        std::cout << std::endl;
-    }
-    
+
+    // interroge un serveur de temps pour mettre l'horloge du PC Ã  jour
+
+    if (chaine.find("updatetime") != string::npos)
+    {
+        CommandeOK = true;
+
+        int rc = system("sntp -s fr.pool.ntp.org");
+
+        if (WEXITSTATUS(rc) ==-1 || WEXITSTATUS(rc) ==127)
+        {
+            Erreur("La commande sntp n'est pas accessible. Merci de vÃ©rifier.\n\n");
+        }
+    }
+
+    // Affiche tous les paramÃštres du programme
+
+    if (chaine.find("status") != string::npos)
+    {
+        CommandeOK = true;
+
+        os << "Latitude = " << (string)LatitudeChar << "\n";
+        os << "Longitude = " << (string)LongitudeChar << "\n\n";
+        os << "Serveur Indi = " << (string)Serveur << "\n";
+        os << "Port du serveur Indi = " << Port << "\n\n";
+        os << "Pression atmosphÃ©rique  = " << Pression << " mBar\n";
+        os << "TempÃ©rature = " << Temperature << " Â°C\n\n";
+        Affiche(&os, true);
+        if (Transit) Affiche("Mode Transit activÃ©.\n\n", true);
+        else Affiche ("Mode Tracking activÃ©.\n\n", true);
+    }
+
+    // interroge le serveur NED sur internet -> retourne les coordonnÃ©es de l'objet
+
+    if (chaine.find("search")!=string::npos)
+    {
+        string objet;
+
+        CommandeOK = true;
+
+        if (DecompositionCommande(chaine, "search", &objet, NULL))
+        {
+            ServeurNED(objet);
+        }
+    }
+
+    // Aide du programme
+
+    if (chaine.find("help") != string::npos)
+    {
+        CommandeOK = true;
+
+        cout << endl;
+
+        cout << "connect :           se connecte au pilote indi_BAO." << endl;
+        cout << "disconnect :        se dÃ©connecte du pilote indi_BAO." << endl;
+        cout << "goto AD Dec :       pointe l'objet situÃ© aux coordonnÃ©es apparentes AD Dec." << endl;
+        cout << "                    AD doit Ãªtre au format xx:yy:zz et dec au format +/-xx:yy:zz" << endl;
+        cout << "                    exemple goto 12:10:05 -05:10:11 permettra de pointer l'objet" << endl;
+        cout << "                    situÃ© aux coordonnÃ©es AD=12h10m5s et dec=-5Â°10'11''" << endl;
+        cout << "goto AD Dec J2000 : pointe l'objet situÃ© aux coordonnÃ©es AD Dec dans le repÃšre J2000." << endl;
+        cout << "                    Avant de pointer l'objet, le programme calcule la prÃ©cession, la nutation et l'aberration" << endl;
+        cout << "                    pour ramener les coordonnÃ©es Ã  l'Ã©cliptique et Ã  l'Ã©quinoxe de l'observation." << endl;
+        cout << "goto nom_objet :    interroge la base NED pour trouver les coordonnÃ©es de l'objet puis le pointe." << endl;
+        cout << "                    exemples: goto m 31, goto messier 1, goto ngc 175, goto ic 434 etc..." << endl;
+        cout << "                    Dans ce mode, les coordonnÃ©es sont automatiquement rapportÃ©es" << endl;
+        cout << "                    Ã  l'Ã©cliptique et Ã  l'Ã©quinoxe de l'observation." << endl;
+        cout << "                    Aussi, merci de ne pas faire suivre les coordonnÃ©es de l'indication J2000."<< endl;
+        cout << "                    Goto sun permet de suivre le soleil." << endl;
+        cout << "search nom_objet :  interroge le serveur NED sur internet et retourne les coordonnÃ©es de l'objet." << endl;
+        cout << "transit :           active le mode de suivi transit." << endl;
+        cout << "tracking :          active le mode de suivi tracking." << endl;
+        cout << "status :            liste les paramÃštres du programme." << endl;
+        cout << "run filename :      exÃ©cute le fichier de mouvements filename." << endl;
+        cout << "abort run :         annule l'exÃ©cution du fichier de mouvements." << endl;
+        cout << "abort :             annule le mouvement en cours." << endl;
+        cout << "park :              place les antennes en position de repos." << endl;
+        cout << "updatetime :        synchronise l'horloge du PC avec un serveur de temps." << endl;
+        cout << "exit :              sortir de BAOControl." << endl;
+
+        cout << endl;
+    }
+
+    // Bye !
 
     if (chaine.find("exit")!=string::npos)
     {
-        Connect (false);
-
-        NoExit=false;
-    }
-}
-
-
-/* chargement des paramÃštres dans le fichier params */
-bool ChargementParametres()
-{
-    char * section =(char * )malloc(80);
-    char * key = (char *)malloc(80);
+        CommandeOK = true;
+
+        Abort();
+
+        Connect(false);
+
+        NoExit = false;
+    }
+
+    // La commande n'a pas Ã©tÃ© identifiÃ©e !
+
+    if (!CommandeOK) Erreur("Commande inconnue... Tapez help pour obtenir la liste des commandes disponibles.\n\n");
+}
+
+
+/**************************************************************************************
+** Interroge le serveur NED sur internet et retourne les coordonnÃ©es dans le repÃšre J2000
+** Si pas de rÃ©ponse, alors message d'erreur et les coordonnÃ©es sont Ã©gales Ã  AR="" dec=""
+***************************************************************************************/
+
+Coordonnees BAOcontrol::ServeurNED(string objet)
+{
+    Coordonnees reponse;
+    stringstream send;
+
+    FILE *pFile = NULL;
+    int rc;
+
+    //initialsation des variables de retour
+
+    reponse.ar = "";
+    reponse.dec = "";
+
+    // le nom de l'objet ne doit pas contenir des espace pour la requÃªte NED
+    // on les remplace par des '+'
+
+    for (int i=0; i<objet.length(); i++) if (objet[i] == ' ') objet[i]='+';
+
+    // Effacer le fichier result s'il existe dans le rÃ©pertoire du programme
+
+    if ((pFile = fopen ("result", "r")) != NULL )
+    {
+        fclose (pFile);
+        rc = system( "rm result");
+    }
+
+    // On utilise l'utilitaire curl pour passer la requÃªte au serveur NED
+    // On sauvegarde le rÃ©sultat dans le fichier result
+
+    send << "curl >> result \"http://ned.ipac.caltech.edu/cgi-bin/nph-objsearch?objname=";
+    send << objet;
+    send << "&extend=no&hconst=73&omegam=0.27&omegav=0.73&corr_z=1&out_csys=Equatorial&out_equinox=J2000.0";
+    send << "&obj_sort=RA+or+Longitude&of=ascii_bar&zv_breaker=30000.0&list_limit=5&img_stamp=NO\"";
+
+    Affiche("Envoi de la requÃªte au serveur NED...\n", true);
+
+    // on lance la requÃªte
+
+    rc = system(send.str().c_str() );
+
+    // traitement du rÃ©sultat
+
+    if (WEXITSTATUS(rc) ==-1 || WEXITSTATUS(rc) ==127)
+    {
+        Erreur("La commande curl n'est pas accessible. Merci de vÃ©rifier.\n\n");
+    }
+    else
+    {
+        // On a obtenu quelque chose
+
+        int nbRead = 0;
+
+        char *pBuf;
+
+        pBuf = new char [100000];
+
+        // On laisse un peu de temps au serveur pour rÃ©pondre.
+        // C'est pas vraiment indispensable mais bon...
+
+        sleep(1);
+
+        // On ouvre le fichier result
+
+        pFile = fopen ("result", "r");
+
+        if (pFile)
+        {
+            nbRead = readline (pFile, pBuf);
+
+            // Si le fichier n'est pas vide
+            if (nbRead!=-1)
+            {
+                if (strstr(pBuf, "Error") != NULL)
+                {
+                    // Le fichier contient une indication d'erreur -> pas de rÃ©ponse exploitable
+
+                    Affiche("\nLe serveur NED n'a pas trouvÃ© de rÃ©ponse Ã  votre demande...\n", true);
+                }
+                else
+                {
+                    // on analyse la rÃ©ponse
+
+                    Affiche("\nRÃ©ponse du serveur :\n", true);
+
+                    do
+                    {
+                        // on cherche la premiÃšre suggestion de NED
+                        // Il faudra peut-Ãªtre un peu complexifier par la suite
+
+                        if (pBuf[0] == '1')
+                        {
+                            string chaine = (string)pBuf;
+                            string chaine2;
+
+                            chaine=chaine.substr(chaine.find('|')+1);
+
+                            // affiche le nom de l'objet dans le serveur NED
+
+                            Affiche(chaine.substr(0, chaine.find('|')) + "\n", true);
+
+                            chaine = chaine.substr(chaine.find('|') + 1);
+
+                            chaine2 = chaine.substr(0, chaine.find('|'));
+
+                            double ar = atof(chaine2.c_str());
+
+                            // affiche l'ascension droite
+
+                            Affiche("AD (J2000) = " + DHMS(ar, true) + "\n", true);
+
+                            reponse.ar = DHMS(ar, true);
+
+                            chaine=chaine.substr(chaine.find('|')+1);
+
+                            chaine2 = chaine.substr(0, chaine.find('|'));
+
+                            double dec = atof(chaine2.c_str());
+
+                            // on affiche la dÃ©clinaison
+
+                            Affiche("Dec (J2000) = " + DHMS(dec, false)+"\n", true);
+
+                            reponse.dec = DHMS(dec, false);
+                        }
+
+                        nbRead = readline (pFile, pBuf);
+
+                    } while (nbRead!=-1);
+                }
+            }
+            else
+            {
+                Erreur("\nLa connexion semble impossible avec le serveur NED !\n\n");
+            }
+
+            fclose(pFile);
+        }
+        else
+        {
+            Erreur("\nLa connexion semble impossible avec le serveur NED !\n\n");
+        }
+
+        delete [] pBuf;
+
+        Affiche("\n", true);
+    }
+
+    return reponse;
+}
+
+
+
+/**************************************************************************************
+** Lecteur d'un fichier ligne aprÃšs ligne
+** retourne -1 Ã  la fin
+***************************************************************************************/
+
+int BAOcontrol::readline (FILE * pfile, char *tab)
+{
+    int nbchar = 0;
+    char c;
+
+    while ((c = getc (pfile)) != '\n')
+    {
+        if (c == EOF)
+        {
+            break;
+        }
+        tab[nbchar++] = c;
+    }
+    tab[nbchar] = '\0';
+
+    while (nbchar>0 && tab[nbchar-1]==' ')
+    {
+        tab[--nbchar] = '\0';
+    }
+
+    while (tab[0]==' ') for (int i=1; i<=nbchar; i++) tab[i-1] = tab[i];
+
+    if (c == EOF) nbchar=-1;
+
+    return (nbchar);
+}
+
+
+
+/**************************************************************************************
+** chargement des paramÃštres contenus dans le fichier params
+***************************************************************************************/
+
+bool BAOcontrol::ChargementParametres(string fileName)
+{
+    string section;
+    string key;
     char * value;
-    char * fileName = (char *)malloc(sizeof(char)*255);
+    stringstream os;
+
 
 
     Affiche("Lecture du fichier de configuration 'params' :\n\n", true);
 
-    strcpy(fileName,"params");
-
-    strcpy(section, "connexion indi");
-
-    strcpy(key, "serveur");
-
-    strcpy(Serveur, "");
-
-    if (readINI(section, key, &value, fileName))
-    {
-        strcpy(Serveur, value);
-        os << "serveur=" << Serveur << std::endl;
-        Affiche(os.str(), true);
+
+    /////////////////////////////////////////
+    // Rubrique CoodonnÃ©es gÃ©ographiques
+
+    section = "coordonnees geographiques";
+
+    key = "latitude";
+
+    if ((readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
+            && (Decomposition(value, 0, NULL, NULL, NULL)))
+    {
+        LatitudeChar = (string)value;
+        delete [] value;
+        Affiche("latitude = " + LatitudeChar +"\n", true);
     }
     else
     {
-        os << "Nom du serveur invalide !" << std::endl;
+        Erreur("La latitude est incorrecte !\n");
+        return false;
+    }
+
+
+    key = "longitude";
+
+    if ((readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
+            && (Decomposition(value, 1, NULL, NULL, NULL)))
+    {
+        LongitudeChar = (string)value;
+        delete [] value;
+        Affiche("longitude = " + LongitudeChar +"\n\n", true);
+    }
+    else
+    {
+        Erreur("La longitude est incorrecte !\n");
+        return false;
+    }
+
+
+    /////////////////////////////////////////
+    // rubrique connexion
+
+    section = "connexion indi";
+
+    key = "serveur";
+
+    if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
+    {
+        Serveur = (string)value;
+        delete [] value;
+        Affiche("serveur = " + Serveur +"\n", true);
+    }
+    else
+    {
+        Erreur("Nom du serveur invalide !\n");
+        return false;
+    }
+
+
+    key = "port";
+
+    if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
+    {
+        Port = (string)value;
+        delete [] value;
+        Affiche("port = " + Port +"\n\n", true);
+    }
+    else
+    {
+        Erreur("NumÃ©ro de port incorrect !\n");
+        return false;
+    }
+
+
+    /////////////////////////////////////////
+    // Rubrique paramÃštres de l'atmosphÃšre
+
+    section = "atmosphere";
+
+    key = "pression";
+
+    if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
+    {
+        Pression = atof(value);
+        delete [] value;
+        os << "pression = " << Pression << endl;
+        Affiche(&os, true);
+    }
+    else
+    {
+        os << "La pression atmosph&rique est incorrecte !" << endl;
+        Erreur(&os);
+        return false;
+    }
+
+    key = "temperature";
+
+    if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
+    {
+        Temperature=atof(value);
+        delete [] value;
+        os << "tempÃ©rature = " << Temperature << endl << endl;
+        Affiche(&os, true);
+    }
+    else
+    {
+        Erreur("La tempÃ©rature est incorrecte !\n");
+        return false;
+    }
+
+
+    /////////////////////////////////////////
+    // Rubrique suivi
+
+    section = "suivi";
+
+    key = "mode";
+
+    if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
+    {
+        Transit = (strstr(value, "transit") != NULL);
+        Affiche("mode suivi = " + (string)value + "\n", true);
+        delete [] value;
+    }
+    else
+    {
+        Erreur("Le paramÃštre mode est incorrect !\n");
+        return false;
+    }
+
+
+
+    key = "delai_transit";
+
+    if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
+    {
+        delaitransit=atoi(value);
+        delete [] value;
+        os << "delai transit = " << delaitransit << " sec" << endl;
+        Affiche(&os, true);
+    }
+    else
+    {
+        Erreur("Le paramÃštre delai_transit est incorrect !\n");
+        return false;
+    }
+
+
+    key = "delai_tracking";
+
+    if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
+    {
+        delaitracking=atoi(value);
+        delete [] value;
+        os << "delai tracking = " << delaitracking << " sec" << endl << endl;
+        Affiche(&os, true);
+    }
+    else
+    {
+        Erreur("Le paramÃštre delai_tracking est incorrect !\n");
+        return false;
+    }
+
+
+    /////////////////////////////////////////
+    // Rubrique divers
+
+    section = "divers";
+
+    key = "couleurs";
+
+    if (readINI(section.c_str(), key.c_str(), &value, fileName.c_str()))
+    {
+        ChoixCouleurs=atoi(value);
+        delete [] value;
+    }
+    else
+    {
+        /*os << "Le paramÃštre couleurs est incorrect !" << endl;
         Erreur(os.str());
-        return false;
-    }
-
-    strcpy(key, "port");
-
-    if (readINI(section, key, &value, fileName))
-    {
-        Port=atoi(value);
-        os << "port=" << Port << std::endl << std::endl;
-        Affiche(os.str(), true);
-    }
-    else
-    {
-        os << "NumÃ©ro de port incorrect !" << std::endl;
-        Erreur(os.str());
-        return false;
-    }
-
-    strcpy(section, "coordonnees geographiques");
-
-    strcpy(Latitude, "");
-    strcpy(Longitude, "");
-    
-    strcpy(key, "latitude");
-
-    if ((readINI(section, key, &value, fileName)) && (Decomposition(value, 0, NULL, NULL, NULL)))
-    {
-        strcpy(Latitude, value);
-        os << "latitude=" << Latitude << std::endl;
-        Affiche(os.str(), true);
-    }
-    else
-    {
-        os << "La latitude est incorrecte !" << std::endl;
-        Erreur(os.str());
-        return false;
-    }
-
-    strcpy(key, "longitude");
-
-    if ((readINI(section, key, &value, fileName)) && (Decomposition(value, 1, NULL, NULL, NULL)))
-    {
-        strcpy(Longitude, value);
-        os << "longitude=" << Longitude << std::endl << std::endl;
-        Affiche(os.str(), true);
-    }
-    else
-    {
-        os << "La longitude est incorrecte !" << std::endl;
-        Erreur(os.str());
-        return false;
-    }
-
-    strcpy(section, "transit");
-
-    strcpy(key, "delai");
-
-    if (readINI(section, key, &value, fileName))
-    {
-        delaitransit=atoi(value);
-        os << "delai transit= " << delaitransit << " sec" << std::endl;
-        Affiche(os.str(), true);
-    }
-    else
-    {
-        os << "Le paramÃštre transit est incorrect !" << std::endl;
-        Erreur(os.str());
-        return false;
-    }
-
-    strcpy(section, "tracking");
-
-    strcpy(key, "delai");
-
-    if (readINI(section, key, &value, fileName))
-    {
-        delaitracking=atoi(value);
-        os << "delai tracking= " << delaitracking << " sec" << std::endl << std::endl;
-        Affiche(os.str(), true);
-    }
-    else
-    {
-        os << "Le paramÃštre tracking est incorrect !" << std::endl;
-        Erreur(os.str());
-        return false;
+        return false;*/
     }
 
@@ -1087,17 +2053,23 @@
 
 
-int main(int argc, char **argv)
-{
-    std::string chaine;
+/**************************************************************************************
+** Routine principale
+***************************************************************************************/
+
+int BAOcontrol::init(int argc, char **argv)
+{
+    string chaine;
 
     pthread_t th1;
 
-    if (argc >1)
+    // gestion au dÃ©marrage des paramÃštres en ligne de commande
+
+    if ( argc >1 )
     {
         if (strstr(argv[1], "-h")!=NULL)
         {
-            std::cout << "usage :\n \
+            cout << "usage :\n \
        BAOControl -h ou --help : affiche l'aide\n \
-       BAOControl -r FileName : execute les mouvements dÃ©finis dans le fichier FileName\n\n";
+       BAOControl -r FileName : exÃ©cute les mouvements dÃ©finis dans le fichier FileName\n\n";
 
             return 0;
@@ -1105,36 +2077,7 @@
     }
 
-    for (int i=0; i<MAXANTENNES; i++)
-    {
-        Antennes[i].ok=0;
-        Antennes[i].ip=0;
-    }
-
-    for (int i=0; i<MAXOBJETS; i++)
-    {
-        objets[i].JJ=0;
-        objets[i].exec=false;
-    }
-
-
-    Affiche("\n\n\n\n\n\n \
-    ************************\n \
-    *      BAO Control     *\n \
-    *         v0.1         *\n \
-    *      10/11/2010      *\n \
-    ************************\n\n", true);
-
-    if (!ChargementParametres())
-    {
-        Erreur("Le fichier de configuration 'params' contient des erreurs ou n'existe pas. Merci de vÃ©rifier.\n");
-        exit(1);
-    }
-
-    client_socket = new ClientSocket("localhost", Port );
-
-    
-    Connect(true);
-
-    if (argc == 1)  std::cout << "Tapez help pour obtenir des infos sur les commandes disponibles.\n" << std::endl;
+    if (argc == 1)  cout << "Tapez help pour obtenir la liste des commandes disponibles.\n" << endl << endl;
+
+    // On lance la fenÃªtre graphique
 
     initialiserFenetre();
@@ -1142,10 +2085,16 @@
     XSelectInput(d,w, ExposureMask );
 
-    if (pthread_create(&th1, NULL, my_thread_process, NULL) < 0) {
+    // On lance le thread pour gÃ©rer la fenÃªtre graphique
+    // la communication avec indi_BAO et le suivi des objets
+
+    if (pthread_create(&th1, NULL, (void*(*)(void*))LancementThread, this) < 0) {
         Erreur("Impossible de crÃ©er le thread\n");
-        exit (1);
-    }
-    
-    astro = new Astro();
+        return -1;
+    }
+
+
+
+    // si on a utilisÃ© l'option -r en ligne de commande
+    // alors on charge et on lance l'exÃ©cution d'un fichier de mouvements
 
     if (argc == 3)
@@ -1156,4 +2105,6 @@
 
             Run(argv[2]);
+
+            // on attend ici la fin de l'exÃ©cution du fichier de mouvements
 
             do
@@ -1169,20 +2120,26 @@
     else
     {
+        // Saisie et dÃ©codage des commandes entrÃ©es par l'utilisateur
 
         do
         {
-            std::cout << blue << '>';
-            getline(std::cin, chaine);
-            std::cout << black;
-
+            // Prompt
+            ChoixCouleurs==1 ? cout << blue1 : cout << blue2;
+            cout << '>';
+            // saisie
+            getline(cin, chaine);
+            ChoixCouleurs==1 ? cout << grey1 : cout << grey2;
+
+            // on met en minuscules
             for (int i=0; i<chaine.size();++i) chaine[i] = tolower(chaine[i]);
 
+            // on dÃ©code et exÃ©cute les commandes
             DecodageEntreesUtilisateur(chaine);
         }
         while (NoExit);
-    }
-
-    delete astro;
-    delete client_socket;
+
+        pthread_join(th1 ,NULL);
+        //pthread_detach(th1);
+    }
 
     return 0;
Index: /BAORadio/libindi/libindi/BAOControl/baocontrol.h
===================================================================
--- /BAORadio/libindi/libindi/BAOControl/baocontrol.h	(revision 503)
+++ /BAORadio/libindi/libindi/BAOControl/baocontrol.h	(revision 504)
@@ -1,2 +1,10 @@
+// Definition of the Astro BAOcontrol
+// Franck RICHARD
+// BAORadio
+
+#ifndef BAOcontrol_class
+#define BAOcontrol_class
+
+
 #include <iostream>
 #include <string.h>
@@ -5,8 +13,9 @@
 #include "SocketException.h"
 #include <stdio.h>
+#include <stdlib.h>
 #include <pthread.h>
 #include <X11/Xlib.h>
 #include "filetools.h"
-#include "astro.h"
+#include "../drivers/telescope/astro.h"
 #include "math.h"
 #include <time.h>
@@ -15,15 +24,29 @@
 
 
-#define red "\033[0;31m"
-#define blue "\033[0;34m"
-#define green "\033[0;32m"
-#define black "\033[0;30m"
+// couleurs utilisÃ©es dans le terminal
+
+#define red1 "\033[0;31m"
+#define blue1 "\033[0;34m"
+#define green1 "\033[0;32m"
+#define black1 "\033[0;30m"
+#define grey1 "\033[1;30m"
+#define red2 "\033[1;31m"
+#define blue2 "\033[1;34m"
+#define green2 "\033[1;32m"
+#define black2 "\033[1;30m"
+#define grey2 "\033[1;37m"
+
+
+// limites des tableaux
 
 #define MAXLOG 1000
 #define MAXOBJETS 100
-#define MAXANTENNES 100
+#define MAXANTENNES 50
 
-#define larg 600
-#define haut 10+30*12
+
+//dimensions de la fenÃªtre graphique
+
+#define haut_fenetre 10+22*10
+#define larg_fenetre 605
 
 using namespace std;
@@ -32,66 +55,100 @@
 struct DefAntenne
 {
-    unsigned char ip;
+    unsigned char ip;			// Adresse ip d'une antenne
 
-    char ok;
+    char ok;				// actuellement disponible ?
 };
+
+// objets stockÃ©s dans le fichier de mouvements
 
 struct DefObjets
 {
-    double JJ;
-    double Duree;
-    char ad[10];
-    char de[10];
-    bool exec;
+    double JJ;				// Jour julien oÃ¹ le tÃ©lescope doit aller pointer vers l'objet
+    double Duree;			// DurÃ©e de l'observation de l'objet en sec
+    string ad;				// Ascension droite J2000 de l'objet
+    string de;				// dÃ©clinaison J2000 de l'objet
+    bool exec;				// En cours d'exÃ©cution ?
 };
 
 
-char Latitude[80];
-char Longitude[80];
-char Serveur[80];
 
-std::string logs[MAXLOG];
+class BAOcontrol : public Astro
+{
 
-std::stringstream os;
+public:
+    BAOcontrol();
+    ~BAOcontrol();
 
-int Port=0;
-int delaitransit=0;
-int delaitracking=0;
-int lognum=0;
-int numAntenne=0;
-int numobjets=0;
-int runnum=1;
-
-struct DefAntenne Antennes[MAXANTENNES];
-struct DefObjets objets[MAXOBJETS];
-
-bool NoExit=true;
-bool Transit=false;
-bool run=false;
-bool exitrun=false;
-
-ClientSocket *client_socket;
-Astro *astro;
-
-Display * d;
-Window w;
-Pixmap db;
-GC noir, vert, rouge, gris;
+    void *my_thread_process ();
+    int init(int argc, char **argv);
 
 
-void initialiserFenetre();
-void Dessiner();
-void rouler(char* reponse);
-void LireReponse();
-void *my_thread_process (void * arg);
-bool Decomposition(std::string chaine, char type, float *a1, float *a2, float *a3);
-bool DecompositionCommande(std::string chaine, std::string commande, std::string *chaine1, std::string *chaine2);
-bool EncoyerCoordGeographiques();
-bool Connect(bool connect);
-bool Park();
-bool Abort();
-bool Goto(std::string ar, std::string dec, bool Transit);
-bool LectureFichierMouvements(char * fileName);
-bool Run(std::string fichier);
-void DecodageFonction(std::string chaine);
-bool ChargementParametres(); 
+private:
+    void Affiche(string chaine, bool AfficheEcran);
+    void Affiche(stringstream *Message, bool AfficheEcran);
+    void Erreur(string chaine);
+    void Erreur(stringstream *Message);
+    void initialiserFenetre();
+    void Dessiner();
+    void rouler();
+    void LireReponse();
+    bool VerifReponse(string reponseattendue);
+    void Update();
+    bool Decomposition(string chaine, char type, float *a1, float *a2, float *a3);
+    bool DecompositionCommande(string chaine, string commande, string *chaine1, string *chaine2);
+    bool EnvoyerCoordGeographiques();
+    bool Park();
+    bool Abort();
+    bool Goto(string ar, string dec, bool Transit, bool J2000);
+    bool Connect(bool connect);
+    bool LectureFichierMouvements(string fileName);
+    void DecodageEntreesUtilisateur(string chaine);
+    bool Run(string fichier);
+    bool ChargementParametres(string fileName);
+    Coordonnees ServeurNED(string objet);
+    int  readline (FILE * pfile, char *tab);
+
+
+
+    // Variables globales
+
+    XFontStruct * fd;                           // Police de caractÃšres dans la fenÃªtre graphique
+
+    char ChoixCouleurs;                         // 1-pour un terminal Ã  fond blanc    2-pour un terminal Ã  fond noir
+
+    string logs[MAXLOG];                        // Sauvegarde de toutes les actions et rÃ©ponses dans un tableau logs
+
+    int delaitransit;				// DÃ©lai entre deux actualisations de la position en mode transit
+    int delaitracking;				// DÃ©lai entre deux actualisations de la position en mode tracking
+    int lognum;					// Nbre d'enregistrements dans le tableau logs
+    int numAntenne;				// Nbre d'antennes connectÃ©es
+    int numobjets;				// Nbre d'objets dans le dernier fichier de mouvements chargÃ©
+    int runnum;					// NumÃ©ro de l'objet actuellement visÃ© dans le fichier de mouvement
+
+    double Pression;				// Pression atmosphÃ©rique en mBar
+    double Temperature; 			// tempÃ©rature de l'atmosphÃšre
+
+    bool NoExit;				// A-t-on tapÃ© exit pour sortir ? Permet de fermer le thread Ã  ce moment-lÃ 
+    bool Transit;				// Si oui, le mode transit est activÃ©, sinon, c'est le mode tracking
+    bool run;					// execute actuellement un fichier de mouvements
+    bool exitrun;				// doit-on sortir du programme Ã  la fin de l'execution de la commande run ?
+    bool J2000;					// est-ce que les coordonnÃ©es du fichier de mouvements sont en coordonnÃ©es J2000 ?
+
+    struct DefAntenne *Antennes;		// Sauvegarde de la situation actuelle de l'antenne i
+    struct DefObjets  *objets;			// Liste des objets chargÃ©s depuis un fichier de mouvements
+
+    string LatitudeChar;			// Latitude du lieu d'observation. ChargÃ©e depuis le fichier de configuration
+    string LongitudeChar;			// Longitude du lieu d'observation. ChargÃ©e depuis le fichier de configuration
+    string Serveur;				// Nom ou IP du serveur faisant tourner indi_BAO. Par defaut c'est localhost
+    string Port; 				// Port utilisÃ© pour connecter le serveur indi_BAO
+
+    ClientSocket *client_socket;		// Socket permettant la connexion avec le pilote indi_BAO
+
+    Display * d;				// contexte graphique
+    Window w;					// fenÃªtre graphique
+    Pixmap db;					// copie de la fenÃªtre pour permettre une actualisation sans scintillement
+    GC noir, vert, rouge, gris;			// couleurs utilisÃ©es dans la fenÃªtre graphique
+
+};
+
+#endif
Index: ORadio/libindi/libindi/BAOControl/filetools.c
===================================================================
--- /BAORadio/libindi/libindi/BAOControl/filetools.c	(revision 503)
+++ 	(revision )
@@ -1,1066 +1,0 @@
-/*filetools.c*/
-
-#include "filetools.h"
-
-#define MAX_LENGHT 255
-
-/******************************************************
- * NOM:              readINI                          *
- * SPECIFICATION:                                     *
- *   retourne la valeur de la cle du                  *
- *               fichier dont la structure est celle  *
- *               d'un fichier .ini windows            *
- * ARGUMENTS:                                         *
- * >section: le nom de la section sans les crochets   *
- * >key: nom de la cle de la section                  *
- * >pStr: pointeur pour mettre le resultat            *
- *       allocation memoire effectuee                 *
- * ENVIRONNEMENT:                                     *
- * VALEUR RETOURNEE:0 si echec 1 si oui               *
- ******************************************************/
-int
-readINI (char *sectionName, char *pKeyName, char **ppStr, char *fileName)
-{
-  INI *pIni = NULL;
-  SECTION *pSection = NULL;
-  KEY *pKey = NULL;
-  int trouve = 0;
-  char *pSectionName = NULL;
-  int offset = 0;
-  //pStr = resultValue;
-  TRY
-  {
-    trouve = 0;
-    pIni = _loadINI (fileName);
-    /*recherche de la section */
-    offset = strlen (sectionName) + 3;
-    pSectionName = (char *) m_malloc (sizeof (char) * offset);
-    pSectionName[0] = '[';
-    strcpy (pSectionName + 1, sectionName);
-    pSectionName[strlen (sectionName) + 1] = ']';
-    pSectionName[offset - 1]='\0';
-
-    pSection = _findSECTION (pIni, pSectionName);
-
-    if (pSection != NULL)
-      {
-        /*recherche de la cle */
-        pKey = _findKEY (pSection, pKeyName);
-        if (pKey != NULL)
-        {
-          *ppStr = (char *) m_malloc (sizeof (char) * strlen (pKey->value) + 2);
-          strcpy (*ppStr, pKey->value);
-          (*ppStr)[strlen (pKey->value)] = '\0';
-          trouve = 1;
-        }
-      }
-  }
-  CATCH (ERR_FOPEN)
-  {
-    printf ("impossible d'ouvrir le fichier %s\n", fileName);
-    ppStr = NULL;
-  }
-  CATCH (ERR_MALLOC)
-  {
-    perror ("Probleme d'allocation memoire");
-    exit (EXIT_FAILURE);
-  }  
-  ENDTRY;
-  
-  
-  return trouve;
-}
-
-/******************************************************
- * NOM:                delINI                         *
- * SPECIFICATION:                                     *
- *  seule la cle de la section est supprimee          *
- *  si la section est vide, elle est supprimee        *
- * ARGUMENTS:                                         *
- * >section: le nom de la section sans les crochets   *
- * >key: nom de la cle de la section                  *
- * >pStr: pointeur pour mettre la valeur de la cle    *
- *       avant sa suppression                         *
- *       allocation memoire effectuee                 *
- * ENVIRONNEMENT:                                     *
- * VALEUR RETOURNEE:                                  *
- * 1 si reussite de la suppression, 0 sinon           *
- ******************************************************/
-int
-delINI (char *sectionName, char *pKeyName, char **ppStr, char *fileName)
-{
-  INI *pIni = NULL;
-  SECTION *pSection = NULL;
-  KEY *pKey = NULL;
-  int del = 0;
-  char *pSectionName = NULL;
-  int offset = 0;
-  //pStr = resultValue;
-  TRY
-  {
-
-    pIni = _loadINI (fileName);
-    /*recherche de la section */
-    offset = strlen (sectionName) + 3;
-    pSectionName = (char *) m_malloc (sizeof (char) * offset);
-    pSectionName[0] = '[';
-    strcpy (pSectionName + 1, sectionName);
-    pSectionName[strlen (sectionName) + 1] = ']';
-    pSectionName[offset - 1];
-
-    pSection = _findSECTION (pIni, pSectionName);
-
-    if (pSection != NULL)
-      {
-	if (pKeyName == NULL)
-	  {
-	    /*on supprime toute la section */
-
-	    pKey = _lastKEY (pSection);
-	    while (pKey != NULL)
-	      {
-		_delKEY (pKey);
-		pKey = _lastKEY (pSection);
-	      }
-	    _delSECTION (pSection);
-	    del = 1;
-	  }
-	else
-	  {
-	    /*recherche de la cle si indiquee */
-	    pKey = _findKEY (pSection, pKeyName);
-	    if (pKey != NULL)
-	      {
-		(*ppStr) =
-		  (char *) m_malloc (sizeof (char) * strlen (pKey->value) +
-				     2);
-		strcpy (*ppStr, pKey->value);
-		(*ppStr)[strlen (pKey->value)] = '\0';
-		if (_delKEY (pKey))
-		  {
-		    /*si la cle supprimee etait la derniere de la section */
-		    _delSECTION (pSection);
-		  }
-		del = 1;
-	      }
-	  }
-      }
-    if (del)
-      {
-	_saveINI (pIni);
-      }
-  }
-  CATCH (ERR_FOPEN)
-  {
-    printf ("impossible d'ouvrir le fichier %s\n", fileName);
-    (*ppStr) = NULL;
-  }
-  CATCH (ERR_MALLOC)
-  {
-    perror ("Probleme d'allocation memoire");
-    exit (EXIT_FAILURE);
-  }
-  ENDTRY;
-
-  return del;
-}
-
-/******************************************************
- * NOM:                writeINI                       *
- * SPECIFICATION:                                     *
- *  si la section n'existe pas elle est cree          *
- *  si la cle n'existe pas elle est cree              *
- *  et la valeur de la cle est initialisee            *
- *  sinon la cle existante de la section existante est*
- *  mise a jour                                       * 
- * ARGUMENTS:                                         *
- * ENVIRONNEMENT:                                     *
- * VALEUR RETOURNEE:                                  *
- *  NULL si echec ou keyValue si reussite             *
- ******************************************************/
-char *
-writeINI (char *sectionName, char *keyName, char *keyValue, char *fileName)
-{
-  char *pSectionName = NULL;
-  char *pKeyName = NULL;
-  char *pKeyValue = NULL;
-  INI *pIni = NULL;
-  SECTION *pSection = NULL;
-  KEY *pKey = NULL;
-  TRY
-  {
-    pKeyName = (char *) m_malloc (sizeof (char) * strlen (keyName) + 1);
-    pSectionName =
-      (char *) m_malloc (sizeof (char) * strlen (sectionName) + 3);
-    if (keyValue != NULL)
-      {
-	pKeyValue = (char *) m_malloc (sizeof (char) * strlen (keyValue) + 1);
-	strcpy (pKeyValue, keyValue);
-	pKeyValue[strlen (keyValue)] = '\0';
-      }
-    else
-      {
-	pKeyValue = (char *) m_malloc (sizeof (char));
-	pKeyValue[0] = '\0';
-      }
-    strcpy (pKeyName, keyName);
-    pSectionName[0] = '[';
-    strcpy (pSectionName + 1, sectionName);
-    pSectionName[strlen (sectionName) + 1] = ']';
-    pSectionName[strlen (sectionName) + 2] = '\0';
-    /*chargement */
-    pIni = _loadINI (fileName);
-
-  }
-  CATCH (ERR_FOPEN)
-  {
-    printf ("Erreur en ouvrant le fichier .ini:%s\n", fileName);
-    exit (EXIT_FAILURE);
-  }
-  CATCH (ERR_MALLOC)
-  {
-    perror ("Probleme d'allocation memoire");
-    exit (EXIT_FAILURE);
-  }
-  ENDTRY;
-
-  /*recherche de la section */
-  pSection = _findSECTION (pIni, pSectionName);
-  /*recherche de la cle */
-  if (pSection != NULL)
-    {
-      pKey = _findKEY (pSection, pKeyName);
-      if (pKey != NULL)
-	{
-	  pKey->value =
-	    (char *) realloc (pKey->value,
-			      sizeof (char) * strlen (pKeyName) + 1);
-	  if (pKey->value == NULL)
-	    {
-	      perror ("probleme de reallocation memoire");
-	      exit (EXIT_FAILURE);
-	    }
-	  strcpy (pKey->value, pKeyValue);
-	}
-      else
-	{
-	  /*cle pas trouve dans la section, on ajoute la cle a la section */
-	  pKey = _newKEY (pKeyName, pKeyValue);
-	  _addKEY (pSection, pKey);
-	}
-    }
-  else
-    {
-      /*section pas trouve, on la cree avec sa cle */
-      pSection = _newSECTION (pSectionName);
-      _addSECTION (pIni, pSection);
-      pKey = _newKEY (pKeyName, pKeyValue);
-      _addKEY (pSection, pKey);
-
-    }
-  TRY
-  {
-
-    /*sauvegarde */
-    _saveINI (pIni);
-
-  }
-  CATCH (ERR_FOPEN)
-  {
-    printf ("erruer sur le fichier %s", pIni->fileName);
-  }
-  ENDTRY;
-
-  /*nettoyage */
-
-  free (pIni);
-  free (pSection);
-  free (pKey);
-  free (pKeyName);
-  free (pSectionName);
-  pIni = NULL;
-  pKeyName = NULL;
-  pSectionName = NULL;
-  return pKeyValue;
-}
-
-/******************************************************
- * NOM:                                               *
- *                 _delKEY                            *
- * SPECIFICATION:                                     *
- * ARGUMENTS:                                         *
- * ENVIRONNEMENT:                                     *
- * VALEUR RETOURNEE:                                  *
- *  1 si derniere cellule, 0 sinon, -1 si probleme    *
- ******************************************************/
-int
-_delKEY (KEY * pKey)
-{
-  int result = 0;
-  if (pKey != NULL)
-    {
-      /*la cle n'est pas la premiere */
-      if (pKey->prev != pKey)
-	{
-	  if (pKey->next != pKey)
-	    {
-	      /*la cle n'est pas la derniere */
-	      pKey->prev->next = pKey->next;
-	    }
-	  else
-	    {
-	      result = 1;
-	      pKey->prev->next = pKey->prev;
-	    }
-	}
-      else
-	{
-	  if (pKey->next != pKey)
-	    {
-	      /*la cle n'est pas non plus la derniere */
-	      pKey->parent->fils = pKey->next;
-	    }
-	  else
-	    {
-	      result = 1;
-	      pKey->parent->fils = NULL;
-	    }
-	}
-      _freeKEY (pKey);
-      return result;
-    }
-  else
-    {
-      result = -1;
-      return result;
-    }
-}
-
-
-/******************************************************
- * NOM:                                               *
- *                 _delSECTION                        *
- * SPECIFICATION:                                     *
- * ARGUMENTS:                                         *
- * ENVIRONNEMENT:                                     *
- * VALEUR RETOURNEE:                                  *
- *  pointeur sur la section                           *
- ******************************************************/
-int
-_delSECTION (SECTION * pSection)
-{
-  if (pSection != NULL)
-    {
-      /*la cle n'est pas la premiere */
-      if (pSection->prev != pSection)
-	{
-	  /*la cle n'est pas la derniere */
-	  if (pSection->next != pSection)
-	    {
-	      pSection->prev->next = pSection->next;
-	    }
-	  else
-	    {
-	      pSection->prev->next = pSection->prev;
-	    }
-	}
-      else
-	{
-	  /*la cle n'estpas nonplus la derniere */
-	  if (pSection->next != pSection)
-	    {
-	      pSection->parent->fils = pSection->next;
-	      pSection->next->prev = pSection->next;
-	    }
-	  else
-	    {
-	      pSection->parent->fils = NULL;
-	    }
-	}
-      _freeSECTION (pSection);
-      return 1;
-    }
-  else
-    {
-      return 0;
-    }
-}
-
-/************************
- * liberation memoire   *
- ************************/
-void
-_freeKEY (KEY * pKey)
-{
-  if (pKey != NULL)
-    {
-      pKey->parent = NULL;
-      pKey->next = NULL;
-      pKey->prev = NULL;
-      if (pKey->value != NULL)
-	{
-	  free (pKey->value);
-	}
-      if (pKey->name != NULL)
-	{
-	  free (pKey->name);
-	}
-      free (pKey);
-    }
-}
-void
-_freeSECTION (SECTION * pSection)
-{
-  if (pSection != NULL)
-    {
-      pSection->parent = NULL;
-      pSection->next = NULL;
-      pSection->prev = NULL;
-      if (pSection->name != NULL)
-	{
-	  free (pSection->name);
-	}
-      free (pSection);
-    }
-}
-
-/******************************************************
- * NOM:                                               *
- *                 _newKEY                            *
- * SPECIFICATION:                                     *
- *  allocation d'une nouvelle cle                     *
- * ARGUMENTS:                                         *
- * le nom et la valeur de la cle                      *
- * ENVIRONNEMENT:                                     *
- * VALEUR RETOURNEE:                                  *
- * pointeur sur la cle, NULL sinon                    *
- ******************************************************/
-KEY *
-_newKEY (char *pKeyName, char *pKeyValue)
-{
-  KEY *pKey;
-  TRY
-  {
-    pKey = (KEY *) m_malloc (sizeof (KEY));
-
-    pKey->name = (char *) m_malloc (sizeof (char) * strlen (pKeyName) + 1);
-    pKey->value = (char *) m_malloc (sizeof (char) * strlen (pKeyValue) + 1);
-  }
-  CATCH (ERR_MALLOC)
-  {
-    perror ("Probleme d'allocation memoire");
-    exit (EXIT_FAILURE);
-  }
-  ENDTRY;
-
-  strcpy (pKey->name, pKeyName);
-  strcpy (pKey->value, pKeyValue);
-  pKey->parent = NULL;
-  pKey->prev = pKey;
-  pKey->next = pKey;
-
-
-  return pKey;
-}
-
-/******************************************************
- * NOM:                                               *
- *                 _newSECTION                        *
- * SPECIFICATION:                                     *
- *  allocation d'une nouvelle section                 *
- * ARGUMENTS:                                         *
- * le nom de la section                               *
- * ENVIRONNEMENT:                                     *
- * VALEUR RETOURNEE:                                  *
- * pointeur sur la section, NULL sinon                *
- ******************************************************/
-SECTION *
-_newSECTION (char *pSectionName)
-{
-  SECTION *pSection;
-  TRY
-  {
-    pSection = (SECTION *) m_malloc (sizeof (SECTION));
-
-    pSection->name =
-      (char *) m_malloc (sizeof (char) * strlen (pSectionName) + 1);
-  }
-  CATCH (ERR_MALLOC)
-  {
-    perror ("Probleme d'allocation memoire");
-    exit (EXIT_FAILURE);
-  }
-  ENDTRY;
-
-  strcpy (pSection->name, pSectionName);
-  pSection->parent = NULL;
-  pSection->fils = NULL;
-  pSection->prev = pSection;
-  pSection->next = pSection;
-  return pSection;
-}
-
-/******************************************************
- * NOM:                                               *
- *                 _findSECTION                       *
- * SPECIFICATION:                                     *
- *  trouver la section dans une struture INI          *
- * ARGUMENTS:                                         *
- * la structure INI, le nom de la section avec ses [ ]*
- * ENVIRONNEMENT:                                     *
- * VALEUR RETOURNEE:                                  *
- * pointeur sur la section, NULL sinon                *
- ******************************************************/
-SECTION *
-_findSECTION (INI * pIni, char *pSectionName)
-{
-  SECTION *pSection = NULL;
-  pSection = pIni->fils;
-  while ((pSection != NULL) && (strcmp (pSection->name, pSectionName) != 0))
-    {
-      if (pSection == pSection->next)
-	{
-	  pSection = NULL;
-	}
-      else
-	{
-	  pSection = pSection->next;
-	}
-    }
-  return pSection;
-}
-
-/******************************************************
- * NOM:                                               *
- *                 _findKEY                           *
- * SPECIFICATION:                                     *
- *  trouver la cle dans une struture SECTION          *
- * ARGUMENTS:                                         *
- * la structure SECTION, le nom de la cle             *
- * ENVIRONNEMENT:                                     *
- * VALEUR RETOURNEE:                                  *
- * pointeur sur la cle, NULL sinon                    *
- ******************************************************/
-KEY *
-_findKEY (SECTION * pSection, char *pKeyName)
-{
-  KEY *pKey = NULL;
-  pKey = pSection->fils;
-  while ((pKey != NULL) && (strcmp (pKey->name, pKeyName) != 0))
-    {
-      if (pKey == pKey->next)
-	{
-	  pKey = NULL;
-	}
-      else
-	{
-	  pKey = pKey->next;
-	}
-    }
-  return pKey;
-}
-
-/******************************************************
- * NOM:                                               *
- *                 _lastKEY                           *
- * SPECIFICATION:                                     *
- *  trouver la derniere cle dans une struture SECTION *
- * ARGUMENTS:                                         *
- * la structure SECTION                               *
- * ENVIRONNEMENT:                                     *
- * VALEUR RETOURNEE:                                  *
- * pointeur sur la cle, NULL sinon                    *
- ******************************************************/
-KEY *
-_lastKEY (SECTION * pSection)
-{
-  KEY *pKey_pred = NULL;
-  KEY *pKey = NULL;
-  pKey = pSection->fils;
-  pKey_pred = pKey;
-  while (pKey != NULL)
-    {
-      pKey_pred = pKey;
-      if (pKey == pKey->next)
-	{
-	  pKey = NULL;
-	}
-      else
-	{
-	  pKey = pKey->next;
-	}
-    }
-  return pKey_pred;
-}
-
-/******************************************************
- * NOM:                                               *
- *                 _lastSECTION                       *
- * SPECIFICATION:                                     *
- *  trouver la derniere section dans une INI          *
- * ARGUMENTS:                                         *
- * la structure INI                                   *
- * ENVIRONNEMENT:                                     *
- * VALEUR RETOURNEE:                                  *
- * pointeur sur la section, NULL sinon                *
- ******************************************************/
-SECTION *
-_lastSECTION (INI * pIni)
-{
-  SECTION *pSection_pred = NULL;
-  SECTION *pSection = NULL;
-  pSection = pIni->fils;
-  pSection_pred = pSection;
-  while (pSection != NULL)
-    {
-      pSection_pred = pSection;
-      if (pSection == pSection->next)
-	{
-	  pSection = NULL;
-	}
-      else
-	{
-	  pSection = pSection->next;
-	}
-    }
-  return pSection_pred;
-}
-
-/******************************************************
- * NOM:                                               *
- *                 _addSECTION                        *
- * SPECIFICATION:                                     *
- *  ajoute une section en derniere place dans une INI *
- *  la section ne doit pas appartenir a une INI       *
- * ARGUMENTS:                                         *
- * la structure INI, la structure SECTION             * 
- * ENVIRONNEMENT:                                     *
- * VALEUR RETOURNEE:                                  *
- * pointeur sur la section, NULL sinon                *
- ******************************************************/
-SECTION *
-_addSECTION (INI * pIni, SECTION * pSection)
-{
-  SECTION *pSection_last = NULL;
-
-  if (pSection->parent != NULL)
-    {
-      return NULL;
-    }
-  else
-    {
-      pSection_last = _lastSECTION (pIni);
-      pSection->parent = pIni;
-      if (pSection_last != NULL)
-	{
-	  pSection_last->next = pSection;
-	  pSection->prev = pSection_last;
-	}
-      else
-	{
-	  pIni->fils = pSection;
-	}
-      return pSection;
-    }
-}
-
-/******************************************************
- * NOM:                                               *
- *                 _addKEY                            *
- * SPECIFICATION:                                     *
- *  ajoute une cle en derniere place dans une SECTION *
- *  la section ne doit pas appartenir a une SECTION   *
- * ARGUMENTS:                                         *
- * la structure KEY, la structure SECTION             *
- * ENVIRONNEMENT:                                     *
- * VALEUR RETOURNEE:                                  *
- * pointeur sur la cle, NULL sinon                *
- ******************************************************/
-KEY *
-_addKEY (SECTION * pSection, KEY * pKey)
-{
-  KEY *pKey_last = NULL;
-
-  if (pKey->parent != NULL)
-    {
-      return NULL;
-    }
-  else
-    {
-
-      pKey_last = _lastKEY (pSection);
-      pKey->parent = pSection;
-      if (pKey_last != NULL)
-	{
-	  pKey_last->next = pKey;
-	  pKey->prev = pKey_last;
-	}
-      else
-	{
-	  pSection->fils = pKey;
-	}
-      pKey->next = pKey;
-      return pKey;
-    }
-}
-
-/******************************************************
- * NOM:                                               *
- *                 saveINI                            *
- * SPECIFICATION:                                     *
- *  sauvegarde de la structure INI dans son fichier   *
- *  Attention, ecrase l'ancien fichier                *
-* ARGUMENTS:                                         *
-*  pointeur sur la structure INI a sauvegarder       *
-* ENVIRONNEMENT:                                     *
-* VALEUR RETOURNEE:                                  *
-*  -1 si un probleme a eu lieu, 0 sinon              *
-******************************************************/
-int
-_saveINI (INI * pIni)
-{
-  FILE *pFile = NULL;
-  char *str = NULL;
-  SECTION *pSection_pred = NULL, *pSection = NULL;
-  KEY *pKey_pred = NULL, *pKey = NULL;
-  int offset = 0;
-
-  pFile = fopen (pIni->fileName, "w");
-  if (pFile == NULL)
-    THROW (ERR_FOPEN);
-  //printf("#SAUVEGARDE Fichier INI#\n");
-  //printf("# %s #\n\n",pIni->fileName);
-  if (pIni->fils != NULL)
-    {
-      pSection = pIni->fils;
-      do
-	{
-
-	  fprintf (pFile, pSection->name);
-	  fprintf (pFile, "\n");
-	  pKey = pSection->fils;
-	  do
-	    {
-
-	      offset = strlen (pKey->name) + strlen (pKey->value) + 2;
-
-	      TRY
-	      {
-		str = (char *) m_malloc (sizeof (char) * offset);
-	      }
-	      CATCH (ERR_MALLOC)
-	      {
-		perror ("probleme d'allocation memoire");
-		exit (EXIT_FAILURE);
-	      }
-	      ENDTRY;
-	      memset (str, 0, offset);
-	      strcpy (str, pKey->name);
-	      offset = strlen (pKey->name);
-	      strcpy (str + offset, "=");
-	      offset = strlen (pKey->name) + 1;
-	      strcpy (str + offset, pKey->value);
-	      fprintf (pFile, str);
-	      fprintf (pFile, "\n");
-	      pKey_pred = pKey;
-	      pKey = pKey->next;
-	      free (str);
-	    }
-	  while (pKey != pKey_pred);
-
-	  pSection_pred = pSection;
-	  pSection = pSection->next;
-	}
-      while (pSection != pSection_pred);
-    }
-  /*nettoyage */
-  fclose (pFile);
-}
-
-/******************************************************
- * NOM:                                               *
- *                  loadINI                           *
- * SPECIFICATION:                                     *
- *  Charge le contenu d'un fichier .ini en memoire    *
- * ARGUMENTS:                                         *
- *  nom du fichier                                    *
- * ENVIRONNEMENT:                                     *
- * VALEUR RETOURNEE:                                  *
- *  pointeur sur la structure INI contenant le fichier*
- *  .ini avec les structures decrites dans le .h      *
- * EXCEPTION:                                         *
- * ERR_FOPEN, ERR_MALLOC
- ******************************************************/
-INI *
-_loadINI (char *fileName)
-{
-  FILE *pFile = NULL;
-  char *pBuf;
-  int nbRead = 0;
-  SECTION *pSection = NULL;
-  KEY *pKey = NULL;
-
-  INI *pIni = NULL;
-  pBuf = (char *) m_malloc (sizeof (char) * MAX_LENGHT);
-
-  pFile = fopen (fileName, "r");
-  if (pFile == NULL)
-    {
-      pFile = fopen (fileName, "a");
-      if (pFile == NULL)
-	THROW (ERR_FOPEN);	/*encore NULL !!? la! il y a vraiment un probleme !! */
-    }
-
-  pIni = (INI *) m_malloc (sizeof (INI));
-  pIni->fileName = (char *) m_malloc (sizeof (char) * strlen (fileName) + 1);
-  strcpy (pIni->fileName, fileName);
-  pIni->fils = NULL;
-  /* on lit ligne par ligne */
-  nbRead = readline (pFile, pBuf);
-  while (nbRead != -1)
-    {
-
-      if ((pBuf[0] == '[') && (pBuf[strlen (pBuf) - 1] == ']'))
-	{
-	  /* une section */
-	  pSection = NULL;
-
-	  pSection = _newSECTION (pBuf);
-	  _addSECTION (pIni, pSection);
-	}
-
-      /* les cles de la section */
-      while (((nbRead = readline (pFile, pBuf)) !=-1) && (pBuf[0] != '['))
-	{
-	  int ind = 0;
-	  pKey = NULL;
-	  if ((ind = _isKey (pBuf)) >= 0)
-	    {
-
-	      char *strName = NULL;
-	      strName = (char *) m_malloc (sizeof (char) * ind + 1);
-	      strncpy (strName, pBuf, ind);
-	      strName[ind] = '\0';
-	      pKey = _newKEY (strName, pBuf + ind + 1);
-	      _addKEY (pSection, pKey);
-	    }
-	}
-    }
-
-  /*nettoyage */
-  free (pBuf);
-  fclose (pFile);
-  return pIni;
-}
-
-/******************************************************
- * NOM:                                               *
- *                 _isKey                             *
- * SPECIFICATION:                                     *
- *  determine si une chaine est une cle valide        *
- * ARGUMENTS:                                         *
- *  pointeur sur la chaine                            *
- * ENVIRONNEMENT:                                     *
- * VALEUR RETOURNEE:                                  *
- *  indice du signe '=' si oui, -1 sinon              *
- ******************************************************/
-int
-_isKey (char *str)
-{
-  int ind = 0;
-  for (ind; (ind < strlen (str)) && (str[ind] != '='); ind++);
-  if (str[ind] == '=')
-    return ind;
-  else
-    return -1;
-}
-
-
-/******************************************************
- * NOM:                                               *
- *                  _printINI                         *
- * SPECIFICATION:                                     *
- * affiche a l'ecran le contenu de structure INI      *
- * ARGUMENTS:                                         *
- *  pointeur sur la structure INI                     *
- * ENVIRONNEMENT:                                     *
- * VALEUR RETOURNEE:                                  *
- ******************************************************/
-void
-_printINI (INI * pIni)
-{
-  SECTION *pSection_pred = NULL;
-  SECTION *pSection = NULL;
-  printf ("#Fichier INI#\n");
-  printf ("# %s #\n\n", pIni->fileName);
-  pSection = pIni->fils;
-  if (pSection != NULL)
-    {
-      do
-	{
-	  _printSECTION (pSection);
-	  pSection_pred = pSection;
-	  pSection = pSection->next;
-	}
-      while (pSection != pSection_pred);
-    }
-  printf ("\n#Fin du fichier INI#\n");
-}
-
-/******************************************************
- * NOM:                                               *
- *                  _printSECTION                     *
- * SPECIFICATION:                                     *
- * affiche a l'ecran le contenu de structure SECTION  *
- * ARGUMENTS:                                         *
- *  pointeur sur la structure SECTION                 *
- * ENVIRONNEMENT:                                     *
- * VALEUR RETOURNEE:                                  *
- ******************************************************/
-void
-_printSECTION (SECTION * pSection)
-{
-  KEY *pKey = NULL;
-  KEY *pKey_pred = NULL;
-  printf ("%s\n", pSection->name);
-  pKey = pSection->fils;
-  if (pKey != NULL)
-    {
-      do
-	{
-	  _printKEY (pKey);
-	  pKey_pred = pKey;
-	  pKey = pKey->next;
-	}
-      while (pKey != pKey_pred);
-    }
-}
-
-/******************************************************
- * NOM:                                               *
- *                  _printKEY                         *
- * SPECIFICATION:                                     *
- * affiche a l'ecran le contenu de structure SECTION  *
- * ARGUMENTS:                                         *
- *  pointeur sur la structure SECTION                 *
- * ENVIRONNEMENT:                                     *
- * VALEUR RETOURNEE:                                  *
- ******************************************************/
-void
-_printKEY (KEY * pKey)
-{
-  printf ("%s=%s\n", pKey->name, pKey->value);
-}
-
-/******************************************************
- * NOM:                                               *
- *                  printINI                          *
- * SPECIFICATION:                                     *
- * affiche a l'ecran le contenu du fichier .ini       *
- * ARGUMENTS:                                         *
- *  nom du fichier                                    *
- * ENVIRONNEMENT:                                     *
- * VALEUR RETOURNEE:                                  *
- ******************************************************/
-void
-printINI (char *file)
-{
-  INI *pIni = NULL;
-  TRY
-  {
-    pIni = _loadINI (file);
-  }
-  CATCH (ERR_MALLOC)
-  {
-    printf ("Erreur d'allocation memoire en chargeant le fichier .ini:%s\n",
-	    file);
-    exit (EXIT_FAILURE);
-  }
-  CATCH (ERR_FOPEN)
-  {
-    printf ("Erreur en ouvrant le fichier .ini:%s\n", file);
-    exit (EXIT_FAILURE);
-  }
-  ENDTRY;
-  _printINI (pIni);
-  free (pIni);
-}
-
-/******************************************************
- * NOM:                 jumpline                      *
- * SPECIFICATION:                                     *
- * fonction permettant de sauter des lignes dans le   *
- * fichier a partir de la position courante dans le   *
- * fichier                                            *
- * ARGUMENTS:                                         *
- * nombre de lignes a saute, pointeur sur le fichier  *
- * ENVIRONNEMENT:                                     *
- * VALEUR RETOURNEE: nombre de lignes sautees         *
- ******************************************************/
-
-int
-jumpline (int nbline, FILE * pfile)
-{
-  int compteur = 0, c;
-
-  while ((compteur < nbline) && ((c = getc (pfile)) != EOF))
-    {
-      if (c == '\n')
-	compteur++;
-    }
-  return (compteur);
-}
-
-/******************************************************
- * NOM:                readline                       *
- * SPECIFICATION:                                     *
- * recupere la ligne courante du fichier et renvoie le*
- * nombre de caracteres lus                           *
- * ARGUMENTS:                                         *
- * pointeur sur le fichier a lire                     *
- * pointeur sur le tableau recevant la ligne          *
- * ENVIRONNEMENT:                                     *
- * VALEUR RETOURNEE:                                  *
- * nombre de caracteres lus                           *
- ******************************************************/
-int
-readline (FILE * pfile, char *tab)
-{
-  int nbchar = 0;
-  char c;
-  while ((c = getc (pfile)) != '\n')
-    {
-      if (c == EOF)
-	{
-	  break;	  
-	}
-      tab[nbchar++] = c;
-    }
-  tab[nbchar] = '\0';
-  
-  while (nbchar>0 && tab[nbchar-1]==' ') { tab[--nbchar] = '\0';}
-  
-  while (tab[0]==' ') for (int i=1; i<=nbchar; i++) tab[i-1]=tab[i];
-  
-  if (c == EOF) nbchar=-1;
-  
-  return (nbchar);
-}
-
-/******************************************************
- * NOM:                m_malloc                       *
- * SPECIFICATION:                                     *
- *  clone de malloc renvoyant une exception           *
- * ARGUMENTS:                                         *
- * ENVIRONNEMENT:                                     *
- * VALEUR RETOURNEE:                                  *
- ******************************************************/
-void *
-m_malloc (size_t size)
-{
-  void *ptr = malloc (size);
-  if (ptr == NULL)
-    THROW (ERR_MALLOC);
-  else
-    return ptr;
-}
Index: /BAORadio/libindi/libindi/BAOControl/filetools.cpp
===================================================================
--- /BAORadio/libindi/libindi/BAOControl/filetools.cpp	(revision 504)
+++ /BAORadio/libindi/libindi/BAOControl/filetools.cpp	(revision 504)
@@ -0,0 +1,1114 @@
+/*filetools.c*/
+
+#include "filetools.h"
+
+#define MAX_LENGHT 255
+
+
+
+/******************************************************
+ * NOM:              readINI                          *
+ * SPECIFICATION:                                     *
+ *   retourne la valeur de la cle du                  *
+ *               fichier dont la structure est celle  *
+ *               d'un fichier .ini windows            *
+ * ARGUMENTS:                                         *
+ * >section: le nom de la section sans les crochets   *
+ * >key: nom de la cle de la section                  *
+ * >pStr: pointeur pour mettre le resultat            *
+ *       allocation memoire effectuee                 *
+ * ENVIRONNEMENT:                                     *
+ * VALEUR RETOURNEE:0 si echec 1 si oui               *
+ ******************************************************/
+int
+readINI (char *sectionName, char *pKeyName, char **ppStr, char *fileName)
+{
+    INI *pIni = NULL;
+    SECTION *pSection = NULL;
+    KEY *pKey = NULL;
+    int trouve = 0;
+    char *pSectionName = NULL;
+    int offset = 0;
+ 
+
+    trouve = 0;
+    pIni = _loadINI (fileName);
+    if (!pIni) return 0;
+
+    /*recherche de la section */
+    offset = strlen (sectionName) + 3;
+    pSectionName = new char [offset];
+    pSectionName[0] = '[';
+    strcpy (pSectionName + 1, sectionName);
+    pSectionName[strlen (sectionName) + 1] = ']';
+    pSectionName[offset - 1]='\0';
+
+    pSection = _findSECTION (pIni, pSectionName);
+
+    delete [] pSectionName;
+
+    if (pSection != NULL)
+    {
+        /*recherche de la cle */
+        pKey = _findKEY (pSection, pKeyName);
+        if (pKey != NULL)
+        {
+            *ppStr = new char [strlen (pKey->value) + 2];
+            strcpy (*ppStr, pKey->value);
+            (*ppStr)[strlen (pKey->value)] = '\0';
+            trouve = 1;
+
+        }
+    }
+
+    //On efface toutes les clÃ©s et toutes les sections
+
+    KEY *keyprev=NULL;
+    SECTION * secprev=NULL;
+    pSection=pIni->fils;
+
+    do
+    {
+        pKey=pSection->fils;
+
+        do
+        {
+            if (pKey->name) delete [] pKey->name;
+            if (pKey->value) delete [] pKey->value;
+
+            keyprev=pKey;
+
+            KEY *prev=pKey;
+            pKey=pKey->next;
+
+            delete prev;
+
+
+        } while (pKey!=keyprev);
+ 
+        if (pSection->name) delete []pSection->name;
+
+        secprev=pSection;
+
+        SECTION *sprev=pSection;
+        pSection=pSection->next;
+
+        delete sprev;
+
+    }  while (pSection!=secprev);
+
+
+
+    delete [] pIni->fileName;
+    delete pIni;
+    pIni=NULL;
+
+    return trouve;
+}
+
+int
+readINI (const char *sectionName, const char *pKeyName, char **ppStr, const char *fileName)
+{
+     return readINI((char*)sectionName, (char*)pKeyName, ppStr, (char*)fileName);
+}
+
+/******************************************************
+ * NOM:                delINI                         *
+ * SPECIFICATION:                                     *
+ *  seule la cle de la section est supprimee          *
+ *  si la section est vide, elle est supprimee        *
+ * ARGUMENTS:                                         *
+ * >section: le nom de la section sans les crochets   *
+ * >key: nom de la cle de la section                  *
+ * >pStr: pointeur pour mettre la valeur de la cle    *
+ *       avant sa suppression                         *
+ *       allocation memoire effectuee                 *
+ * ENVIRONNEMENT:                                     *
+ * VALEUR RETOURNEE:                                  *
+ * 1 si reussite de la suppression, 0 sinon           *
+ ******************************************************/
+/*
+int
+delINI (char *sectionName, char *pKeyName, char **ppStr, char *fileName)
+{
+  INI *pIni = NULL;
+  SECTION *pSection = NULL;
+  KEY *pKey = NULL;
+  int del = 0;
+  char *pSectionName = NULL;
+  int offset = 0;
+  //pStr = resultValue;
+  TRY
+  {
+
+    pIni = _loadINI (fileName);
+    //recherche de la section
+    offset = strlen (sectionName) + 3;
+    pSectionName = (char *) m_malloc (sizeof (char) * offset);
+    pSectionName[0] = '[';
+    strcpy (pSectionName + 1, sectionName);
+    pSectionName[strlen (sectionName) + 1] = ']';
+    pSectionName[offset - 1];
+
+    pSection = _findSECTION (pIni, pSectionName);
+
+    if (pSection != NULL)
+      {
+	if (pKeyName == NULL)
+	  {
+	    //on supprime toute la section
+
+	    pKey = _lastKEY (pSection);
+	    while (pKey != NULL)
+	      {
+		_delKEY (pKey);
+		pKey = _lastKEY (pSection);
+	      }
+	    _delSECTION (pSection);
+	    del = 1;
+	  }
+	else
+	  {
+	    //recherche de la cle si indiquee
+	    pKey = _findKEY (pSection, pKeyName);
+	    if (pKey != NULL)
+	      {
+		(*ppStr) =
+		  (char *) m_malloc (sizeof (char) * strlen (pKey->value) +
+				     2);
+		strcpy (*ppStr, pKey->value);
+		(*ppStr)[strlen (pKey->value)] = '\0';
+		if (_delKEY (pKey))
+		  {
+		    //si la cle supprimee etait la derniere de la section
+		    _delSECTION (pSection);
+		  }
+		del = 1;
+	      }
+	  }
+      }
+    if (del)
+      {
+	_saveINI (pIni);
+      }
+  }
+  CATCH (ERR_FOPEN)
+  {
+    printf ("impossible d'ouvrir le fichier %s\n", fileName);
+    (*ppStr) = NULL;
+  }
+  CATCH (ERR_MALLOC)
+  {
+    perror ("Probleme d'allocation memoire");
+    exit (EXIT_FAILURE);
+  }
+  ENDTRY;
+
+  return del;
+}
+*/
+/******************************************************
+ * NOM:                writeINI                       *
+ * SPECIFICATION:                                     *
+ *  si la section n'existe pas elle est cree          *
+ *  si la cle n'existe pas elle est cree              *
+ *  et la valeur de la cle est initialisee            *
+ *  sinon la cle existante de la section existante est*
+ *  mise a jour                                       *
+ * ARGUMENTS:                                         *
+ * ENVIRONNEMENT:                                     *
+ * VALEUR RETOURNEE:                                  *
+ *  NULL si echec ou keyValue si reussite             *
+ ******************************************************/
+
+/*
+
+char * writeINI (char *sectionName, char *keyName, char *keyValue, char *fileName)
+{
+  char *pSectionName = NULL;
+  char *pKeyName = NULL;
+  char *pKeyValue = NULL;
+  INI *pIni = NULL;
+  SECTION *pSection = NULL;
+  KEY *pKey = NULL;
+  TRY
+  {
+    pKeyName = (char *) m_malloc (sizeof (char) * strlen (keyName) + 1);
+    pSectionName =
+      (char *) m_malloc (sizeof (char) * strlen (sectionName) + 3);
+    if (keyValue != NULL)
+      {
+	pKeyValue = (char *) m_malloc (sizeof (char) * strlen (keyValue) + 1);
+	strcpy (pKeyValue, keyValue);
+	pKeyValue[strlen (keyValue)] = '\0';
+      }
+    else
+      {
+	pKeyValue = (char *) m_malloc (sizeof (char));
+	pKeyValue[0] = '\0';
+      }
+    strcpy (pKeyName, keyName);
+    pSectionName[0] = '[';
+    strcpy (pSectionName + 1, sectionName);
+    pSectionName[strlen (sectionName) + 1] = ']';
+    pSectionName[strlen (sectionName) + 2] = '\0';
+    //chargement
+    pIni = _loadINI (fileName);
+
+  }
+  CATCH (ERR_FOPEN)
+  {
+    printf ("Erreur en ouvrant le fichier .ini:%s\n", fileName);
+    exit (EXIT_FAILURE);
+  }
+  CATCH (ERR_MALLOC)
+  {
+    perror ("Probleme d'allocation memoire");
+    exit (EXIT_FAILURE);
+  }
+  ENDTRY;
+
+  //recherche de la section
+  pSection = _findSECTION (pIni, pSectionName);
+  //recherche de la cle
+  if (pSection != NULL)
+    {
+      pKey = _findKEY (pSection, pKeyName);
+      if (pKey != NULL)
+	{
+	  pKey->value =
+	    (char *) realloc (pKey->value,
+			      sizeof (char) * strlen (pKeyName) + 1);
+	  if (pKey->value == NULL)
+	    {
+	      perror ("probleme de reallocation memoire");
+	      exit (EXIT_FAILURE);
+	    }
+	  strcpy (pKey->value, pKeyValue);
+	}
+      else
+	{
+	  //cle pas trouve dans la section, on ajoute la cle a la section
+	  pKey = _newKEY (pKeyName, pKeyValue);
+	  _addKEY (pSection, pKey);
+	}
+    }
+  else
+    {
+      //section pas trouve, on la cree avec sa cle
+      pSection = _newSECTION (pSectionName);
+      _addSECTION (pIni, pSection);
+      pKey = _newKEY (pKeyName, pKeyValue);
+      _addKEY (pSection, pKey);
+
+    }
+  TRY
+  {
+
+    //sauvegarde
+    _saveINI (pIni);
+
+  }
+  CATCH (ERR_FOPEN)
+  {
+    printf ("erruer sur le fichier %s", pIni->fileName);
+  }
+  ENDTRY;
+
+  //nettoyage
+
+  free (pIni);
+  free (pSection);
+  free (pKey);
+  free (pKeyName);
+  free (pSectionName);
+  pIni = NULL;
+  pKeyName = NULL;
+  pSectionName = NULL;
+  return pKeyValue;
+}
+*/
+
+/******************************************************
+ * NOM:                                               *
+ *                 _delKEY                            *
+ * SPECIFICATION:                                     *
+ * ARGUMENTS:                                         *
+ * ENVIRONNEMENT:                                     *
+ * VALEUR RETOURNEE:                                  *
+ *  1 si derniere cellule, 0 sinon, -1 si probleme    *
+ ******************************************************/
+int
+_delKEY (KEY * pKey)
+{
+    int result = 0;
+    if (pKey != NULL)
+    {
+        /*la cle n'est pas la premiere */
+        if (pKey->prev != pKey)
+        {
+            if (pKey->next != pKey)
+            {
+                /*la cle n'est pas la derniere */
+                pKey->prev->next = pKey->next;
+            }
+            else
+            {
+                result = 1;
+                pKey->prev->next = pKey->prev;
+            }
+        }
+        else
+        {
+            if (pKey->next != pKey)
+            {
+                /*la cle n'est pas non plus la derniere */
+                pKey->parent->fils = pKey->next;
+            }
+            else
+            {
+                result = 1;
+                pKey->parent->fils = NULL;
+            }
+        }
+        _freeKEY (pKey);
+        return result;
+    }
+    else
+    {
+        result = -1;
+        return result;
+    }
+}
+
+
+/******************************************************
+ * NOM:                                               *
+ *                 _delSECTION                        *
+ * SPECIFICATION:                                     *
+ * ARGUMENTS:                                         *
+ * ENVIRONNEMENT:                                     *
+ * VALEUR RETOURNEE:                                  *
+ *  pointeur sur la section                           *
+ ******************************************************/
+int
+_delSECTION (SECTION * pSection)
+{
+    if (pSection != NULL)
+    {
+        /*la cle n'est pas la premiere */
+        if (pSection->prev != pSection)
+        {
+            /*la cle n'est pas la derniere */
+            if (pSection->next != pSection)
+            {
+                pSection->prev->next = pSection->next;
+            }
+            else
+            {
+                pSection->prev->next = pSection->prev;
+            }
+        }
+        else
+        {
+            /*la cle n'estpas nonplus la derniere */
+            if (pSection->next != pSection)
+            {
+                pSection->parent->fils = pSection->next;
+                pSection->next->prev = pSection->next;
+            }
+            else
+            {
+                pSection->parent->fils = NULL;
+            }
+        }
+        _freeSECTION (pSection);
+        return 1;
+    }
+    else
+    {
+        return 0;
+    }
+}
+
+/************************
+ * liberation memoire   *
+ ************************/
+void
+_freeKEY (KEY * pKey)
+{
+    if (pKey != NULL)
+    {
+        pKey->parent = NULL;
+        pKey->next = NULL;
+        pKey->prev = NULL;
+        if (pKey->value != NULL)
+        {
+            delete [] pKey->value;
+        }
+        if (pKey->name != NULL)
+        {
+            delete [] pKey->name;
+        }
+        delete pKey;
+
+        pKey=NULL;
+    }
+}
+void
+_freeSECTION (SECTION * pSection)
+{
+    if (pSection != NULL)
+    {
+        pSection->parent = NULL;
+        pSection->next = NULL;
+        pSection->prev = NULL;
+        if (pSection->name != NULL)
+        {
+            delete [] pSection->name;
+        }
+        delete pSection;
+
+        pSection=NULL;
+    }
+}
+
+/******************************************************
+ * NOM:                                               *
+ *                 _newKEY                            *
+ * SPECIFICATION:                                     *
+ *  allocation d'une nouvelle cle                     *
+ * ARGUMENTS:                                         *
+ * le nom et la valeur de la cle                      *
+ * ENVIRONNEMENT:                                     *
+ * VALEUR RETOURNEE:                                  *
+ * pointeur sur la cle, NULL sinon                    *
+ ******************************************************/
+KEY *
+_newKEY (char *pKeyName, char *pKeyValue)
+{
+    KEY *pKey;
+
+    {
+        pKey = new KEY;
+
+        pKey->name = new char [strlen (pKeyName) + 1];
+        pKey->value = new char [strlen (pKeyValue) + 1];
+    }
+
+
+    strcpy (pKey->name, pKeyName);
+    strcpy (pKey->value, pKeyValue);
+    pKey->parent = NULL;
+    pKey->prev = pKey;
+    pKey->next = pKey;
+
+    return pKey;
+}
+
+/******************************************************
+ * NOM:                                               *
+ *                 _newSECTION                        *
+ * SPECIFICATION:                                     *
+ *  allocation d'une nouvelle section                 *
+ * ARGUMENTS:                                         *
+ * le nom de la section                               *
+ * ENVIRONNEMENT:                                     *
+ * VALEUR RETOURNEE:                                  *
+ * pointeur sur la section, NULL sinon                *
+ ******************************************************/
+SECTION *
+_newSECTION (char *pSectionName)
+{
+    SECTION *pSection;
+
+    {
+        pSection = new SECTION;
+
+        pSection->name = new char [strlen (pSectionName) + 1];
+    }
+
+
+    strcpy (pSection->name, pSectionName);
+    pSection->parent = NULL;
+    pSection->fils = NULL;
+    pSection->prev = pSection;
+    pSection->next = pSection;
+
+    return pSection;
+}
+
+/******************************************************
+ * NOM:                                               *
+ *                 _findSECTION                       *
+ * SPECIFICATION:                                     *
+ *  trouver la section dans une struture INI          *
+ * ARGUMENTS:                                         *
+ * la structure INI, le nom de la section avec ses [ ]*
+ * ENVIRONNEMENT:                                     *
+ * VALEUR RETOURNEE:                                  *
+ * pointeur sur la section, NULL sinon                *
+ ******************************************************/
+SECTION *
+_findSECTION (INI * pIni, char *pSectionName)
+{
+    SECTION *pSection = NULL;
+    pSection = pIni->fils;
+    while ((pSection != NULL) && (strcmp (pSection->name, pSectionName) != 0))
+    {
+        if (pSection == pSection->next)
+        {
+            pSection = NULL;
+        }
+        else
+        {
+            pSection = pSection->next;
+        }
+    }
+    return pSection;
+}
+
+/******************************************************
+ * NOM:                                               *
+ *                 _findKEY                           *
+ * SPECIFICATION:                                     *
+ *  trouver la cle dans une struture SECTION          *
+ * ARGUMENTS:                                         *
+ * la structure SECTION, le nom de la cle             *
+ * ENVIRONNEMENT:                                     *
+ * VALEUR RETOURNEE:                                  *
+ * pointeur sur la cle, NULL sinon                    *
+ ******************************************************/
+KEY *
+_findKEY (SECTION * pSection, char *pKeyName)
+{
+    KEY *pKey = NULL;
+    pKey = pSection->fils;
+    while ((pKey != NULL) && (strcmp (pKey->name, pKeyName) != 0))
+    {
+        if (pKey == pKey->next)
+        {
+            pKey = NULL;
+        }
+        else
+        {
+            pKey = pKey->next;
+        }
+    }
+    return pKey;
+}
+
+/******************************************************
+ * NOM:                                               *
+ *                 _lastKEY                           *
+ * SPECIFICATION:                                     *
+ *  trouver la derniere cle dans une struture SECTION *
+ * ARGUMENTS:                                         *
+ * la structure SECTION                               *
+ * ENVIRONNEMENT:                                     *
+ * VALEUR RETOURNEE:                                  *
+ * pointeur sur la cle, NULL sinon                    *
+ ******************************************************/
+KEY *
+_lastKEY (SECTION * pSection)
+{
+    KEY *pKey_pred = NULL;
+    KEY *pKey = NULL;
+    pKey = pSection->fils;
+    pKey_pred = pKey;
+    while (pKey != NULL)
+    {
+        pKey_pred = pKey;
+        if (pKey == pKey->next)
+        {
+            pKey = NULL;
+        }
+        else
+        {
+            pKey = pKey->next;
+        }
+    }
+    return pKey_pred;
+}
+
+/******************************************************
+ * NOM:                                               *
+ *                 _lastSECTION                       *
+ * SPECIFICATION:                                     *
+ *  trouver la derniere section dans une INI          *
+ * ARGUMENTS:                                         *
+ * la structure INI                                   *
+ * ENVIRONNEMENT:                                     *
+ * VALEUR RETOURNEE:                                  *
+ * pointeur sur la section, NULL sinon                *
+ ******************************************************/
+SECTION *
+_lastSECTION (INI * pIni)
+{
+    SECTION *pSection_pred = NULL;
+    SECTION *pSection = NULL;
+    pSection = pIni->fils;
+    pSection_pred = pSection;
+    while (pSection != NULL)
+    {
+        pSection_pred = pSection;
+        if (pSection == pSection->next)
+        {
+            pSection = NULL;
+        }
+        else
+        {
+            pSection = pSection->next;
+        }
+    }
+    return pSection_pred;
+}
+
+/******************************************************
+ * NOM:                                               *
+ *                 _addSECTION                        *
+ * SPECIFICATION:                                     *
+ *  ajoute une section en derniere place dans une INI *
+ *  la section ne doit pas appartenir a une INI       *
+ * ARGUMENTS:                                         *
+ * la structure INI, la structure SECTION             *
+ * ENVIRONNEMENT:                                     *
+ * VALEUR RETOURNEE:                                  *
+ * pointeur sur la section, NULL sinon                *
+ ******************************************************/
+SECTION *
+_addSECTION (INI * pIni, SECTION * pSection)
+{
+    SECTION *pSection_last = NULL;
+
+    if (pSection->parent != NULL)
+    {
+        return NULL;
+    }
+    else
+    {
+        pSection_last = _lastSECTION (pIni);
+        pSection->parent = pIni;
+        if (pSection_last != NULL)
+        {
+            pSection_last->next = pSection;
+            pSection->prev = pSection_last;
+        }
+        else
+        {
+            pIni->fils = pSection;
+        }
+        return pSection;
+    }
+}
+
+/******************************************************
+ * NOM:                                               *
+ *                 _addKEY                            *
+ * SPECIFICATION:                                     *
+ *  ajoute une cle en derniere place dans une SECTION *
+ *  la section ne doit pas appartenir a une SECTION   *
+ * ARGUMENTS:                                         *
+ * la structure KEY, la structure SECTION             *
+ * ENVIRONNEMENT:                                     *
+ * VALEUR RETOURNEE:                                  *
+ * pointeur sur la cle, NULL sinon                *
+ ******************************************************/
+KEY *
+_addKEY (SECTION * pSection, KEY * pKey)
+{
+    KEY *pKey_last = NULL;
+
+    if (pKey->parent != NULL)
+    {
+        return NULL;
+    }
+    else
+    {
+
+        pKey_last = _lastKEY (pSection);
+        pKey->parent = pSection;
+        if (pKey_last != NULL)
+        {
+            pKey_last->next = pKey;
+            pKey->prev = pKey_last;
+        }
+        else
+        {
+            pSection->fils = pKey;
+        }
+        pKey->next = pKey;
+        return pKey;
+    }
+}
+
+/******************************************************
+ * NOM:                                               *
+ *                 saveINI                            *
+ * SPECIFICATION:                                     *
+ *  sauvegarde de la structure INI dans son fichier   *
+ *  Attention, ecrase l'ancien fichier                *
+* ARGUMENTS:                                         *
+*  pointeur sur la structure INI a sauvegarder       *
+* ENVIRONNEMENT:                                     *
+* VALEUR RETOURNEE:                                  *
+*  -1 si un probleme a eu lieu, 0 sinon              *
+******************************************************/
+
+/*
+ * int
+_saveINI (INI * pIni)
+{
+  FILE *pFile = NULL;
+  char *str = NULL;
+  SECTION *pSection_pred = NULL, *pSection = NULL;
+  KEY *pKey_pred = NULL, *pKey = NULL;
+  int offset = 0;
+
+  pFile = fopen (pIni->fileName, "w");
+  if (pFile == NULL)
+    THROW (ERR_FOPEN);
+  //printf("#SAUVEGARDE Fichier INI#\n");
+  //printf("# %s #\n\n",pIni->fileName);
+  if (pIni->fils != NULL)
+    {
+      pSection = pIni->fils;
+      do
+	{
+
+	  fprintf (pFile, pSection->name);
+	  fprintf (pFile, "\n");
+	  pKey = pSection->fils;
+	  do
+	    {
+
+	      offset = strlen (pKey->name) + strlen (pKey->value) + 2;
+
+	      TRY
+	      {
+		str = (char *) m_malloc (sizeof (char) * offset);
+	      }
+	      CATCH (ERR_MALLOC)
+	      {
+		perror ("probleme d'allocation memoire");
+		exit (EXIT_FAILURE);
+	      }
+	      ENDTRY;
+	      memset (str, 0, offset);
+	      strcpy (str, pKey->name);
+	      offset = strlen (pKey->name);
+	      strcpy (str + offset, "=");
+	      offset = strlen (pKey->name) + 1;
+	      strcpy (str + offset, pKey->value);
+	      fprintf (pFile, str);
+	      fprintf (pFile, "\n");
+	      pKey_pred = pKey;
+	      pKey = pKey->next;
+	      free (str);
+	    }
+	  while (pKey != pKey_pred);
+
+	  pSection_pred = pSection;
+	  pSection = pSection->next;
+	}
+      while (pSection != pSection_pred);
+    }
+  //nettoyage
+  fclose (pFile);
+}*/
+
+/******************************************************
+ * NOM:                                               *
+ *                  loadINI                           *
+ * SPECIFICATION:                                     *
+ *  Charge le contenu d'un fichier .ini en memoire    *
+ * ARGUMENTS:                                         *
+ *  nom du fichier                                    *
+ * ENVIRONNEMENT:                                     *
+ * VALEUR RETOURNEE:                                  *
+ *  pointeur sur la structure INI contenant le fichier*
+ *  .ini avec les structures decrites dans le .h      *
+ * EXCEPTION:                                         *
+ * ERR_FOPEN, ERR_MALLOC
+ ******************************************************/
+INI *
+_loadINI (char *fileName)
+{
+    FILE *pFile = NULL;
+    char *pBuf;
+    int nbRead = 0;
+    SECTION *pSection = NULL;
+    KEY *pKey = NULL;
+
+    INI *pIni = NULL;
+    pBuf = new char [MAX_LENGHT];
+
+    pFile = fopen (fileName, "r");
+    if (pFile == NULL)
+    {
+        pFile = fopen (fileName, "a");
+        if (pFile == NULL)
+            
+        return NULL;
+    }
+
+    pIni = new INI;
+    pIni->fileName = new char [strlen (fileName) + 1];
+    strcpy (pIni->fileName, fileName);
+    pIni->fils = NULL;
+    /* on lit ligne par ligne */
+    nbRead = readline (pFile, pBuf);
+    if (nbRead==-1) { fclose(pFile); delete  [] pIni->fileName; delete pIni; delete [] pBuf; return 0;}
+    while (nbRead != -1)
+    {
+
+        if ((pBuf[0] == '[') && (pBuf[strlen (pBuf) - 1] == ']'))
+        {
+            /* une section */
+            pSection = NULL;
+
+            pSection = _newSECTION (pBuf);
+            _addSECTION (pIni, pSection);
+        }
+
+        /* les cles de la section */
+        while (((nbRead = readline (pFile, pBuf)) !=-1) && (pBuf[0] != '['))
+        {
+            int ind = 0;
+            pKey = NULL;
+            if ((ind = _isKey (pBuf)) >= 0)
+            {
+
+                char *strName = NULL;
+                strName = new char [ind + 1];
+                strncpy (strName, pBuf, ind);
+                strName[ind] = '\0';
+                pKey = _newKEY (strName, pBuf + ind + 1);
+                _addKEY (pSection, pKey);
+                delete [] strName;
+            }
+        }
+    }
+
+    /*nettoyage */
+    delete [] pBuf;
+    fclose (pFile);
+    return pIni;
+}
+
+/******************************************************
+ * NOM:                                               *
+ *                 _isKey                             *
+ * SPECIFICATION:                                     *
+ *  determine si une chaine est une cle valide        *
+ * ARGUMENTS:                                         *
+ *  pointeur sur la chaine                            *
+ * ENVIRONNEMENT:                                     *
+ * VALEUR RETOURNEE:                                  *
+ *  indice du signe '=' si oui, -1 sinon              *
+ ******************************************************/
+int
+_isKey (char *str)
+{
+    int ind = 0;
+    for (ind; (ind < strlen (str)) && (str[ind] != '='); ind++);
+    if (str[ind] == '=')
+        return ind;
+    else
+        return -1;
+}
+
+
+/******************************************************
+ * NOM:                                               *
+ *                  _printINI                         *
+ * SPECIFICATION:                                     *
+ * affiche a l'ecran le contenu de structure INI      *
+ * ARGUMENTS:                                         *
+ *  pointeur sur la structure INI                     *
+ * ENVIRONNEMENT:                                     *
+ * VALEUR RETOURNEE:                                  *
+ ******************************************************/
+/*void
+_printINI (INI * pIni)
+{
+  SECTION *pSection_pred = NULL;
+  SECTION *pSection = NULL;
+  printf ("#Fichier INI#\n");
+  printf ("# %s #\n\n", pIni->fileName);
+  pSection = pIni->fils;
+  if (pSection != NULL)
+    {
+      do
+	{
+	  _printSECTION (pSection);
+	  pSection_pred = pSection;
+	  pSection = pSection->next;
+	}
+      while (pSection != pSection_pred);
+    }
+  printf ("\n#Fin du fichier INI#\n");
+}*/
+
+/******************************************************
+ * NOM:                                               *
+ *                  _printSECTION                     *
+ * SPECIFICATION:                                     *
+ * affiche a l'ecran le contenu de structure SECTION  *
+ * ARGUMENTS:                                         *
+ *  pointeur sur la structure SECTION                 *
+ * ENVIRONNEMENT:                                     *
+ * VALEUR RETOURNEE:                                  *
+ ******************************************************/
+/*void
+_printSECTION (SECTION * pSection)
+{
+  KEY *pKey = NULL;
+  KEY *pKey_pred = NULL;
+  printf ("%s\n", pSection->name);
+  pKey = pSection->fils;
+  if (pKey != NULL)
+    {
+      do
+	{
+	  _printKEY (pKey);
+	  pKey_pred = pKey;
+	  pKey = pKey->next;
+	}
+      while (pKey != pKey_pred);
+    }
+}*/
+
+/******************************************************
+ * NOM:                                               *
+ *                  _printKEY                         *
+ * SPECIFICATION:                                     *
+ * affiche a l'ecran le contenu de structure SECTION  *
+ * ARGUMENTS:                                         *
+ *  pointeur sur la structure SECTION                 *
+ * ENVIRONNEMENT:                                     *
+ * VALEUR RETOURNEE:                                  *
+ ******************************************************/
+/*
+ * void
+_printKEY (KEY * pKey)
+{
+  printf ("%s=%s\n", pKey->name, pKey->value);
+}*/
+
+/******************************************************
+ * NOM:                                               *
+ *                  printINI                          *
+ * SPECIFICATION:                                     *
+ * affiche a l'ecran le contenu du fichier .ini       *
+ * ARGUMENTS:                                         *
+ *  nom du fichier                                    *
+ * ENVIRONNEMENT:                                     *
+ * VALEUR RETOURNEE:                                  *
+ ******************************************************/
+
+/*void
+printINI (char *file)
+{
+  INI *pIni = NULL;
+  TRY
+  {
+    pIni = _loadINI (file);
+  }
+  CATCH (ERR_MALLOC)
+  {
+    printf ("Erreur d'allocation memoire en chargeant le fichier .ini:%s\n",
+	    file);
+    exit (EXIT_FAILURE);
+  }
+  CATCH (ERR_FOPEN)
+  {
+    printf ("Erreur en ouvrant le fichier .ini:%s\n", file);
+    exit (EXIT_FAILURE);
+  }
+  ENDTRY;
+  _printINI (pIni);
+  free (pIni);
+}*/
+
+/******************************************************
+ * NOM:                 jumpline                      *
+ * SPECIFICATION:                                     *
+ * fonction permettant de sauter des lignes dans le   *
+ * fichier a partir de la position courante dans le   *
+ * fichier                                            *
+ * ARGUMENTS:                                         *
+ * nombre de lignes a saute, pointeur sur le fichier  *
+ * ENVIRONNEMENT:                                     *
+ * VALEUR RETOURNEE: nombre de lignes sautees         *
+ ******************************************************/
+
+int
+jumpline (int nbline, FILE * pfile)
+{
+    int compteur = 0, c;
+
+    while ((compteur < nbline) && ((c = getc (pfile)) != EOF))
+    {
+        if (c == '\n')
+            compteur++;
+    }
+    return (compteur);
+}
+
+/******************************************************
+ * NOM:                readline                       *
+ * SPECIFICATION:                                     *
+ * recupere la ligne courante du fichier et renvoie le*
+ * nombre de caracteres lus                           *
+ * ARGUMENTS:                                         *
+ * pointeur sur le fichier a lire                     *
+ * pointeur sur le tableau recevant la ligne          *
+ * ENVIRONNEMENT:                                     *
+ * VALEUR RETOURNEE:                                  *
+ * nombre de caracteres lus                           *
+ ******************************************************/
+int
+readline (FILE * pfile, char *tab)
+{
+    int nbchar = 0;
+    char c;
+    while ((c = getc (pfile)) != '\n')
+    {
+        if (c == EOF)
+        {
+            break;
+        }
+        tab[nbchar++] = c;
+    }
+    tab[nbchar] = '\0';
+
+    while (nbchar>0 && tab[nbchar-1]==' ') {
+        tab[--nbchar] = '\0';
+    }
+
+    while (tab[0]==' ') for (int i=1; i<=nbchar; i++) tab[i-1]=tab[i];
+
+    if (c == EOF) nbchar=-1;
+
+    return (nbchar);
+}
+
+/******************************************************
+ * NOM:                m_malloc                       *
+ * SPECIFICATION:                                     *
+ *  clone de malloc renvoyant une exception           *
+ * ARGUMENTS:                                         *
+ * ENVIRONNEMENT:                                     *
+ * VALEUR RETOURNEE:                                  *
+ ******************************************************/
+
+/*
+void * m_malloc (size_t size)
+{
+  void *ptr = malloc (size);
+  if (ptr == NULL)
+    THROW (ERR_MALLOC);
+  else
+    return ptr;
+}*/
Index: /BAORadio/libindi/libindi/BAOControl/filetools.h
===================================================================
--- /BAORadio/libindi/libindi/BAOControl/filetools.h	(revision 503)
+++ /BAORadio/libindi/libindi/BAOControl/filetools.h	(revision 504)
@@ -57,5 +57,5 @@
 
 **********************************************************************************/
-
+int readINI (const char *sectionName, const char *pKeyName, char **ppStr, const char *fileName);
 
 char *writeINI (char *section, char *key, char *pKeyValue, char *fileName);
Index: /BAORadio/libindi/libindi/BAOControl/main.cpp
===================================================================
--- /BAORadio/libindi/libindi/BAOControl/main.cpp	(revision 504)
+++ /BAORadio/libindi/libindi/BAOControl/main.cpp	(revision 504)
@@ -0,0 +1,13 @@
+#include "baocontrol.h" 
+
+int main(int argc, char **argv)
+{   
+  BAOcontrol *appli;
+  
+  appli = new BAOcontrol();
+  
+  appli->init(argc, argv);
+  
+  delete appli;
+  
+} 
Index: /BAORadio/libindi/libindi/BAOControl/mouvements
===================================================================
--- /BAORadio/libindi/libindi/BAOControl/mouvements	(revision 503)
+++ /BAORadio/libindi/libindi/BAOControl/mouvements	(revision 504)
@@ -1,5 +1,9 @@
+[parametres]
+mode=tracking
+J2000=on
+
 [objet 1]
-date=07/11/2010
-heure=14:19:00
+date=19/06/2011
+heure=22:52:00
 duree=30
 ad=12:25:00
@@ -7,7 +11,14 @@
 
 [objet 2]
-date=07/11/2010
-heure=14:19:31
+date=19/06/2011
+heure=22:53:00
 duree=30
 ad=00:25:00
 de=89:00:00
+
+[objet 3]
+date=19/06/2011
+heure=22:54:00
+duree=30
+ad=00:25:00
+de=87:00:00
Index: /BAORadio/libindi/libindi/BAOControl/params
===================================================================
--- /BAORadio/libindi/libindi/BAOControl/params	(revision 503)
+++ /BAORadio/libindi/libindi/BAOControl/params	(revision 504)
@@ -4,12 +4,18 @@
 
 [coordonnees geographiques]
-latitude=48:41:56
-longitude=2:10:13
+latitude=48:51:00
+longitude=2:19:59
 
-[transit]
-delai=100
+[atmosphere]
+pression=1013
+temperature=10
 
-[tracking]
-delai=5
+[suivi]
+mode=tracking
+delai_transit=100
+delai_tracking=5
+
+[divers]
+couleurs=1
 
 
Index: /BAORadio/libindi/libindi/BAOControl/result
===================================================================
--- /BAORadio/libindi/libindi/BAOControl/result	(revision 504)
+++ /BAORadio/libindi/libindi/BAOControl/result	(revision 504)
@@ -0,0 +1,27 @@
+
+
+Results from query to  NASA/IPAC Extragalactic Database (NED),
+which is operated by the Jet Propulsion Laboratory, California Institute of
+Technology, under contract with the National Aeronautics and Space Administration.
+This work was (partially) supported by the US National Virtual Observatory
+development project, which is funded by the National Science Foundation
+under cooperative agreement AST0122449 with The Johns Hopkins University.
+
+
+
+queryDateTime:2011-06-26T14:47:53PDT
+
+
+
+Main Information Table for MESSIER 082
+
+
+
+Equinox:J2000.0
+
+
+
+CoordSystem:Equatorial
+
+No.|Object Name|RA(deg)|DEC(deg)|Type|Velocity|Redshift|Redshift Flag|Magnitude and Filter|Distance (arcmin)|References|Notes|Photometry Points|Positions|Redshift Points|Diameter Points|Associations
+1|MESSIER 082|148.96969 |  69.67938 |G|   203| 0.000677 |    | 9.30||1671|32|239|9|14|9|0
Index: /BAORadio/libindi/libindi/BAOTest/.kdev_include_paths
===================================================================
--- /BAORadio/libindi/libindi/BAOTest/.kdev_include_paths	(revision 504)
+++ /BAORadio/libindi/libindi/BAOTest/.kdev_include_paths	(revision 504)
@@ -0,0 +1,1 @@
+/home/richard/BAORadio/libindi/libindi/drivers/telescope
Index: /BAORadio/libindi/libindi/BAOTest/BAOtest_main.cpp
===================================================================
--- /BAORadio/libindi/libindi/BAOTest/BAOtest_main.cpp	(revision 503)
+++ /BAORadio/libindi/libindi/BAOTest/BAOtest_main.cpp	(revision 504)
@@ -69,5 +69,5 @@
     result.y=0;
 
-    if (str.length()>2)
+    if (str.length() > 2)
     {
         result.x=atoi(str.substr(2, 4).c_str());
@@ -203,5 +203,5 @@
                             if (Aleat)
                             {
-                                sprintf(chaine, "POSITION/%04i/%04i/\n", Pos.x, Pos.y);
+                                sprintf(chaine, "POSITION/%05i/%05i/\n", Pos.x, Pos.y);
                             }
                             else
Index: ORadio/libindi/libindi/BAOTest/baocontrol.h
===================================================================
--- /BAORadio/libindi/libindi/BAOTest/baocontrol.h	(revision 503)
+++ 	(revision )
@@ -1,93 +1,0 @@
-#include <iostream>
-#include <string.h>
-#include <sstream>
-#include "ClientSocket.h"
-#include "SocketException.h"
-#include <stdio.h>
-#include <pthread.h>
-#include <X11/Xlib.h>
-#include "filetools.h"
-#include "astro.h"
-#include "math.h"
-#include <time.h>
-#include <unistd.h>
-#include <sys/time.h>
-
-
-#define red "\033[0;31m"
-#define blue "\033[0;34m"
-#define green "\033[0;32m"
-#define black "\033[0;30m"
-
-#define MAXLOG 1000
-#define MAXOBJETS 100
-#define MAXANTENNES 100
-
-using namespace std;
-
-
-struct DefAntenne
-{
-    unsigned char ip;
-
-    char ok;
-};
-
-struct DefObjets
-{
-    double JJ;
-    double Duree;
-    char ad[10];
-    char de[10];
-    bool exec;
-};
-
-
-char Latitude[80];
-char Longitude[80];
-char Serveur[80];
-
-std::string logs[MAXLOG];
-
-std::stringstream os;
-
-int Port=0;
-int delaitransit=0;
-int delaitracking=0;
-int lognum=0;
-int numAntenne=0;
-int numobjets=0;
-int runnum=1;
-
-struct DefAntenne Antennes[MAXANTENNES];
-struct DefObjets objets[MAXOBJETS];
-
-bool NoExit=true;
-bool Transit=false;
-bool run=false;
-bool exitrun=false;
-
-ClientSocket *client_socket;
-Astro *astro;
-
-Display * d;
-Window w;
-GC noir, vert, rouge, gris;
-
-
-void initialiserFenetre();
-void Dessiner();
-void rouler(char* reponse);
-void LireReponse();
-void *my_thread_process (void * arg);
-bool Decomposition(std::string chaine, char type, float *a1, float *a2, float *a3);
-bool DecompositionCommande(std::string chaine, std::string commande, std::string *chaine1, std::string *chaine2);
-bool EncoyerCoordGeographiques();
-bool Connect(bool connect);
-bool Park();
-bool Abort();
-bool Goto(std::string ar, std::string dec, bool Transit);
-bool LectureFichierMouvements(char * fileName);
-bool Run(std::string fichier);
-void DecodageFonction(std::string chaine);
-bool ChargementParametres(); 
Index: /BAORadio/libindi/libindi/CMakeLists.txt
===================================================================
--- /BAORadio/libindi/libindi/CMakeLists.txt	(revision 503)
+++ /BAORadio/libindi/libindi/CMakeLists.txt	(revision 504)
@@ -1,14 +1,8 @@
 cmake_minimum_required(VERSION 2.4.7)
-
- if(COMMAND cmake_policy)
-      cmake_policy(SET CMP0003 NEW)
-    endif(COMMAND cmake_policy)
-
-
 
 ##################  INDI version  ################################
 set(INDI_SOVERSION "0")
 set(CMAKE_INDI_VERSION_MAJOR 0)
-set(CMAKE_INDI_VERSION_MINOR 7)
+set(CMAKE_INDI_VERSION_MINOR 8)
 set(CMAKE_INDI_VERSION_RELEASE 0)
 set(CMAKE_INDI_VERSION_STRING "${CMAKE_INDI_VERSION_MAJOR}.${CMAKE_INDI_VERSION_MINOR}.${CMAKE_INDI_VERSION_RELEASE}")
@@ -38,11 +32,17 @@
 find_package(ZLIB REQUIRED)
 
+FIND_PACKAGE(Boost)
+IF (BOOST_FOUND)
+    INCLUDE_DIRECTORIES(${BOOST_INCLUDE_DIR})
+ENDIF()
+
+
 macro_optional_find_package(USB)
-macro_log_feature(LIBUSB_FOUND "libusb" "User level access to USB devices" "http://indi.sf.net" FALSE "" "Provides support for USB based drivers in INDI.")
+macro_log_feature(LIBUSB_FOUND "libusb" "User level access to USB devices" "http://www.libusb.org" FALSE "" "Provides support for USB based drivers in INDI.")
 
 macro_optional_find_package(CFITSIO)
 
 if (NOT CFITSIO_FOUND OR CFITSIO_VERSION_MAJOR LESS 3)
-  message(FATAL_ERROR "CFITSIO version too old, Please install cfitsio 3.x and try again. http://indi.sf.net")
+  message(FATAL_ERROR "CFITSIO version too old, Please install cfitsio 3.x and try again. http://heasarc.gsfc.nasa.gov/fitsio/fitsio.html")
 endif (NOT CFITSIO_FOUND OR CFITSIO_VERSION_MAJOR LESS 3)
 
@@ -50,7 +50,4 @@
 macro_log_feature(CFITSIO_FOUND "libcfitsio" "A library for reading and writing data files in FITS (Flexible Image Transport System) data format" "http://indi.sf.net" FALSE "3.03" "Provides INDI with FITS I/O support.")
 
-
-macro_optional_find_package(FLI)
-macro_log_feature(FLI_FOUND "libfli" "Finger Lakes Instrument Library" "http://indi.sourceforge.net/" FALSE "1.71" "Provides INDI with support for controlling FLI CCDS & Filter Wheels.")
 
 macro_optional_find_package(Nova)
@@ -61,4 +58,10 @@
 check_include_files(termios.h TERMIOS_FOUND)
 macro_bool_to_01(TERMIOS_FOUND HAVE_TERMIOS_H)
+
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h )
+
+if(COMMAND cmake_policy)
+ cmake_policy(SET CMP0003 NEW)
+endif(COMMAND cmake_policy)
 
 include_directories( ${CMAKE_CURRENT_BINARY_DIR})
@@ -74,8 +77,4 @@
     include_directories(${NOVA_INCLUDE_DIR})
 endif (NOVA_FOUND)
-
-if (FLI_FOUND)
-    include_directories(${FLI_INCLUDE_DIR})
-endif (FLI_FOUND)
 
 set(liblilxml_SRCS  ${CMAKE_SOURCE_DIR}/libs/lilxml.c )
@@ -100,12 +99,17 @@
     )
 
-set (indibase_SRCS
+set (indiclient_SRCS
         ${CMAKE_SOURCE_DIR}/libs/indibase/basedriver.cpp
         ${CMAKE_SOURCE_DIR}/libs/indibase/baseclient.cpp
     )
 
-set (indidefaultdevice_SRCS
+set (indidriver_SRCS
         ${CMAKE_SOURCE_DIR}/libs/indibase/basedriver.cpp
         ${CMAKE_SOURCE_DIR}/libs/indibase/defaultdriver.cpp
+        ${CMAKE_SOURCE_DIR}/libs/indibase/indiccd.cpp
+        ${CMAKE_SOURCE_DIR}/libs/indibase/inditelescope.cpp
+        ${CMAKE_SOURCE_DIR}/libs/indibase/indifilterwheel.cpp
+        ${CMAKE_SOURCE_DIR}/libs/indibase/indifocuser.cpp
+        ${CMAKE_SOURCE_DIR}/libs/indibase/indiusbdevice.cpp
     )
 
@@ -127,8 +131,9 @@
 install(TARGETS indiserver RUNTIME DESTINATION bin )
 
-
-######################################
-######## INDI Shared Library #########
-######################################
+#################################################
+############# INDI Shared Library ###############
+# To offer lilxml and communination routines    #
+# Mostly used by generic clients                #
+#################################################
 add_library(indi SHARED ${libindicom_SRCS} ${liblilxml_SRCS})
 target_link_libraries(indi m z)
@@ -140,29 +145,27 @@
 target_link_libraries(indi ${CFITSIO_LIBRARIES})
 endif(CFITSIO_FOUND)
-if (FLI_FOUND)
-target_link_libraries(indi ${FLI_LIBRARIES})
-endif(FLI_FOUND)
 
 install(TARGETS indi LIBRARY DESTINATION lib${LIB_POSTFIX})
 set_target_properties(indi PROPERTIES VERSION ${CMAKE_INDI_VERSION_STRING} SOVERSION ${INDI_SOVERSION})
 
-
-######################################
-######## INDI Static Library #########
-######################################
-add_library(indidriver STATIC ${indimain_SRCS})
+##################################################
+############ INDI Main Static Library ############
+# To link with main() for 3rd party drivers      #
+##################################################
+add_library(indimain STATIC ${indimain_SRCS})
+install(TARGETS indimain ARCHIVE DESTINATION lib${LIB_POSTFIX})
+
+##################################################
+###### INDI Default Driver Static Library ########
+# To link with main() and indibase classes       #
+##################################################
+add_library(indidriver STATIC ${indimain_SRCS} ${indidriver_SRCS})
 install(TARGETS indidriver ARCHIVE DESTINATION lib${LIB_POSTFIX})
 
-##############################################
-######## INDI Default Driver Library #########
-##############################################
-add_library(indidefaultdriver STATIC ${indimain_SRCS} ${indidefaultdevice_SRCS})
-install(TARGETS indidefaultdriver ARCHIVE DESTINATION lib${LIB_POSTFIX})
-
-##############################################
-######## INDI Client Library #########
-##############################################
-add_library(indiclient STATIC ${indibase_SRCS})
-target_link_libraries(indiclient indi)
+##################################################
+########### INDI Client Static Library ###########
+##################################################
+add_library(indiclient STATIC ${indiclient_SRCS})
+target_link_libraries(indiclient indi pthread)
 install(TARGETS indiclient ARCHIVE DESTINATION lib${LIB_POSTFIX})
 
@@ -324,25 +327,64 @@
 install(TARGETS indi_BAO RUNTIME DESTINATION bin )
 
+########### Syncscan ###############
+set(synscan_SRCS
+   ${indimain_SRCS}
+   ${CMAKE_SOURCE_DIR}/drivers/telescope/synscanmount.cpp )
+
+add_executable(indi_synscan ${synscan_SRCS} ${liblilxml_SRCS} ${libindicom_SRCS})
+
+target_link_libraries(indi_synscan indidriver m z)
+
+if (NOVA_FOUND)
+  target_link_libraries(indi_synscan ${NOVA_LIBRARIES})
+endif (NOVA_FOUND)
+
+install(TARGETS indi_synscan RUNTIME DESTINATION bin )
+
+########### Telescope Simulator ##############
+set(telescopesimulator_SRCS
+        ${indimain_SRCS}
+        ${CMAKE_SOURCE_DIR}/drivers/telescope/telescope_simulator.cpp
+   )
+
+add_executable(indi_simulator_telescope ${telescopesimulator_SRCS} ${liblilxml_SRCS} ${libindicom_SRCS})
+
+target_link_libraries(indi_simulator_telescope indidriver ${CFITSIO_LIBRARIES} m z pthread)
+
+if (NOVA_FOUND)
+  target_link_libraries(indi_simulator_telescope ${NOVA_LIBRARIES})
+endif (NOVA_FOUND)
+
+install(TARGETS indi_simulator_telescope RUNTIME DESTINATION bin )
+
 #####################################
 ########## FOCUSER GROUP ############
 #####################################
 
-###### FLI Precision Digital Focuser ######
-if (FLI_FOUND)
-set(flipdf_SRCS
-	${indimain_SRCS}
-	${CMAKE_SOURCE_DIR}/drivers/focuser/fli_pdf.c
-)
-
-add_executable(indi_fli_pdf ${flipdf_SRCS} ${liblilxml_SRCS} ${libindicom_SRCS})
-
-target_link_libraries(indi_fli_pdf m ${FLI_LIBRARIES})
-
-if (NOVA_FOUND)
-  target_link_libraries(indi_fli_pdf ${NOVA_LIBRARIES})
-endif (NOVA_FOUND)
-
-install(TARGETS indi_fli_pdf RUNTIME DESTINATION bin )
-endif(FLI_FOUND)
+########### CCD Simulator ##############
+if (CFITSIO_FOUND)
+
+set(ccdsimulator_SRCS
+        ${indimain_SRCS}
+        ${CMAKE_SOURCE_DIR}/drivers/ccd/ccd_simulator.cpp
+   )
+
+add_executable(indi_simulator_ccd ${ccdsimulator_SRCS} ${liblilxml_SRCS} ${libindicom_SRCS})
+
+target_link_libraries(indi_simulator_ccd indidriver ${CFITSIO_LIBRARIES} m z pthread)
+
+if (NOVA_FOUND)
+  target_link_libraries(indi_simulator_ccd ${NOVA_LIBRARIES})
+endif (NOVA_FOUND)
+
+install(TARGETS indi_simulator_ccd RUNTIME DESTINATION bin )
+
+endif (CFITSIO_FOUND)
+
+
+#####################################
+########## FOCUSER GROUP ############
+#####################################
+
 #################################################################################
 
@@ -355,13 +397,34 @@
    )
 
-add_executable(indi_robofocus ${robofocus_SRCS} ${liblilxml_SRCS} ${libindicom_SRCS})
-
-target_link_libraries(indi_robofocus m)
-
-if (NOVA_FOUND)
-  target_link_libraries(indi_robofocus ${NOVA_LIBRARIES})
-endif (NOVA_FOUND)
-
-install(TARGETS indi_robofocus RUNTIME DESTINATION bin )
+add_executable(indi_robo_focus ${robofocus_SRCS} ${liblilxml_SRCS} ${libindicom_SRCS})
+
+target_link_libraries(indi_robo_focus m)
+
+if (NOVA_FOUND)
+  target_link_libraries(indi_robo_focus ${NOVA_LIBRARIES})
+endif (NOVA_FOUND)
+
+install(TARGETS indi_robo_focus RUNTIME DESTINATION bin )
+
+################ Optec TCF-S ################
+
+set(tcfs_SRCS
+        ${indimain_SRCS}
+        ${CMAKE_SOURCE_DIR}/drivers/focuser/tcfs.cpp
+   )
+
+add_executable(indi_tcfs_focus ${tcfs_SRCS} ${liblilxml_SRCS} ${libindicom_SRCS})
+
+target_link_libraries(indi_tcfs_focus indidriver m z)
+
+if (NOVA_FOUND)
+  target_link_libraries(indi_tcfs_focus ${NOVA_LIBRARIES})
+endif (NOVA_FOUND)
+
+install(TARGETS indi_tcfs_focus RUNTIME DESTINATION bin )
+
+file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/make_tcfs_symlink.cmake
+"exec_program(${CMAKE_COMMAND} ARGS -E create_symlink ${BIN_INSTALL_DIR}/indi_tcfs_focus ${BUILD_ROOT}${BIN_INSTALL_DIR}/indi_tcfs3_focus)\n")
+set_target_properties(indi_tcfs_focus PROPERTIES POST_INSTALL_SCRIPT ${CMAKE_CURRENT_BINARY_DIR}/make_tcfs_symlink.cmake)
 
 #################################################################################
@@ -387,48 +450,20 @@
 install(TARGETS indi_trutech_wheel RUNTIME DESTINATION bin )
 
-#################################################################################
-
-########## FLI Filter Wheel ############
-if (FLI_FOUND)
-set(fliwheel_SRCS
-	${indimain_SRCS}
-	${CMAKE_SOURCE_DIR}/drivers/filter_wheel/fli_wheel.c
-   )
-
-add_executable(indi_fli_wheel ${fliwheel_SRCS}  ${liblilxml_SRCS} ${libindicom_SRCS})
-
-target_link_libraries(indi_fli_wheel ${FLI_LIBRARIES} m)
-
-if (NOVA_FOUND)
-  target_link_libraries(indi_fli_wheel ${NOVA_LIBRARIES})
-endif (NOVA_FOUND)
-
-install(TARGETS indi_fli_wheel RUNTIME DESTINATION bin )
-endif (FLI_FOUND)
-#################################################################################
-
-#######################################
-############# CCD GROUP ###############
-#######################################
-
-############# FLI CCD ###############
-if (CFITSIO_FOUND AND FLI_FOUND)
-
-set(fliccd_SRCS
-	${indimain_SRCS}
-	${CMAKE_SOURCE_DIR}/drivers/ccd/fli_ccd.c
-)
-
-add_executable(indi_fli_ccd ${fliccd_SRCS} ${liblilxml_SRCS} ${libindicom_SRCS})
-
-target_link_libraries(indi_fli_ccd ${FLI_LIBRARIES} ${CFITSIO_LIBRARIES} m z)
-
-if (NOVA_FOUND)
-  target_link_libraries(indi_fli_ccd ${NOVA_LIBRARIES})
-endif (NOVA_FOUND)
-
-install(TARGETS indi_fli_ccd RUNTIME DESTINATION bin )
-
-endif (CFITSIO_FOUND AND FLI_FOUND)
+########### Filter Simulator ##############
+set(filtersimulator_SRCS
+        ${indimain_SRCS}
+        ${CMAKE_SOURCE_DIR}/drivers/filter_wheel/filter_simulator.cpp
+   )
+
+add_executable(indi_simulator_wheel ${filtersimulator_SRCS} ${liblilxml_SRCS} ${libindicom_SRCS})
+
+target_link_libraries(indi_simulator_wheel indidriver ${CFITSIO_LIBRARIES} m z pthread)
+
+if (NOVA_FOUND)
+  target_link_libraries(indi_simulator_wheel ${NOVA_LIBRARIES})
+endif (NOVA_FOUND)
+
+install(TARGETS indi_simulator_wheel RUNTIME DESTINATION bin )
+
 #################################################################################
 
@@ -458,4 +493,5 @@
 
 ### Meade Lunar Planetary Imager ########
+if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
 if (CFITSIO_FOUND)
 
@@ -479,8 +515,10 @@
 
 endif (CFITSIO_FOUND)
+endif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
 
 #################################################################################
 
 ########### V4L Philips ##############
+if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
 if (CFITSIO_FOUND)
 
@@ -503,8 +541,10 @@
 
 endif (CFITSIO_FOUND)
+endif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
 
 #################################################################################
 
 ########### Generic V4L Driver ###############
+if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
 if (CFITSIO_FOUND)
 
@@ -526,4 +566,5 @@
 
 endif (CFITSIO_FOUND)
+endif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
 
 #################################################################################
@@ -630,4 +671,6 @@
 
 ########### Tutorial four ##############
+if (CFITSIO_FOUND)
+
 set(tutorialfour_SRCS
         ${indimain_SRCS}
@@ -637,5 +680,5 @@
 add_executable(tutorial_four ${tutorialfour_SRCS} ${liblilxml_SRCS} ${libindicom_SRCS})
 
-target_link_libraries(tutorial_four indidefaultdriver indiclient m z pthread)
+target_link_libraries(tutorial_four indidriver ${CFITSIO_LIBRARIES} m z pthread)
 
 if (NOVA_FOUND)
@@ -643,4 +686,5 @@
 endif (NOVA_FOUND)
 
+endif (CFITSIO_FOUND)
 
 ########### Tutorial dome ##############
@@ -672,14 +716,30 @@
 endif (NOVA_FOUND)
 
-#################################################################################
-
-install( FILES drivers.xml DESTINATION ${DATA_INSTALL_DIR})
+
+########### Client Tutorial ##############
+set(tutorialclient_SRCS
+        ${CMAKE_SOURCE_DIR}/examples/tutorial_client.cpp
+   )
+
+add_executable(tutorial_client ${tutorialclient_SRCS} ${liblilxml_SRCS} ${libindicom_SRCS})
+
+target_link_libraries(tutorial_client indiclient m)
+
+if (NOVA_FOUND)
+  target_link_libraries(tutorial_client ${NOVA_LIBRARIES})
+endif (NOVA_FOUND)
+
+#################################################################################
+
+install( FILES drivers.xml ${CMAKE_SOURCE_DIR}/drivers/focuser/indi_tcfs_sk.xml DESTINATION ${DATA_INSTALL_DIR})
 
 install( FILES indiapi.h indidevapi.h base64.h eventloop.h indidriver.h ${CMAKE_SOURCE_DIR}/libs/lilxml.h ${CMAKE_SOURCE_DIR}/libs/indibase/indibase.h
 ${CMAKE_SOURCE_DIR}/libs/indibase/basedriver.h  ${CMAKE_SOURCE_DIR}/libs/indibase/defaultdriver.h
+${CMAKE_SOURCE_DIR}/libs/indibase/indiccd.h  ${CMAKE_SOURCE_DIR}/libs/indibase/indifilterwheel.h
+${CMAKE_SOURCE_DIR}/libs/indibase/indifocuser.h  ${CMAKE_SOURCE_DIR}/libs/indibase/inditelescope.h
 ${CMAKE_SOURCE_DIR}/libs/indibase/baseclient.h ${CMAKE_SOURCE_DIR}/libs/indicom.h
+${CMAKE_SOURCE_DIR}/libs/indibase/indiusbdevice.h
  DESTINATION ${INCLUDE_INSTALL_DIR}/libindi COMPONENT Devel)
 
 configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libindi.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/libindi.pc @ONLY)
 install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libindi.pc DESTINATION ${PKGCONFIG_INSTALL_PREFIX})
-
Index: /BAORadio/libindi/libindi/ChangeLog
===================================================================
--- /BAORadio/libindi/libindi/ChangeLog	(revision 503)
+++ /BAORadio/libindi/libindi/ChangeLog	(revision 504)
@@ -1,2 +1,15 @@
+From 0.7.2 to 0.8
+
+      # TCF-S Focuser driver.
+      # Synscan Telescope driver.
+
+From 0.7.0 to 0.7.1
+
+      # Fixed change filter bug in true technology filter wheel. (JM)
+      # setINDI updated and improved. (ED)
+      # Improved INDI::Mediator functionality. (JM)
+      # Fixed buffer reading in INDI::BaseClient. (JM)
+      # Add new tutorial for INDI::BaseClient. (JM).
+
 From 0.6.2 to 0.7.0
 
Index: /BAORadio/libindi/libindi/INSTALL
===================================================================
--- /BAORadio/libindi/libindi/INSTALL	(revision 503)
+++ /BAORadio/libindi/libindi/INSTALL	(revision 504)
@@ -1,3 +1,3 @@
-INDI Library Setup 0.7.0
+INDI Library Setup 0.8.0
 ========================
 
@@ -22,7 +22,2 @@
 + cfitsio >= 3.0
 
-You can download packages for the dependencies above from SUSE BuildService:
-
-http://software.opensuse.org/search
-
-The packages are available for all major distributions.
Index: /BAORadio/libindi/libindi/README
===================================================================
--- /BAORadio/libindi/libindi/README	(revision 503)
+++ /BAORadio/libindi/libindi/README	(revision 504)
@@ -1,4 +1,4 @@
-libindi v0.6.2
-==============
+libindi v0.8
+============
 
 The code here demonstrates the use of INDI, an Instrument-Neutral Device
@@ -103,4 +103,3 @@
 	more stuff
 
-! For RCS Only -- Do Not Edit
-! @(#) $RCSfile$ $Date: 2004-02-03 09:34:32 +0300 (Tue, 03 Feb 2004) $ $Revision: 284704 $ $Name:  $
+
Index: /BAORadio/libindi/libindi/README.drivers
===================================================================
--- /BAORadio/libindi/libindi/README.drivers	(revision 503)
+++ /BAORadio/libindi/libindi/README.drivers	(revision 504)
@@ -10,6 +10,6 @@
 You can find more up to date information on INDI drivers from the following sources:
 
-1. INDI Device Profiles: http://indi.sf.net/devices.html
-2. INDI Wiki: http://wiki.kde.org/tiki-index.php?page=indi
+1. INDI Device Profiles: http://www.indilib.org
+2. INDI Wiki: http://www.indilib.org
 
 
Index: /BAORadio/libindi/libindi/cmake_modules/FindFLI.cmake
===================================================================
--- /BAORadio/libindi/libindi/cmake_modules/FindFLI.cmake	(revision 503)
+++ /BAORadio/libindi/libindi/cmake_modules/FindFLI.cmake	(revision 504)
@@ -45,5 +45,5 @@
   else (FLI_FOUND)
     if (FLI_FIND_REQUIRED)
-      message(FATAL_ERROR "FLI not found. Please install libfli1-devel. http://indi.sf.net")
+      message(FATAL_ERROR "FLI not found. Please install libfli-dev. http://www.indilib.org")
     endif (FLI_FIND_REQUIRED)
   endif (FLI_FOUND)
Index: /BAORadio/libindi/libindi/cmake_modules/FindINDI.cmake
===================================================================
--- /BAORadio/libindi/libindi/cmake_modules/FindINDI.cmake	(revision 503)
+++ /BAORadio/libindi/libindi/cmake_modules/FindINDI.cmake	(revision 504)
@@ -5,8 +5,10 @@
 #  INDI_INCLUDE_DIR - the INDI include directory
 #  INDI_LIBRARIES - Link these to use INDI
-#  INDI_DEVICE_LIBRARY - The indi default device library
+#  INDI_MAIN_LIBRARIES - Link to these to build INDI drivers with main()
+#  INDI_DRIVER_LIBRARIES - Link to these to build INDI drivers with indibase support
+#  INDI_CLIENT_LIBRARIES - Link to these to build INDI clients
 #  INDI_DATA_DIR - INDI shared data dir.
 
-# Copyright (c) 2010, Jasem Mutlaq <mutlaqja@ikarustech.com>
+# Copyright (c) 2011, Jasem Mutlaq <mutlaqja@ikarustech.com>
 # Based on FindLibfacile by Carsten Niehaus, <cniehaus@gmx.de>
 #
@@ -14,5 +16,5 @@
 # For details see the accompanying COPYING-CMAKE-SCRIPTS file.
 
-if (INDI_INCLUDE_DIR AND INDI_LIBRARIES AND INDI_DRIVER_LIBRARIES)
+if (INDI_INCLUDE_DIR AND INDI_DATA_DIR AND INDI_LIBRARIES AND INDI_DRIVER_LIBRARIES AND INDI_MAIN_LIBRARIES)
 
   # in cache already
@@ -21,5 +23,5 @@
 
 
-else (INDI_INCLUDE_DIR AND INDI_LIBRARIES AND INDI_DRIVER_LIBRARIES)
+else (INDI_INCLUDE_DIR AND INDI_DATA_DIR AND INDI_LIBRARIES AND INDI_DRIVER_LIBRARIES AND INDI_MAIN_LIBRARIES)
 
   find_path(INDI_INCLUDE_DIR indidevapi.h
@@ -30,9 +32,12 @@
 
  find_path(INDI_DATA_DIR drivers.xml
+    PATHS /usr/share /usr/local/share /opt ${GNUWIN32_DIR}/share
     PATH_SUFFIXES indi
-    /usr
-    /usr/local
-    /opt
-    ${GNUWIN32_DIR}/share
+  )
+
+  find_library(INDI_LIBRARIES NAMES indi
+    PATHS
+    ${_obLinkDir}
+    ${GNUWIN32_DIR}/lib
   )
 
@@ -43,5 +48,5 @@
   )
 
-  find_library(INDI_DEVICE_LIBRARIES NAMES indidefaultdevice
+  find_library(INDI_MAIN_LIBRARIES NAMES indimain
     PATHS
     ${_obLinkDir}
@@ -49,6 +54,5 @@
   )
 
-
-  find_library(INDI_LIBRARIES NAMES indi
+  find_library(INDI_CLIENT_LIBRARIES NAMES indiclient
     PATHS
     ${_obLinkDir}
@@ -56,22 +60,23 @@
   )
 
-  if(INDI_INCLUDE_DIR AND INDI_LIBRARIES AND INDI_DRIVER_LIBRARIES)
+  if(INDI_INCLUDE_DIR AND INDI_DATA_DIR AND INDI_LIBRARIES AND INDI_DRIVER_LIBRARIES AND INDI_MAIN_LIBRARIES)
     set(INDI_FOUND TRUE)
-  else (INDI_INCLUDE_DIR AND INDI_LIBRARIES AND INDI_DRIVER_LIBRARIES)
+  else (INDI_INCLUDE_DIR AND INDI_DATA_DIR AND INDI_LIBRARIES AND INDI_DRIVER_LIBRARIES AND INDI_MAIN_LIBRARIES)
     set(INDI_FOUND FALSE)
-  endif(INDI_INCLUDE_DIR AND INDI_LIBRARIES AND INDI_DRIVER_LIBRARIES)
+  endif(INDI_INCLUDE_DIR AND INDI_DATA_DIR AND INDI_LIBRARIES AND INDI_DRIVER_LIBRARIES AND INDI_MAIN_LIBRARIES)
 
 
   if (INDI_FOUND)
     if (NOT INDI_FIND_QUIETLY)
-      message(STATUS "Found INDI: ${INDI_LIBRARIES}, ${INDI_DRIVER_LIBRARIES}")
+      message(STATUS "Found INDI: ${INDI_LIBRARIES}, ${INDI_MAIN_LIBRARIES}")
+      message(STATUS "INDI Include: ${INDI_INCLUDE_DIR}, INDI Data: ${INDI_DATA_DIR}")
     endif (NOT INDI_FIND_QUIETLY)
   else (INDI_FOUND)
     if (INDI_FIND_REQUIRED)
-      message(FATAL_ERROR "indi-devel not found. Cannot compile INDI drivers. Please install indi-devel and try again. http://www.indilib.org")
+      message(FATAL_ERROR "indi-dev not found. Cannot compile INDI drivers. Please install indi-dev and try again. http://www.indilib.org")
     endif (INDI_FIND_REQUIRED)
   endif (INDI_FOUND)
 
-  mark_as_advanced(INDI_INCLUDE_DIR INDI_LIBRARIES INDI_DRIVER_LIBRARIES INDI_DEVICE_LIBRARIES INDI_DATA_DIR)
+  mark_as_advanced(INDI_INCLUDE_DIR INDI_DATA_DIR INDI_LIBRARIES INDI_DRIVER_LIBRARIES INDI_MAIN_LIBRARIES INDI_CLIENT_LIBRARIES)
 
-endif (INDI_INCLUDE_DIR AND INDI_LIBRARIES AND INDI_DRIVER_LIBRARIES)
+endif (INDI_INCLUDE_DIR AND INDI_DATA_DIR AND INDI_LIBRARIES AND INDI_DRIVER_LIBRARIES AND INDI_MAIN_LIBRARIES)
Index: /BAORadio/libindi/libindi/config.h.cmake
===================================================================
--- /BAORadio/libindi/libindi/config.h.cmake	(revision 503)
+++ /BAORadio/libindi/libindi/config.h.cmake	(revision 504)
@@ -13,2 +13,3 @@
 /* Define if you have libnova.h */
 #cmakedefine   HAVE_NOVA_H 1
+
Index: /BAORadio/libindi/libindi/drivers.xml
===================================================================
--- /BAORadio/libindi/libindi/drivers.xml	(revision 503)
+++ /BAORadio/libindi/libindi/drivers.xml	(revision 504)
@@ -1,9 +1,9 @@
 <devGroup group="Telescopes">
+        <device label="BAO" focal_length="" aperture="">
+		<driver name="BAO">indi_BAO</driver>
+		<version>1.0</version>
+	</device>
 	<device label="LX200 Basic" focal_length="" aperture="">
 		<driver name="LX200 Basic">indi_lx200basic</driver>
-		<version>1.0</version>
-	</device>
-	<device label="BAO" focal_length="" aperture="">
-		<driver name="BAO">indi_BAO</driver>
 		<version>1.0</version>
 	</device>
@@ -92,20 +92,44 @@
 		<version>0.2</version>
 	</device>
+        <device label="SynScan" focal_length="" aperture="">
+                <driver name="SynScan">indi_synscan</driver>
+                <version>1.0</version>
+        </device>
+        <device label="EQ6" focal_length="" aperture="">
+                <driver name="SynScan">indi_synscan</driver>
+                <version>1.0</version>
+        </device>
+        <device label="HEQ5" focal_length="" aperture="">
+                <driver name="SynScan">indi_synscan</driver>
+                <version>1.0</version>
+        </device>
+        <device label="NEQ3" focal_length="" aperture="">
+                <driver name="SynScan">indi_synscan</driver>
+                <version>1.0</version>
+        </device>
+        <device label="Telescope Simulator" focal_length="" aperture="">
+                <driver name="Telescope Simulator">indi_simulator_telescope</driver>
+                <version>1.0</version>
+        </device>
+</devGroup>
+<devGroup group="Focusers">
+	<device label="Robo Focus">
+                <driver name="Robofocus">indi_robo_focus</driver>
+		<version>0.1</version>
+	</device>
+        <device label="Optec TCF-S">
+                <driver name="Optec TCF-S">indi_tcfs_focus</driver>
+                <version>0.1</version>
+        </device>
+        <device label="Optec TCF-S3">
+                <driver name="Optec TCF-S">indi_tcfs3_focus</driver>
+                <version>0.1</version>
+        </device>
 </devGroup>
 <devGroup group="CCDs">
-	<device label="FLI CCD">
-		<driver name="FLI CCD">indi_fli_ccd</driver>
-		<version>1.0</version>
-	</device>
-</devGroup>
-<devGroup group="Focusers">
-	<device label="FLI PDF">
-		<driver name="FLI PDF">indi_fli_pdf</driver>
-		<version>0.1</version>
-	</device>
-	<device label="Robo Focus">
-		<driver name="Robofocus">indi_robofocus</driver>
-		<version>0.1</version>
-	</device>
+        <device label="CCD Simulator">
+                <driver name="CCD Simulator">indi_simulator_ccd</driver>
+                <version>0.1</version>
+        </device>
 </devGroup>
 <devGroup group="Filter Wheels">
@@ -118,4 +142,8 @@
 		<version>0.1</version>
     	</device>
+        <device label="Filter Simulator">
+                <driver name="Filter Simulator">indi_simulator_wheel</driver>
+                <version>0.1</version>
+        </device>
 </devGroup>
 <devGroup group="Video">
Index: /BAORadio/libindi/libindi/drivers/ccd/ccd_simulator.cpp
===================================================================
--- /BAORadio/libindi/libindi/drivers/ccd/ccd_simulator.cpp	(revision 504)
+++ /BAORadio/libindi/libindi/drivers/ccd/ccd_simulator.cpp	(revision 504)
@@ -0,0 +1,971 @@
+/*******************************************************************************
+  Copyright(c) 2010 Gerry Rozema. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published by the Free
+  Software Foundation; either version 2 of the License, or (at your option)
+  any later version.
+
+  This program is distributed in the hope that it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc., 59
+  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+  The full GNU General Public License is included in this distribution in the
+  file called LICENSE.
+*******************************************************************************/
+#include "ccd_simulator.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <math.h>
+#include <string.h>
+
+
+// We declare an auto pointer to ccdsim.
+std::auto_ptr<CCDSim> ccdsim(0);
+
+void ISPoll(void *p);
+
+
+void ISInit()
+{
+   static int isInit =0;
+
+   if (isInit == 1)
+       return;
+
+    isInit = 1;
+    if(ccdsim.get() == 0) ccdsim.reset(new CCDSim());
+    //IEAddTimer(POLLMS, ISPoll, NULL);
+
+}
+
+void ISGetProperties(const char *dev)
+{
+        ISInit();
+        ccdsim->ISGetProperties(dev);
+}
+
+void ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int num)
+{
+        ISInit();
+        ccdsim->ISNewSwitch(dev, name, states, names, num);
+}
+
+void ISNewText(	const char *dev, const char *name, char *texts[], char *names[], int num)
+{
+        ISInit();
+        ccdsim->ISNewText(dev, name, texts, names, num);
+}
+
+void ISNewNumber(const char *dev, const char *name, double values[], char *names[], int num)
+{
+        ISInit();
+        ccdsim->ISNewNumber(dev, name, values, names, num);
+}
+
+void ISNewBLOB (const char *dev, const char *name, int sizes[], int blobsizes[], char *blobs[], char *formats[], char *names[], int n)
+{
+  INDI_UNUSED(dev);
+  INDI_UNUSED(name);
+  INDI_UNUSED(sizes);
+  INDI_UNUSED(blobsizes);
+  INDI_UNUSED(blobs);
+  INDI_UNUSED(formats);
+  INDI_UNUSED(names);
+  INDI_UNUSED(n);
+}
+void ISSnoopDevice (XMLEle *root)
+{
+    INDI_UNUSED(root);
+}
+
+
+CCDSim::CCDSim()
+{
+    //ctor
+    testvalue=0;
+    AbortGuideFrame=false;
+    ShowStarField=true;
+
+    HasSt4Port=true;
+    HasGuideHead=false;
+
+
+    RA=9.95;
+    Dec=68.9;
+
+    //  sxvh9
+    bias=1500;
+    maxnoise=20;
+    maxval=65000;
+    limitingmag=11.5;
+    saturationmag=2;
+    focallength=1280;   //  focal length of the telescope in millimeters
+    OAGoffset=0;    //  An oag is offset this much from center of scope position (arcminutes);
+    skyglow=40;
+
+    seeing=3.5;         //  fwhm of our stars
+    ImageScalex=1.0;    //  preset with a valid non-zero
+    ImageScaley=1.0;
+    //focallength=175;   //  focal length of the telescope in millimeters
+    time(&RunStart);
+
+    //  Our PEPeriod is 8 minutes
+    //  and we have a 22 arcsecond swing
+    PEPeriod=8*60;
+    PEMax=11;
+    GuideRate=7;    //  guide rate is 7 arcseconds per second
+    TimeFactor=1;
+
+}
+
+bool CCDSim::SetupParms()
+{
+    SetCCDParams(SimulatorSettingsN[0].value,SimulatorSettingsN[1].value,16,SimulatorSettingsN[2].value,SimulatorSettingsN[3].value);
+    //  Kwiq
+    maxnoise=SimulatorSettingsN[10].value;
+    skyglow=SimulatorSettingsN[11].value;
+    maxval=SimulatorSettingsN[4].value;
+    bias=SimulatorSettingsN[5].value;
+    limitingmag=SimulatorSettingsN[7].value;
+    saturationmag=SimulatorSettingsN[6].value;
+    focallength=SimulatorSettingsN[8].value;   //  focal length of the telescope in millimeters
+    OAGoffset=SimulatorSettingsN[12].value;    //  An oag is offset this much from center of scope position (arcminutes);
+    seeing=SimulatorSettingsN[9].value;        //  we get real fat stars in this one
+
+
+    if(RawFrame != NULL) delete RawFrame;
+    RawFrameSize=XRes*YRes;                 //  this is pixel count
+    RawFrameSize=RawFrameSize*2;            //  Each pixel is 2 bytes
+    RawFrameSize+=512;                      //  leave a little extra at the end
+    RawFrame=new char[RawFrameSize];
+
+    return true;
+}
+
+bool CCDSim::Connect()
+{
+
+    SetupParms();
+
+    if(HasGuideHead) {
+        SetGuidHeadParams(500,290,8,9.8,12.6);
+        RawGuideSize=GXRes*GYRes;                 //  this is pixel count
+        RawGuideSize+=512;                      //  leave a little extra at the end
+        RawGuiderFrame=new char[RawGuideSize];
+    }
+
+    SetTimer(1000);     //  start the timer
+    return true;
+}
+
+CCDSim::~CCDSim()
+{
+    //dtor
+}
+
+const char * CCDSim::getDefaultName()
+{
+    //fprintf(stderr,"Arrived in getDefaultName and deviceName returns '%s'\n",deviceName());
+    //if(strlen(deviceName())==0) {
+        return (char *)"CCD Simulator";
+    //} else {
+    //    char n[500];
+    //    strcpy(n,deviceName());
+    //    return n;
+    //}
+}
+
+bool CCDSim::initProperties()
+{
+    //  Most hardware layers wont actually have indi properties defined
+    //  but the simulators are a special case
+    INDI::CCD::initProperties();
+
+    IUFillNumber(&EqN[0],"RA","Ra (hh:mm:ss)","%010.6m",0,24,0,0);
+    IUFillNumber(&EqN[1],"DEC","Dec (dd:mm:ss)","%010.6m",-90,90,0,0);
+    IUFillNumberVector(&EqNV,EqN,2,"","EQUATORIAL_EOD_COORD","Eq. Coordinates","Main Control",IP_RW,60,IPS_IDLE);
+    //IUFillNumberVector(&EqNV,EqN,2,deviceName(),"EQUATORIAL_EOD_COORD","Eq. Coordinates","Main Control",IP_RW,60,IPS_IDLE);
+
+    SimulatorSettingsNV = new INumberVectorProperty;
+    IUFillNumber(&SimulatorSettingsN[0],"SIM_XRES","CCD X resolution","%4.0f",0,2048,0,1280);
+    IUFillNumber(&SimulatorSettingsN[1],"SIM_YRES","CCD Y resolution","%4.0f",0,2048,0,1024);
+    IUFillNumber(&SimulatorSettingsN[2],"SIM_XSIZE","CCD X Pixel Size","%4.2f",0,60,0,5.2);
+    IUFillNumber(&SimulatorSettingsN[3],"SIM_YSIZE","CCD Y Pixel Size","%4.2f",0,60,0,5.2);
+    IUFillNumber(&SimulatorSettingsN[4],"SIM_MAXVAL","CCD Maximum ADU","%4.0f",0,65000,0,65000);
+    IUFillNumber(&SimulatorSettingsN[5],"SIM_BIAS","CCD Bias","%4.0f",0,6000,0,1500);
+    IUFillNumber(&SimulatorSettingsN[6],"SIM_SATURATION","Saturation Mag","%4.1f",0,20,0,1.0);
+    IUFillNumber(&SimulatorSettingsN[7],"SIM_LIMITINGMAG","Limiting Mag","%4.1f",0,20,0,20);
+    IUFillNumber(&SimulatorSettingsN[8],"SIM_FOCALLENGTH","Focal Length","%4.0f",0,60000,0,1000);
+    IUFillNumber(&SimulatorSettingsN[9],"SIM_FWHM","FWHM (arcseconds)","%4.2f",0,60,0,3.5);
+    IUFillNumber(&SimulatorSettingsN[10],"SIM_NOISE","CCD Noise","%4.0f",0,6000,0,50);
+    IUFillNumber(&SimulatorSettingsN[11],"SIM_SKYGLOW","Sky Glow (magnitudes)","%4.1f",0,6000,0,19.5);
+    IUFillNumber(&SimulatorSettingsN[12],"SIM_OAGOFFSET","Oag Offset (arminutes)","%4.1f",0,6000,0,0);
+    IUFillNumberVector(SimulatorSettingsNV,SimulatorSettingsN,13,deviceName(),"SIMULATOR_SETTINGS","Simulator Settings","SimSettings",IP_RW,60,IPS_IDLE);
+
+
+    TelescopeTV = new ITextVectorProperty;
+    IUFillText(&TelescopeT[0],"ACTIVE_TELESCOPE","Telescope","");
+    IUFillTextVector(TelescopeTV,TelescopeT,1,deviceName(),"ACTIVE_DEVICES","Snoop Scope","Simulator Config",IP_RW,60,IPS_IDLE);
+
+    TimeFactorSV = new ISwitchVectorProperty;
+
+    IUFillSwitch(&TimeFactorS[0],"1X","Actual Time",ISS_ON);
+    IUFillSwitch(&TimeFactorS[1],"10X","10x",ISS_OFF);
+    IUFillSwitch(&TimeFactorS[2],"100X","100x",ISS_OFF);
+    IUFillSwitchVector(TimeFactorSV,TimeFactorS,3,deviceName(),"ON_TIME_FACTOR","Time Factor","Simulator Config",IP_RW,ISR_1OFMANY,60,IPS_IDLE);
+
+
+    loadConfig();
+
+    return true;
+}
+
+void CCDSim::ISGetProperties (const char *dev)
+{
+    //  First we let our parent populate
+
+    //IDLog("CCDSim IsGetProperties with %s\n",dev);
+    INDI::CCD::ISGetProperties(dev);
+
+    defineNumber(SimulatorSettingsNV);
+    defineSwitch(TimeFactorSV);
+    defineText(TelescopeTV);
+    //IDDefText(&ConfigFileTV, NULL);
+    //IDDefSwitch(&ConfigSaveRestoreSV, NULL);
+
+
+    return;
+}
+
+bool CCDSim::updateProperties()
+{
+    IDDefNumber(SimulatorSettingsNV, NULL);
+
+    INDI::CCD::updateProperties();
+    return true;
+}
+
+
+bool CCDSim::Disconnect()
+{
+    delete RawFrame;
+    RawFrameSize=0;
+    RawFrame=NULL;
+
+
+    if(RawGuiderFrame != NULL) {
+        delete RawGuiderFrame;
+        RawGuideSize=0;
+    }
+
+    return true;
+}
+
+int CCDSim::StartExposure(float duration)
+{
+    //  for the simulator, we can just draw the frame now
+    //  and it will get returned at the right time
+    //  by the timer routines
+    ExposureRequest=duration;
+
+    if(InExposure)
+    {
+        //  We are already in an exposure, just change the time
+        //  and be done with it.
+        return 0;
+    }
+
+    gettimeofday(&ExpStart,NULL);
+    //  Leave the proper time showing for the draw routines
+    DrawCcdFrame();
+    //  Now compress the actual wait time
+    ExposureRequest=duration*TimeFactor;
+
+    InExposure=true;
+    return 0;
+}
+
+int CCDSim::StartGuideExposure(float n)
+{
+    GuideExposureRequest=n;
+    if(InGuideExposure) return 0;
+    DrawGuiderFrame();
+    gettimeofday(&GuideExpStart,NULL);
+    InGuideExposure=true;
+    return 0;
+}
+
+bool CCDSim::AbortGuideExposure()
+{
+    //IDLog("Enter AbortGuideExposure\n");
+    if(!InGuideExposure) return true;   //  no need to abort if we aren't doing one
+    AbortGuideFrame=true;
+    return true;
+}
+
+float CCDSim::CalcTimeLeft(timeval start,float req)
+{
+    double timesince;
+    double timeleft;
+    struct timeval now;
+    gettimeofday(&now,NULL);
+
+    timesince=(double)(now.tv_sec * 1000.0 + now.tv_usec/1000) - (double)(start.tv_sec * 1000.0 + start.tv_usec/1000);
+    timesince=timesince/1000;
+    timeleft=req-timesince;
+    return timeleft;
+}
+
+void CCDSim::TimerHit()
+{
+    int nexttimer=1000;
+
+    if(isConnected() == false) return;  //  No need to reset timer if we are not connected anymore
+
+    if(InExposure)
+    {
+        float timeleft;
+        timeleft=CalcTimeLeft(ExpStart,ExposureRequest);
+        if(timeleft < 1.0)
+        {
+            if(timeleft <= 0.001)
+            {
+                InExposure=false;
+                ExposureComplete();
+            } else
+            {
+                nexttimer=timeleft*1000;    //  set a shorter timer
+            }
+        }
+    }
+    if(InGuideExposure)
+    {
+        float timeleft;
+        timeleft=CalcTimeLeft(GuideExpStart,GuideExposureRequest);
+        if(timeleft < 1.0)
+        {
+            if(timeleft <= 0.001)
+            {
+                InGuideExposure=false;
+                if(!AbortGuideFrame)
+                {
+                    //IDLog("Sending guider frame\n");
+                    GuideExposureComplete();
+                    if(InGuideExposure)
+                    {    //  the call to complete triggered another exposure
+                        timeleft=CalcTimeLeft(GuideExpStart,GuideExposureRequest);
+                        if(timeleft <1.0)
+                        {
+                            nexttimer=timeleft*1000;
+                        }
+                    }
+                } else
+                {
+                    IDLog("Not sending guide frame cuz of abort\n");
+                }
+                AbortGuideFrame=false;
+            } else
+            {
+                nexttimer=timeleft*1000;    //  set a shorter timer
+            }
+        }
+    }
+    SetTimer(nexttimer);
+    return;
+}
+
+int CCDSim::DrawCcdFrame()
+{
+    //  Ok, lets just put a silly pattern into this
+    //  CCd frame is 16 bit data
+    unsigned short int *ptr;
+    unsigned short int val;
+
+    ptr=(unsigned short int *)RawFrame;
+
+    if(ShowStarField) {
+        char gsccmd[250];
+        FILE *pp;
+        int stars=0;
+        int lines=0;
+        int drawn=0;
+        int x,y;
+        float PEOffset;
+        float PESpot;
+        double rad;  //  telescope ra in degrees
+        double rar;  //  telescope ra in radians
+        double decr; //  telescope dec in radians;
+
+
+        double timesince;
+        time_t now;
+        time(&now);
+
+        //  Lets figure out where we are on the pe curve
+        timesince=difftime(now,RunStart);
+        //  This is our spot in the curve
+        PESpot=timesince/PEPeriod;
+        //  Now convert to radians
+        PESpot=PESpot*2.0*3.14159;
+
+        PEOffset=PEMax*sin(PESpot);
+        //fprintf(stderr,"PEOffset = %4.2f arcseconds timesince %4.2f\n",PEOffset,timesince);
+        PEOffset=PEOffset/3600;     //  convert to degrees
+        //PeOffset=PeOffset/15;       //  ra is in h:mm
+
+        //  Start by clearing the frame buffer
+        memset(RawFrame,0,RawFrameSize);
+
+
+        //  Spin up a set of plate constants that will relate
+        //  ra/dec of stars, to our fictitious ccd layout
+
+        //  to account for various rotations etc
+        //  we should spin up some plate constants here
+        //  then we can use these constants to rotate and offset
+        //  the standard co-ordinates on each star for drawing
+        //  a ccd frame;
+        double pa,pb,pc,pd,pe,pf;
+        //  Since this is a simple ccd, correctly aligned
+        //  for now we cheat
+        //  no offset or rotation for and y axis means
+        pb=0.0;
+        pc=XRes/2/BinX;
+        pd=0.0;
+        pf=YRes/2/BinY;
+        //  and we do a simple scale for x and y locations
+        //  based on the focal length and pixel size
+        //  focal length in mm, pixels in microns
+        pa=focallength/PixelSizex*1000/BinX;
+        pe=focallength/PixelSizey*1000/BinY;
+
+        //IDLog("Pixels are %4.2f %4.2f  pa %6.4f  pe %6.4f\n",PixelSizex,PixelSizey,pa,pe);
+
+        //  these numbers are now pixels per radian
+        float Scalex;
+        float Scaley;
+        Scalex=pa*0.0174532925;    //  pixels per degree
+        Scalex=Scalex/3600.0;           // pixels per arcsecond
+        Scalex=1.0/Scalex;  //  arcseconds per pixel
+
+        Scaley=pe*0.0174532925;    //  pixels per degree
+        Scaley=Scaley/3600.0;           // pixels per arcsecond
+        Scaley=1.0/Scaley;  //  arcseconds per pixel
+        //qq=qq/3600; //  arcseconds per pixel
+
+        //IDLog("Pixel scale is %4.2f x %4.2f\n",Scalex,Scaley);
+        ImageScalex=Scalex;
+        ImageScaley=Scaley;
+
+        //  calc this now, we will use it a lot later
+        rad=RA*15.0;
+        rar=rad*0.0174532925;
+        //  offsetting the dec by the guide head offset
+        float cameradec;
+        cameradec=Dec+OAGoffset/60;
+        decr=cameradec*0.0174532925;
+
+        //fprintf(stderr,"Dec %7.5f  cameradec %7.5f  CenterOffsetDec %4.4f\n",Dec,cameradec,CenterOffsetDec);
+        //  now lets calculate the radius we need to fetch
+        float radius;
+
+        radius=sqrt((Scalex*Scalex*XRes/2.0*XRes/2.0)+(Scaley*Scaley*YRes/2.0*YRes/2.0));
+        //  we have radius in arcseconds now
+        radius=radius/60;   //  convert to arcminutes
+        //fprintf(stderr,"Lookup radius %4.2f\n",radius);
+        //radius=radius*2;
+
+        //  A saturationmag star saturates in one second
+        //  and a limitingmag produces a one adu level in one second
+        //  solve for zero point and system gain
+
+        k=(saturationmag-limitingmag)/((-2.5*log(maxval))-(-2.5*log(1.0/2.0)));
+        z=saturationmag-k*(-2.5*log(maxval));
+        //z=z+saturationmag;
+
+        //IDLog("K=%4.2f  Z=%4.2f\n",k,z);
+
+        //  Should probably do some math here to figure out the dimmest
+        //  star we can see on this exposure
+        //  and only fetch to that magnitude
+        //  for now, just use the limiting mag number with some room to spare
+        float lookuplimit;
+
+        lookuplimit=limitingmag;
+        lookuplimit=lookuplimit;
+        if(radius > 60) lookuplimit=11;
+
+        //  if this is a light frame, we need a star field drawn
+        if(FrameType==FRAME_TYPE_LIGHT)
+        {
+            //sprintf(gsccmd,"gsc -c %8.6f %+8.6f -r 120 -m 0 9.1",rad+PEOffset,Dec);
+            sprintf(gsccmd,"gsc -c %8.6f %+8.6f -r %4.1f -m 0 %4.2f -n 3000",rad+PEOffset,cameradec,radius,lookuplimit);
+            //fprintf(stderr,"gsccmd %s\n",gsccmd);
+            pp=popen(gsccmd,"r");
+            if(pp != NULL) {
+                char line[256];
+                while(fgets(line,256,pp)!=NULL)
+                {
+                    //fprintf(stderr,"%s",line);
+
+                    //  ok, lets parse this line for specifcs we want
+                    char id[20];
+                    char plate[6];
+                    char ob[6];
+                    float mag;
+                    float mage;
+                    float ra;
+                    float dec;
+                    float pose;
+                    int band;
+                    float dist;
+                    int dir;
+                    int c;
+                    int rc;
+
+                    rc=sscanf(line,"%10s %f %f %f %f %f %d %d %4s %2s %f %d",
+                            id,&ra,&dec,&pose,&mag,&mage,&band,&c,plate,ob,&dist,&dir);
+                    //fprintf(stderr,"Parsed %d items\n",rc);
+                    if(rc==12) {
+                        lines++;
+                        //if(c==0) {
+                        stars++;
+                        //fprintf(stderr,"%s %8.4f %8.4f %5.2f %5.2f %d\n",id,ra,dec,mag,dist,dir);
+
+                        //  Convert the ra/dec to standard co-ordinates
+                        double sx;   //  standard co-ords
+                        double sy;   //
+                        double srar;        //  star ra in radians
+                        double sdecr;       //  star dec in radians;
+                        double ccdx;
+                        double ccdy;
+
+                        //fprintf(stderr,"line %s",line);
+                        //fprintf(stderr,"parsed %6.5f %6.5f\n",ra,dec);
+
+                        srar=ra*0.0174532925;
+                        sdecr=dec*0.0174532925;
+                        //  Handbook of astronomical image processing
+                        //  page 253
+                        //  equations 9.1 and 9.2
+                        //  convert ra/dec to standard co-ordinates
+
+                        sx=cos(decr)*sin(srar-rar)/( cos(decr)*cos(sdecr)*cos(srar-rar)+sin(decr)*sin(sdecr) );
+                        sy=(sin(decr)*cos(sdecr)*cos(srar-rar)-cos(decr)*sin(sdecr))/( cos(decr)*cos(sdecr)*cos(srar-rar)+sin(decr)*sin(sdecr) );
+
+                        //  now convert to microns
+                        ccdx=pa*sx+pb*sy+pc;
+                        ccdy=pd*sx+pe*sy+pf;
+
+
+                        rc=DrawImageStar(mag,ccdx,ccdy);
+                        drawn+=rc;
+                        if(rc==1) {
+                            //fprintf(stderr,"star %s scope %6.4f %6.4f star %6.4f %6.4f  ccd %6.2f %6.2f\n",id,rad,Dec,ra,dec,ccdx,ccdy);
+                            //fprintf(stderr,"star %s ccd %6.2f %6.2f\n",id,ccdx,ccdy);
+                        }
+                    }
+                }
+                pclose(pp);
+            } else
+            {
+                IDMessage(deviceName(),"Error looking up stars, is gsc installed with appropriate environment variables set ??");
+                //fprintf(stderr,"Error doing gsc lookup\n");
+            }
+            if(drawn==0)
+            {
+                IDMessage(deviceName(),"Got no stars, is gsc installed with appropriate environment variables set ??");
+
+            }
+        }
+        //fprintf(stderr,"Got %d stars from %d lines drew %d\n",stars,lines,drawn);
+
+        //  now we need to add background sky glow, with vignetting
+        //  this is essentially the same math as drawing a dim star with
+        //  fwhm equivalent to the full field of view
+
+        if((FrameType==FRAME_TYPE_LIGHT)||(FrameType==FRAME_TYPE_FLAT))
+        {
+            float skyflux;
+            float glow;
+            //  calculate flux from our zero point and gain values
+            glow=skyglow;
+            if(FrameType==FRAME_TYPE_FLAT)
+            {
+                //  Assume flats are done with a diffuser
+                //  in broad daylight, so, the sky magnitude
+                //  is much brighter than at night
+                glow=skyglow/10;
+            }
+            //fprintf(stderr,"Using glow %4.2f\n",glow);
+            skyflux=pow(10,((glow-z)*k/-2.5));
+            //  ok, flux represents one second now
+            //  scale up linearly for exposure time
+            skyflux=skyflux*ExposureRequest*BinX*BinY;
+            //IDLog("SkyFlux = %4.2f ExposureRequest %4.2f\n",skyflux,ExposureRequest);
+
+            unsigned short *pt;
+            pt=(unsigned short int *)RawFrame;
+            for(int y=0; y<YRes/BinY; y++) {
+                for(int x=0; x<XRes/BinX; x++) {
+                    float dc;   //  distance from center
+                    float fp;   //  flux this pixel;
+                    float sx,sy;
+                    float vig;
+
+                    sx=XRes/2/BinX;
+                    sx=sx-x;
+                    sy=YRes/2/BinY;
+                    sy=sy-y;
+
+                    vig=XRes/BinX;
+                    vig=vig*ImageScalex;
+                    //  need to make this account for actual pixel size
+                    dc=sqrt(sx*sx*ImageScalex*ImageScalex+sy*sy*ImageScaley*ImageScaley);
+                    //  now we have the distance from center, in arcseconds
+                    //  now lets plot a gaussian falloff to the edges
+                    //
+                    float fa;
+                    fa=exp(-2.0*0.7*(dc*dc)/vig/vig);
+                    //  get the current value
+                    fp=pt[0];
+                    //  Add the sky glow
+                    fp+=skyflux;
+                    //  now scale it for the vignetting
+                    fp=fa*fp;
+                    //  clamp to limits
+                    if(fp > maxval) fp=maxval;
+                    //  and put it back
+                    pt[0]=fp;
+                    pt++;
+
+                }
+            }
+        }
+
+
+        //  Now we add some bias and read noise
+        for(x=0; x<XRes; x++) {
+            for(y=0; y<YRes; y++) {
+                int noise;
+
+                noise=random();
+                noise=noise%maxnoise; //
+
+                AddToPixel(x,y,bias+noise);
+            }
+        }
+
+
+    } else {
+        testvalue++;
+        if(testvalue > 255) testvalue=0;
+        val=testvalue;
+
+        for(int x=0; x<XRes*YRes; x++)
+        {
+            *ptr=val++;
+            ptr++;
+        }
+
+    }
+    return 0;
+}
+
+int CCDSim::DrawGuiderFrame()
+{
+    unsigned char *ptr;
+    unsigned char val;
+
+    ptr=(unsigned char *)RawGuiderFrame;
+    testvalue++;
+    if(testvalue > 255) testvalue=0;
+    val=testvalue;
+
+    for(int x=0; x<GXRes*GYRes; x++) {
+        *ptr=val++;
+        ptr++;
+    }
+    return 0;
+}
+
+int CCDSim::DrawImageStar(float mag,float x,float y)
+{
+    //float d;
+    //float r;
+    int sx,sy;
+    int drew=0;
+    int boxsizex=5;
+    int boxsizey=5;
+    float flux;
+
+    if((x<0)||(x>XRes/BinX)||(y<0)||(y>YRes/BinY))
+    {
+        //  this star is not on the ccd frame anyways
+        return 0;
+    }
+
+
+
+    //  calculate flux from our zero point and gain values
+    flux=pow(10,((mag-z)*k/-2.5));
+    //  ok, flux represents one second now
+    //  scale up linearly for exposure time
+    flux=flux*ExposureRequest;
+
+
+    float qx;
+    //  we need a box size that gives a radius at least 3 times fwhm
+    qx=seeing/ImageScalex;
+    qx=qx*3;
+    boxsizex=(int)qx;
+    boxsizex++;
+    qx=seeing/ImageScaley;
+    qx=qx*3;
+    boxsizey=(int)qx;
+    boxsizey++;
+
+    //IDLog("BoxSize %d %d\n",boxsizex,boxsizey);
+
+
+    for(sy=-boxsizey; sy<=boxsizey; sy++) {
+        for(sx=-boxsizey; sx<=boxsizey; sx++) {
+            int rc;
+            float dc;   //  distance from center
+            float fp;   //  flux this pixel;
+
+            //  need to make this account for actual pixel size
+            dc=sqrt(sx*sx*ImageScalex*ImageScalex+sy*sy*ImageScaley*ImageScaley);
+            //  now we have the distance from center, in arcseconds
+            //  This should be gaussian, but, for now we'll just go with
+            //  a simple linear function
+            float fa;
+            fa=exp(-2.0*0.7*(dc*dc)/seeing/seeing);
+            fp=fa*flux*BinX*BinY;
+            if(fp < 0) fp=0;
+
+            /*
+            if(dc < boxsize) {
+                dc=boxsize-dc;
+                dc=dc/boxsize;
+                fp=dc*flux;
+            } else {
+                fp=0;
+            }
+            */
+            rc=AddToPixel(x+sx,y+sy,fp);
+            if(rc != 0) drew=1;
+        }
+    }
+    return drew;
+}
+
+int CCDSim::AddToPixel(int x,int y,int val)
+{
+    int drew=0;
+    if(x >= 0) {
+        if(x < XRes/BinX) {
+            if(y >= 0) {
+                if(y < YRes/BinY) {
+                    unsigned short *pt;
+                    int newval;
+                    drew++;
+                    pt=(unsigned short int *)RawFrame;
+                    pt+=(y*XRes/BinX);
+                    pt+=x;
+                    newval=pt[0];
+                    newval+=val;
+                    if(newval > maxval) newval=maxval;
+                    pt[0]=newval;
+                }
+            }
+        }
+    }
+    return drew;
+}
+
+int CCDSim::GuideNorth(float v)
+{
+    float c;
+
+    c=v*GuideRate;  //
+    c=c/3600;
+    Dec=Dec+c;
+
+    return 0;
+}
+int CCDSim::GuideSouth(float v)
+{
+    float c;
+
+    c=v*GuideRate;  //
+    c=c/3600;
+    Dec=Dec-c;
+
+    return 0;
+}
+
+int CCDSim::GuideEast(float v)
+{
+    float c;
+
+    c=v*GuideRate;
+    c=c/3600.0/15.0;
+    c=c/(cos(Dec*0.0174532925));
+    RA=RA-c;
+
+    return 0;
+}
+int CCDSim::GuideWest(float v)
+{
+    float c;
+
+    c=v*GuideRate;  //
+    c=c/3600.0/15.0;
+    c=c/(cos(Dec*0.0174532925));
+    RA=RA+c;
+
+    return 0;
+}
+
+void CCDSim::ISSnoopDevice (XMLEle *root)
+ {
+     //fprintf(stderr,"CCDSim handling snoop\n");
+     if(IUSnoopNumber(root,&EqNV)==0) {
+        float newra,newdec;
+        newra=EqN[0].value;
+        newdec=EqN[1].value;
+        if((newra != RA)||(newdec != Dec)) {
+            //fprintf(stderr,"RA %4.2f  Dec %4.2f Snooped RA %4.2f  Dec %4.2f\n",RA,Dec,newra,newdec);
+            RA=newra;
+            Dec=newdec;
+
+        }
+     } else {
+        //fprintf(stderr,"Snoop Failed\n");
+     }
+ }
+
+bool CCDSim::ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n)
+{
+    //  first check if it's for our device
+    //IDLog("INDI::CCD::ISNewNumber %s\n",name);
+    if(strcmp(dev,deviceName())==0) {
+        //  This is for our device
+        //  Now lets see if it's something we process here
+
+        //IDLog("CCDSim::ISNewNumber %s\n",name);
+        if(strcmp(name,"SIMULATOR_SETTINGS")==0) {
+            //  We are being asked to set camera binning
+            SimulatorSettingsNV->s=IPS_OK;
+
+            for(int x=0; x<n; x++) {
+                //fprintf(stderr,"name %s value %4.2f\n",names[x],values[x]);
+                if(values[x] != 0) {
+                    SimulatorSettingsN[x].value=values[x];
+                } else {
+                    //  We ignore zeros on most of our items
+                    //  because they likely mean it was just a field not
+                    //  actually filled in, but, for the dec offset it is
+                    //  important to keep a zero value
+                    if(strcmp(names[x],"SIM_OAGOFFSET")==0) {
+                        SimulatorSettingsN[x].value=values[x];
+                    }
+                }
+            }
+
+            //  Reset our parameters now
+            SetupParms();
+            IDSetNumber(SimulatorSettingsNV,NULL);
+            saveConfig();
+
+            //IDLog("Frame set to %4.0f,%4.0f %4.0f x %4.0f\n",CcdFrameN[0].value,CcdFrameN[1].value,CcdFrameN[2].value,CcdFrameN[3].value);
+            //seeing=SimulatorSettingsN[0].value;
+            return true;
+        }
+
+
+    }
+    //  if we didn't process it, continue up the chain, let somebody else
+    //  give it a shot
+    return INDI::CCD::ISNewNumber(dev,name,values,names,n);
+}
+bool CCDSim::ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n)
+{
+    //  Ok, lets see if this is a property wer process
+    //IDLog("IndiTelescope got %d new text items name %s\n",n,name);
+    //  first check if it's for our device
+    if(strcmp(dev,deviceName())==0) {
+        //  This is for our device
+        //  Now lets see if it's something we process here
+        if(strcmp(name,TelescopeTV->name)==0) {
+            int rc;
+            //IDLog("calling update text\n");
+            TelescopeTV->s=IPS_OK;
+            rc=IUUpdateText(TelescopeTV,texts,names,n);
+            //IDLog("update text returns %d\n",rc);
+            //  Update client display
+            IDSetText(TelescopeTV,NULL);
+            saveConfig();
+            IUFillNumberVector(&EqNV,EqN,2,TelescopeT[0].text,"EQUATORIAL_EOD_COORD","Eq. Coordinates","Main Control",IP_RW,60,IPS_IDLE);
+            IDSnoopDevice(TelescopeT[0].text,"EQUATORIAL_EOD_COORD");
+            //  We processed this one, so, tell the world we did it
+            return true;
+        }
+
+    }
+
+    return INDI::DefaultDriver::ISNewText(dev,name,texts,names,n);
+}
+
+
+bool CCDSim::ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n)
+{
+    //IDLog("Enter IsNewSwitch for %s\n",name);
+    //for(int x=0; x<n; x++) {
+    //    IDLog("Switch %s %d\n",names[x],states[x]);
+    //}
+
+    if(strcmp(dev,deviceName())==0) {
+        //  This one is for us
+
+
+        if(strcmp(name,"ON_TIME_FACTOR")==0) {
+
+            //  client is telling us what to do with co-ordinate requests
+            TimeFactorSV->s=IPS_OK;
+            IUUpdateSwitch(TimeFactorSV,states,names,n);
+            //  Update client display
+            IDSetSwitch(TimeFactorSV,NULL);
+
+            saveConfig();
+            if(TimeFactorS[0].s==ISS_ON    ) {
+                //IDLog("CCDSim:: Time Factor 1\n");
+                TimeFactor=1;
+            }
+            if(TimeFactorS[1].s==ISS_ON    ) {
+                //IDLog("CCDSim:: Time Factor 0.1\n");
+                TimeFactor=0.1;
+            }
+            if(TimeFactorS[2].s==ISS_ON    ) {
+                //IDLog("CCDSim:: Time Factor 0.01\n");
+                TimeFactor=0.01;
+            }
+
+            return true;
+        }
+
+    }
+
+    //  Nobody has claimed this, so, ignore it
+    return INDI::CCD::ISNewSwitch(dev,name,states,names,n);
+}
+
Index: /BAORadio/libindi/libindi/drivers/ccd/ccd_simulator.h
===================================================================
--- /BAORadio/libindi/libindi/drivers/ccd/ccd_simulator.h	(revision 504)
+++ /BAORadio/libindi/libindi/drivers/ccd/ccd_simulator.h	(revision 504)
@@ -0,0 +1,136 @@
+/*******************************************************************************
+  Copyright(c) 2010 Gerry Rozema. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published by the Free
+  Software Foundation; either version 2 of the License, or (at your option)
+  any later version.
+
+  This program is distributed in the hope that it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc., 59
+  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+  The full GNU General Public License is included in this distribution in the
+  file called LICENSE.
+*******************************************************************************/
+
+#ifndef CCDSIM_H
+#define CCDSIM_H
+
+#include "indibase/indiccd.h"
+
+/*  Some headers we need */
+#include <math.h>
+#include <sys/time.h>
+
+
+class CCDSim : public INDI::CCD
+{
+    protected:
+    private:
+
+        bool InExposure;
+        float ExposureRequest;
+        struct timeval ExpStart;
+
+        bool InGuideExposure;
+        float GuideExposureRequest;
+        struct timeval GuideExpStart;
+
+        float CalcTimeLeft(timeval,float);
+
+        int testvalue;
+        int ShowStarField;
+        int bias;
+        int maxnoise;
+        int maxval;
+        float skyglow;
+        float limitingmag;
+        float saturationmag;
+        float seeing;
+        float ImageScalex;
+        float ImageScaley;
+        float focallength;
+        float OAGoffset;
+        float TimeFactor;
+        //  our zero point calcs used for drawing stars
+        float k;
+        float z;
+
+        bool AbortGuideFrame;
+
+        float RA;
+        float Dec;
+        float GuideRate;
+
+        float PEPeriod;
+        float PEMax;
+        time_t RunStart;
+
+        //  We are going to snoop these from a telescope
+        INumberVectorProperty EqNV;
+        INumber EqN[2];
+
+        //  And this lives in our simulator settings page
+
+        INumberVectorProperty *SimulatorSettingsNV;
+        INumber SimulatorSettingsN[13];
+
+        ITextVectorProperty *TelescopeTV; //  A text vector that stores the telescope we want to snoop
+        IText TelescopeT[1];
+
+        //ISwitch ConfigSaveRestoreS[2];
+        //ISwitchVectorProperty ConfigSaveRestoreSV;
+
+        ISwitch TimeFactorS[3];
+        ISwitchVectorProperty *TimeFactorSV;
+
+        bool SetupParms();
+
+    public:
+        CCDSim();
+        virtual ~CCDSim();
+
+        const char *getDefaultName();
+
+        bool initProperties();
+        bool updateProperties();
+
+        void ISGetProperties (const char *dev);
+        void ISSnoopDevice (XMLEle *root);
+
+
+
+        bool Connect();
+        bool Disconnect();
+
+        int StartExposure(float duration);
+        int StartGuideExposure(float);
+        bool AbortGuideExposure();
+
+
+        void TimerHit();
+
+        int DrawCcdFrame();
+        int DrawGuiderFrame();
+
+        int DrawImageStar(float,float,float);
+        int AddToPixel(int,int,int);
+
+        int GuideNorth(float);
+        int GuideSouth(float);
+        int GuideEast(float);
+        int GuideWest(float);
+
+        virtual bool ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n);
+        virtual bool ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n);
+        virtual bool ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n);
+
+};
+
+#endif // CCDSim_H
Index: /BAORadio/libindi/libindi/drivers/filter_wheel/filter_simulator.cpp
===================================================================
--- /BAORadio/libindi/libindi/drivers/filter_wheel/filter_simulator.cpp	(revision 504)
+++ /BAORadio/libindi/libindi/drivers/filter_wheel/filter_simulator.cpp	(revision 504)
@@ -0,0 +1,102 @@
+#include "filter_simulator.h"
+
+
+// We declare an auto pointer to FilterSim.
+std::auto_ptr<FilterSim> filter_sim(0);
+
+void ISPoll(void *p);
+
+
+void ISInit()
+{
+   static int isInit =0;
+
+   if (isInit == 1)
+       return;
+
+    isInit = 1;
+    if(filter_sim.get() == 0) filter_sim.reset(new FilterSim());
+    //IEAddTimer(POLLMS, ISPoll, NULL);
+
+}
+
+void ISGetProperties(const char *dev)
+{
+        ISInit();
+        filter_sim->ISGetProperties(dev);
+}
+
+void ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int num)
+{
+        ISInit();
+        filter_sim->ISNewSwitch(dev, name, states, names, num);
+}
+
+void ISNewText(	const char *dev, const char *name, char *texts[], char *names[], int num)
+{
+        ISInit();
+        filter_sim->ISNewText(dev, name, texts, names, num);
+}
+
+void ISNewNumber(const char *dev, const char *name, double values[], char *names[], int num)
+{
+        ISInit();
+        filter_sim->ISNewNumber(dev, name, values, names, num);
+}
+
+void ISNewBLOB (const char *dev, const char *name, int sizes[], int blobsizes[], char *blobs[], char *formats[], char *names[], int n)
+{
+  INDI_UNUSED(dev);
+  INDI_UNUSED(name);
+  INDI_UNUSED(sizes);
+  INDI_UNUSED(blobsizes);
+  INDI_UNUSED(blobs);
+  INDI_UNUSED(formats);
+  INDI_UNUSED(names);
+  INDI_UNUSED(n);
+}
+void ISSnoopDevice (XMLEle *root)
+{
+    INDI_UNUSED(root);
+}
+
+
+FilterSim::FilterSim()
+{
+    //ctor
+}
+
+FilterSim::~FilterSim()
+{
+    //dtor
+}
+
+const char *FilterSim::getDefaultName()
+{
+    return (char *)"Filter Simulator";
+}
+
+bool FilterSim::Connect()
+{
+    CurrentFilter=1;
+    MinFilter=1;
+    MaxFilter=7;
+    return true;
+}
+
+bool FilterSim::Disconnect()
+{
+    return true;
+}
+
+int FilterSim::SelectFilter(int f)
+{
+    CurrentFilter=f;
+    SetTimer(500);
+    return 0;
+}
+
+void FilterSim::TimerHit()
+{
+    SelectFilterDone(CurrentFilter);
+}
Index: /BAORadio/libindi/libindi/drivers/filter_wheel/filter_simulator.h
===================================================================
--- /BAORadio/libindi/libindi/drivers/filter_wheel/filter_simulator.h	(revision 504)
+++ /BAORadio/libindi/libindi/drivers/filter_wheel/filter_simulator.h	(revision 504)
@@ -0,0 +1,44 @@
+/*******************************************************************************
+  Copyright(c) 2010 Gerry Rozema. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published by the Free
+  Software Foundation; either version 2 of the License, or (at your option)
+  any later version.
+
+  This program is distributed in the hope that it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc., 59
+  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+  The full GNU General Public License is included in this distribution in the
+  file called LICENSE.
+*******************************************************************************/
+
+#ifndef FILTERSIM_H
+#define FILTERSIM_H
+
+#include "indibase/indifilterwheel.h"
+
+class FilterSim : public INDI::FilterWheel
+{
+    protected:
+    private:
+    public:
+        FilterSim();
+        virtual ~FilterSim();
+
+        const char *getDefaultName();
+
+        bool Connect();
+        bool Disconnect();
+        int SelectFilter(int);
+        void TimerHit();
+
+};
+
+#endif // FILTERSIM_H
Index: /BAORadio/libindi/libindi/drivers/filter_wheel/trutech_wheel.c
===================================================================
--- /BAORadio/libindi/libindi/drivers/filter_wheel/trutech_wheel.c	(revision 503)
+++ /BAORadio/libindi/libindi/drivers/filter_wheel/trutech_wheel.c	(revision 504)
@@ -168,7 +168,7 @@
 		unsigned char type = 0x03;
 		unsigned char chksum = COMM_INIT + type + COMM_FILL;
-		/*char filter_command[5] = { COMM_PRE, COMM_INIT, type, COMM_FILL, chksum };*/
                 unsigned char filter_command[CMD_SIZE];
-		snprintf(filter_command, CMD_SIZE,  "%c%c%c%c%c", COMM_PRE, COMM_INIT, type, COMM_FILL, chksum);
+                //snprintf(filter_command, CMD_SIZE,  "%c%c%c%c%c", COMM_PRE, COMM_INIT, type, COMM_FILL, chksum);
+                snprintf(filter_command, CMD_SIZE,  "%c%c%c%c", COMM_INIT, type, COMM_FILL, chksum);
 
 		if (checkPowerS(&HomeSP))
@@ -181,6 +181,6 @@
                 if (DEBUG_ON)
                 {
-                    IDLog("Home Search Command (int): #%d#%d#%d#%d#%d#\n",COMM_PRE, COMM_INIT, type, COMM_FILL, chksum);
-                    IDLog("Home Search Command (char): #%c#%c#%c#%c#%c#\n",COMM_PRE, COMM_INIT, type, COMM_FILL, chksum);
+                    IDLog("Home Search Command (int): #%d#%d#%d#%d#\n",COMM_INIT, type, COMM_FILL, chksum);
+                    IDLog("Home Search Command (char): #%c#%c#%c#%c#\n",COMM_INIT, type, COMM_FILL, chksum);
                 }
 
@@ -273,10 +273,11 @@
 			IUUpdateNumber(&FilterPositionNP, values, names, n);
 
-                        snprintf(filter_command, CMD_SIZE,  "%c%c%c%c%c", COMM_PRE, COMM_INIT, type, targetFilter, chksum);
+                        //snprintf(filter_command, CMD_SIZE,  "%c%c%c%c%c", COMM_PRE, COMM_INIT, type, targetFilter, chksum);
+                        snprintf(filter_command, CMD_SIZE,  "%c%c%c%c", COMM_INIT, type, targetFilter, chksum);
 
                         if (DEBUG_ON)
                         {
-                            IDLog("Filter Position Command (int): #%d#%d#%d#%d#%d#\n",COMM_PRE, COMM_INIT, type, targetFilter, chksum);
-                            IDLog("Filter Position Command (char): #%c#%c#%c#%c#%c#\n",COMM_PRE, COMM_INIT, type, targetFilter, chksum);
+                            IDLog("Filter Position Command (int): #%d#%d#%d#%d#\n", COMM_INIT, type, targetFilter, chksum);
+                            IDLog("Filter Position Command (char): #%c#%c#%c#%c#\n", COMM_INIT, type, targetFilter, chksum);
                         }
 
Index: /BAORadio/libindi/libindi/drivers/focuser/indi_tcfs_sk.xml
===================================================================
--- /BAORadio/libindi/libindi/drivers/focuser/indi_tcfs_sk.xml	(revision 504)
+++ /BAORadio/libindi/libindi/drivers/focuser/indi_tcfs_sk.xml	(revision 504)
@@ -0,0 +1,76 @@
+<INDIDriver>
+<defSwitchVector device="Optec TCF-S" name="CONNECTION" label="Connection" group="Main Control" state="Idle" perm="rw" rule="OneOfMany" timeout="60">
+    <defSwitch name="CONNECT" label="Connect">
+Off
+    </defSwitch>
+    <defSwitch name="DISCONNECT" label="Disconnect">
+On
+    </defSwitch>
+</defSwitchVector>
+<defTextVector device="Optec TCF-S" name="DEVICE_PORT" label="Focuser" group="Main Control" state="Idle" perm="rw" timeout="0">
+    <defText name="PORT" label="Port">
+/dev/ttyUSB0
+    </defText>
+</defTextVector>
+<defSwitchVector device="Optec TCF-S" name="FOCUS_MODE" label="Mode" group="Main Control" state="Idle" perm="rw" rule="OneOfMany" timeout="0">
+    <defSwitch name="Manual" label="">
+Off
+    </defSwitch>
+    <defSwitch name="Auto A" label="">
+Off
+    </defSwitch>
+    <defSwitch name="Auto B" label="">
+Off
+    </defSwitch>
+</defSwitchVector>
+<defSwitchVector device="Optec TCF-S" name="FOCUS_MOTION" label="Motion" group="Operation" state="Idle" perm="rw" rule="OneOfMany" timeout="0">
+    <defSwitch name="FOCUS_INWARD" label="Inward">
+Off
+    </defSwitch>
+    <defSwitch name="FOCUS_OUTWARD" label="Outward">
+Off
+    </defSwitch>
+</defSwitchVector>
+<defSwitchVector device="Optec TCF-S" name="FOCUS_GOTO" label="Go to" group="Operation" state="Idle" perm="rw" rule="OneOfMany" timeout="0">
+    <defSwitch name="FOCUS_MIN" label="Min">
+Off
+    </defSwitch>
+    <defSwitch name="FOCUS_CENTER" label="Center">
+Off
+    </defSwitch>
+    <defSwitch name="FOCUS_MAX" label="Max">
+Off
+    </defSwitch>
+<defSwitch name="FOCUS_HOME" label="Home">
+Off
+    </defSwitch>
+</defSwitchVector>
+<defNumberVector device="Optec TCF-S" name="FOCUS_STEP" label="Step" group="Operation" state="Idle" perm="rw" timeout="0">
+    <defNumber name="FOCUS_STEP_VALUE" label="# Steps" format="%.3f" min="0" max="1000" step="5">
+100
+    </defNumber>
+</defNumberVector>
+<defNumberVector device="Optec TCF-S" name="FOCUS_POSITION_REQUEST" label="Position" group="Operation" state="Idle" perm="wo" timeout="0">
+    <defNumber name="FOCUS_POSITION_VALUE" label="Current" format="%.3f" min="0" max="7000" step="0">
+0
+    </defNumber>
+</defNumberVector>
+<defNumberVector device="Optec TCF-S" name="FOCUS_POSITION" label="Position" group="Operation" state="Idle" perm="ro" timeout="0">
+    <defNumber name="FOCUS_POSITION_VALUE" label="Target" format="%.3f" min="0" max="9999" step="0">
+0
+    </defNumber>
+</defNumberVector>
+<defNumberVector device="Optec TCF-S" name="FOCUS_TEMPERATURE" label="Probe" group="Operation" state="Idle" perm="ro" timeout="0">
+    <defNumber name="FOCUS_TEMPERATURE_VALUE" label="Temperature (c)" format="%.3f" min="-50" max="80" step="0">
+0
+    </defNumber>
+</defNumberVector>
+<defSwitchVector device="Optec TCF-S" name="FOCUS_POWER" label="Power" group="Operation" state="Idle" perm="rw" rule="OneOfMany" timeout="0">
+    <defSwitch name="FOCUS_SLEEP" label="Sleep">
+Off
+    </defSwitch>
+    <defSwitch name="FOCUS_WAKEUP" label="Wake up">
+Off
+    </defSwitch>
+</defSwitchVector>
+</INDIDriver>
Index: /BAORadio/libindi/libindi/drivers/focuser/tcfs.cpp
===================================================================
--- /BAORadio/libindi/libindi/drivers/focuser/tcfs.cpp	(revision 504)
+++ /BAORadio/libindi/libindi/drivers/focuser/tcfs.cpp	(revision 504)
@@ -0,0 +1,933 @@
+/*
+    INDI Driver for Optec TCF-S Focuser
+
+    Copyright (C) 2010 Jasem Mutlaq (mutlaqja@ikarustech.com)
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+*/
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <math.h>
+#include <unistd.h>
+#include <time.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <termios.h>
+#include <memory>
+#include <indicom.h>
+
+#include "tcfs.h"
+
+#define mydev                   "Optec TCF-S"
+#define nFocusSteps             FocusStepNP->np[0].value
+#define nFocusCurrentPosition   FocusPositionNP->np[0].value
+#define nFocusTargetPosition    FocusPositionRequestNP->np[0].value
+#define nFocusTemperature       FocusTemperatureNP->np[0].value
+#define isFocusSleep            (FocusPowerSP->sp[0].s == ISS_ON)
+
+const int POLLMS = 1000;
+
+
+// We declare an auto pointer to TCFS.
+auto_ptr<TCFS> tcfs(0);
+
+void ISPoll(void *p);
+
+
+void ISInit()
+{
+   static int isInit =0;
+
+   if (isInit == 1)
+       return;
+
+    isInit = 1;
+    if(tcfs.get() == 0) tcfs.reset(new TCFS());
+    IEAddTimer(POLLMS, ISPoll, NULL);
+
+}
+
+void ISPoll(void *p)
+{
+    tcfs->ISPoll();
+    IEAddTimer(POLLMS, ISPoll, NULL);
+}
+
+void ISGetProperties(const char *dev)
+{ 
+	if(dev && strcmp(mydev, dev)) return;
+	ISInit();
+        tcfs->ISGetProperties(dev);
+}
+
+void ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int num)
+{
+	if(dev && strcmp (mydev, dev)) return;
+	ISInit();
+        tcfs->ISNewSwitch(name, states, names, num);
+}
+
+void ISNewText(	const char *dev, const char *name, char *texts[], char *names[], int num)
+{
+	if(dev && strcmp (mydev, dev)) return;
+	ISInit();
+        tcfs->ISNewText(name, texts, names, num);
+}
+
+void ISNewNumber(const char *dev, const char *name, double values[], char *names[], int num)
+{
+	if(dev && strcmp (mydev, dev)) return;
+	ISInit();
+        tcfs->ISNewNumber(name, values, names, num);
+}
+
+void ISNewBLOB (const char *dev, const char *name, int sizes[], int blobsizes[], char *blobs[], char *formats[], char *names[], int n) 
+{
+  INDI_UNUSED(dev);
+  INDI_UNUSED(name);
+  INDI_UNUSED(sizes);
+  INDI_UNUSED(blobsizes);
+  INDI_UNUSED(blobs);
+  INDI_UNUSED(formats);
+  INDI_UNUSED(names);
+  INDI_UNUSED(n);
+}
+void ISSnoopDevice (XMLEle *root) 
+{
+    INDI_UNUSED(root);
+}
+
+/****************************************************************
+**
+**
+*****************************************************************/
+TCFS::TCFS()
+{
+    const char *skelFileName = "/usr/share/indi/indi_tcfs_sk.xml";
+    struct stat st;
+
+    char *skel = getenv("INDISKEL");
+    if (skel)
+      buildSkeleton(skel);
+    else if (stat(skelFileName,&st) == 0)
+       buildSkeleton(skelFileName);
+    else
+       IDLog("No skeleton file was specified. Set environment variable INDISKEL to the skeleton path and try again.\n");
+
+     // Optional: Add aux controls for configuration, debug & simulation
+     addAuxControls();
+
+     simulated_position    = 3000;
+     simulated_temperature = 25.4;
+
+}
+
+/****************************************************************
+**
+**
+*****************************************************************/
+TCFS::~TCFS()
+{
+}
+
+/****************************************************************
+**
+**
+*****************************************************************/
+void TCFS::ISGetProperties(const char *dev)
+{
+    static int propInit=0;
+
+    INDI::DefaultDriver::ISGetProperties(dev);
+
+    if (propInit == 0)
+    {
+        init_properties();
+
+        loadConfig();
+
+        isTCFS3 = false;
+
+        // Set upper limit for TCF-S3 focuser
+        if (!strcmp(me, "indi_tcfs3_focus"))
+        {
+            isTCFS3 = true;
+
+            FocusPositionRequestNP->np[0].max = 9999;
+            IUUpdateMinMax(FocusPositionRequestNP);
+            if (isDebug())
+               IDLog("TCF-S3 detected. Updating maximum position value to 9999.\n");
+        }
+
+        propInit = 1;      
+    }
+
+}
+
+/****************************************************************
+**
+**
+*****************************************************************/
+void TCFS::init_properties()
+{
+    ConnectSP = getSwitch("CONNECTION");
+    FocusStepNP = getNumber("FOCUS_STEP");
+    FocusPositionNP = getNumber("FOCUS_POSITION");
+    FocusPositionRequestNP = getNumber("FOCUS_POSITION_REQUEST");
+    FocusTemperatureNP = getNumber("FOCUS_TEMPERATURE");
+    FocusPowerSP = getSwitch("FOCUS_POWER");
+    FocusModeSP  = getSwitch("FOCUS_MODE");
+}
+
+/****************************************************************
+**
+**
+*****************************************************************/   
+bool TCFS::Connect()
+{
+    ITextVectorProperty *tProp = getText("DEVICE_PORT");
+
+   if (isConnected())
+		return true;
+
+    if (tProp == NULL)
+        return false;
+
+    if (isSimulation())
+    {
+        setConnected(true);
+
+        IDSetSwitch(ConnectSP, "TCF-S: Simulating connection to port %s.", tProp->tp[0].text);
+
+        fd=-1;
+        IUResetSwitch(FocusModeSP);
+        FocusModeSP->sp[0].s = ISS_ON;
+        FocusModeSP->s       = IPS_OK;
+        IDSetSwitch(FocusModeSP, NULL);
+
+        FocusPositionNP->s = IPS_OK;
+        IDSetNumber(FocusPositionNP, NULL);
+
+        FocusTemperatureNP->s = IPS_OK;
+        IDSetNumber(FocusTemperatureNP, NULL);
+
+        IUResetSwitch(FocusPowerSP);
+        IDSetSwitch(FocusPowerSP, NULL);
+	return true;
+    }
+
+    if (isDebug())
+        IDLog("Attempting to connect to TCF-S focuser....\n");
+
+    if (tty_connect(tProp->tp[0].text, 19200, 8, 0, 1, &fd) != TTY_OK)
+    {
+        ConnectSP->s = IPS_ALERT;
+        IDSetSwitch (ConnectSP, "Error connecting to port %s. Make sure you have BOTH read and write permission to the port.", tProp->tp[0].text);
+	return false;
+    }
+
+    for (int i=0; i < TCFS_MAX_TRIES; i++)
+    {
+        dispatch_command(FMMODE);
+
+        if (read_tcfs() == true)
+        {
+            if (!strcmp(response, "!"))
+            {
+                setConnected(true, IPS_OK, "Successfully connected to TCF-S Focuser in Manual Mode.");
+
+                IUResetSwitch(FocusModeSP);
+                FocusModeSP->sp[0].s = ISS_ON;
+                FocusModeSP->s       = IPS_OK;
+                IDSetSwitch(FocusModeSP, NULL);
+
+                FocusPositionNP->s = IPS_OK;
+                IDSetNumber(FocusPositionNP, NULL);
+
+                FocusTemperatureNP->s = IPS_OK;
+                IDSetNumber(FocusTemperatureNP, NULL);
+
+                IUResetSwitch(FocusPowerSP);
+                IDSetSwitch(FocusPowerSP, NULL);
+
+                return true;
+             }
+        }
+
+        usleep(500000);
+    }
+
+    setConnected(false, IPS_ALERT, "Error connecting to TCF-S focuser...");
+    return false;
+
+}
+
+/****************************************************************
+**
+**
+*****************************************************************/   
+bool TCFS::Disconnect()
+{
+
+    FocusPositionNP->s = IPS_IDLE;
+    IDSetNumber(FocusPositionNP, NULL);
+
+    FocusTemperatureNP->s = IPS_IDLE;
+    IDSetNumber(FocusTemperatureNP, NULL);
+
+    dispatch_command(FFMODE);
+
+    tty_disconnect(fd);
+
+    setConnected(false, IPS_OK, "Disconnected from TCF-S.");
+
+    return true;
+}
+
+/****************************************************************
+**
+**
+*****************************************************************/
+bool TCFS::ISNewNumber (const char *name, double values[], char *names[], int n)
+{
+
+  INumberVectorProperty *nProp = getNumber(name);
+
+  if (nProp == NULL)
+      return false;
+
+  if (isConnected() == false)
+  {
+      resetProperties();
+      IDMessage(deviceID, "TCF-S is offline. Connect before issiung any commands.");
+      return false;
+  }
+
+  if (!strcmp(nProp->name, "FOCUS_STEP"))
+  {
+      IUUpdateNumber(nProp, values, names, n);
+      nProp->s = IPS_OK;
+      IDSetNumber(nProp, NULL);
+      return true;
+  }
+
+  if (isFocusSleep)
+  {
+      nProp->s = IPS_IDLE;
+      IDSetNumber(nProp, "Focuser is still in sleep mode. Wake up in order to issue commands.");
+      return true;
+  }
+
+  if (!strcmp(nProp->name, "FOCUS_POSITION_REQUEST"))
+  {
+      int current_step = nFocusSteps;
+      IUUpdateNumber(nProp, values, names, n);
+
+      nFocusSteps = fabs(nFocusTargetPosition - nFocusCurrentPosition);
+
+      if ( (nFocusTargetPosition - nFocusCurrentPosition) > 0)
+          move_focuser(TCFS_OUTWARD);
+      else
+          move_focuser(TCFS_INWARD);
+
+      nFocusSteps = current_step;
+
+      FocusPositionNP->s = IPS_BUSY;
+      nProp->s = IPS_BUSY;
+      IDSetNumber(nProp, "Moving focuser to new position %g...", nFocusTargetPosition);
+      return true;
+  }
+    
+}
+
+/****************************************************************
+**
+**
+*****************************************************************/
+bool TCFS::ISNewText (const char *name, char *texts[], char *names[], int n)
+{
+    ITextVectorProperty * tProp = getText(name);
+
+    if (tProp == NULL)
+        return false;
+
+    // Device Port Text
+    if (!strcmp(tProp->name, "DEVICE_PORT"))
+    {
+        if (IUUpdateText(tProp, texts, names, n) < 0)
+                        return false;
+
+                tProp->s = IPS_OK;
+                IDSetText(tProp, "Port updated.");
+
+                return true;
+    }
+
+
+    return false;
+	
+}
+
+/****************************************************************
+**
+**
+*****************************************************************/
+bool TCFS::ISNewSwitch (const char *name, ISState *states, char *names[], int n)
+{
+
+    ISwitch *current_active_switch = NULL, *target_active_switch = NULL;
+    // First process parent!
+    if (INDI::DefaultDriver::ISNewSwitch(deviceID, name, states, names, n) == true)
+        return true;
+
+    ISwitchVectorProperty *sProp = getSwitch(name);
+
+    if (sProp == NULL)
+        return false;
+
+    /*if (!strcmp(sProp->name, "CONNECTION"))
+    {
+        if (!strcmp(names[0], "CONNECT"))
+            connect();
+        else
+            disconnect();
+        return true;
+    }*/
+
+
+    if (isConnected() == false)
+    {
+      resetProperties();
+      IDMessage(deviceID, "TCF-S is offline. Connect before issiung any commands.");
+      return false;
+    }
+
+    // Which switch is CURRENTLY on?
+    current_active_switch = IUFindOnSwitch(sProp);
+
+    IUUpdateSwitch(sProp, states, names, n);
+
+    // Which switch the CLIENT wants to turn on?
+    target_active_switch = IUFindOnSwitch(sProp);
+
+    if (target_active_switch == NULL)
+    {
+        if (isDebug())
+        {
+            IDLog("Error: no ON switch found in %s property.\n", sProp->name);
+        }
+        return true;
+    }
+
+
+    if (!strcmp(sProp->name, "FOCUS_POWER"))
+    {
+        bool sleep = false;
+
+        // Sleep
+        if (!strcmp(target_active_switch->name, "FOCUS_SLEEP"))
+        {
+               dispatch_command(FSLEEP);
+               sleep = true;
+        }
+        // Wake Up
+        else
+            dispatch_command(FWAKUP);
+
+        if (read_tcfs() == false)
+        {
+              IUResetSwitch(sProp);
+              sProp->s = IPS_ALERT;
+              IDSetSwitch(sProp, "Error reading TCF-S reply.");
+              return true;
+        }
+
+            if (sleep)
+            {
+                if (isSimulation())
+                    strncpy(response, "ZZZ", TCFS_MAX_CMD);
+
+                if (!strcmp(response, "ZZZ"))
+                {
+                    sProp->s = IPS_OK;
+                    IDSetSwitch(sProp, "Focuser is set into sleep mode.");
+                    FocusPositionNP->s = IPS_IDLE;
+                    IDSetNumber(FocusPositionNP, NULL);
+                    FocusTemperatureNP->s = IPS_IDLE;
+                    IDSetNumber(FocusTemperatureNP, NULL);
+                    return true;
+                }
+                else
+                {
+                    sProp->s = IPS_ALERT;
+                    IDSetSwitch(sProp, "Focuser sleep mode operation failed. Response: %s.", response);
+                    return true;
+                }
+            }
+            else
+            {
+                if (isSimulation())
+                    strncpy(response, "WAKE", TCFS_MAX_CMD);
+
+                if (!strcmp(response, "WAKE"))
+                {
+                    sProp->s = IPS_OK;
+                    IDSetSwitch(sProp, "Focuser is awake.");
+                    FocusPositionNP->s = IPS_OK;
+                    IDSetNumber(FocusPositionNP, NULL);
+                    FocusTemperatureNP->s = IPS_OK;
+                    IDSetNumber(FocusTemperatureNP, NULL);
+                    return true;
+                }
+                else
+                {
+                    sProp->s = IPS_ALERT;
+                    IDSetSwitch(sProp, "Focuser wake up operation failed. Response: %s", response);
+                    return true;
+                }
+            }
+      }
+
+    if (isFocusSleep)
+    {
+        sProp->s = IPS_IDLE;
+        IUResetSwitch(sProp);
+
+        if (!strcmp(sProp->name, "FOCUS_MODE") && current_active_switch != NULL)
+            current_active_switch->s = ISS_ON;
+
+        IDSetSwitch(sProp, "Focuser is still in sleep mode. Wake up in order to issue commands.");
+        return true;
+    }
+
+    if (!strcmp(sProp->name, "FOCUS_MODE"))
+    {
+
+        sProp->s = IPS_OK;
+
+        if (!strcmp(target_active_switch->name, "Manual"))
+        {
+           dispatch_command(FMMODE);
+           read_tcfs();
+           if (isSimulation() == false && strcmp(response, "!"))
+           {
+               IUResetSwitch(sProp);
+               sProp->s = IPS_ALERT;
+               IDSetSwitch(sProp, "Error switching to manual mode. No reply from TCF-S. Try again.");
+               return true;
+           }
+       }
+        else if (!strcmp(target_active_switch->name, "Auto A"))
+        {
+            dispatch_command(FAMODE);
+            read_tcfs();
+            if (isSimulation() == false && strcmp(response, "A"))
+            {
+                IUResetSwitch(sProp);
+                sProp->s = IPS_ALERT;
+                IDSetSwitch(sProp, "Error switching to Auto Mode A. No reply from TCF-S. Try again.");
+                return true;
+            }
+        }
+        else
+        {
+            dispatch_command(FBMODE);
+            read_tcfs();
+            if (isSimulation() == false && strcmp(response, "B"))
+            {
+                IUResetSwitch(sProp);
+                sProp->s = IPS_ALERT;
+                IDSetSwitch(sProp, "Error switching to Auto Mode B. No reply from TCF-S. Try again.");
+                return true;
+            }
+        }
+
+        IDSetSwitch(sProp, NULL);
+        return true;
+    }
+
+    if (!strcmp(sProp->name, "FOCUS_MOTION"))
+    {
+        // Inward
+        if (!strcmp(target_active_switch->name, "FOCUS_INWARD"))
+          move_focuser(TCFS_INWARD);
+        // Outward
+        else
+            move_focuser(TCFS_OUTWARD);
+
+        return true;
+
+     }
+
+    if (!strcmp(sProp->name, "FOCUS_GOTO"))
+    {
+        int currentStep = nFocusSteps;
+
+        FocusPositionNP->s = IPS_BUSY;
+        sProp->s = IPS_OK;
+
+        // Min
+        if (!strcmp(target_active_switch->name, "FOCUS_MIN"))
+        {
+            nFocusSteps = nFocusCurrentPosition;
+            move_focuser(TCFS_INWARD);
+            nFocusSteps = currentStep;
+            IUResetSwitch(sProp);
+            IDSetSwitch(sProp, "Moving focouser to minimum position...");
+        }
+        // Center
+        else if (!strcmp(target_active_switch->name, "FOCUS_CENTER"))
+        {
+            dispatch_command(FCENTR);
+            read_tcfs();
+
+            if (isSimulation())
+                strncpy(response, "CENTER", TCFS_MAX_CMD);
+
+            if (!strcmp(response, "CENTER"))
+            {
+                IUResetSwitch(sProp);
+                sProp->s = IPS_OK;
+                FocusPositionNP->s = IPS_BUSY;
+                if (isTCFS3)
+                    nFocusTargetPosition = 5000;
+                else
+                    nFocusTargetPosition = 3500;
+
+                IDSetSwitch(sProp, "Moving focuser to center position %g...", nFocusTargetPosition);
+                return true;
+            }
+            else
+            {
+                IUResetSwitch(sProp);
+                sProp->s = IPS_ALERT;
+                IDSetSwitch(sProp, "Failed to move focuser to center position!");
+                return true;
+            }
+        }
+        // Max
+        else if (!strcmp(target_active_switch->name, "FOCUS_MAX"))
+        {
+            nFocusSteps = FocusPositionRequestNP->np[0].max - nFocusCurrentPosition;
+            move_focuser(TCFS_OUTWARD);
+            nFocusSteps = currentStep;
+            IUResetSwitch(sProp);
+            IDSetSwitch(sProp, "Moving focouser to maximum position %g...", FocusPositionRequestNP->np[0].max);
+        }
+        // Home
+        else if (!strcmp(target_active_switch->name, "FOCUS_HOME"))
+        {
+            dispatch_command(FHOME);
+            read_tcfs();
+
+            if (isSimulation())
+                strncpy(response, "DONE", TCFS_MAX_CMD);
+
+            if (!strcmp(response, "DONE"))
+            {
+                IUResetSwitch(sProp);
+                sProp->s = IPS_OK;
+                //FocusInfoNP->s = IPS_BUSY;
+                IDSetSwitch(sProp, "Moving focuser to new calculated position based on temperature...");
+                return true;
+            }
+            else
+            {
+                IUResetSwitch(sProp);
+                sProp->s = IPS_ALERT;
+                IDSetSwitch(sProp, "Failed to move focuser to home position!");
+                return true;
+            }
+        }
+
+        return true;
+    }
+
+
+
+    return false;
+}
+
+bool TCFS::move_focuser(TCFSMotion dir)
+{
+    ISwitchVectorProperty *sProp = getSwitch("FOCUS_MOTION");
+
+    if (sProp == NULL)
+        return false;
+
+    // Inward
+    if (dir == TCFS_INWARD)
+    {
+        dispatch_command(FIN);
+        nFocusTargetPosition = nFocusCurrentPosition - nFocusSteps;
+    }
+    // Outward
+    else
+    {
+        dispatch_command(FOUT);
+        nFocusTargetPosition = nFocusCurrentPosition + nFocusSteps;
+    }
+
+     if (read_tcfs() == false)
+     {
+          IUResetSwitch(sProp);
+          sProp->s = IPS_ALERT;
+          IDSetSwitch(sProp, "Error reading TCF-S reply.");
+          return false;
+     }
+
+        if (isSimulation())
+            strncpy(response, "*", TCFS_MAX_CMD);
+
+        if (!strcmp(response, "*"))
+        {
+            IUResetSwitch(sProp);
+            sProp->s = IPS_OK;
+            FocusPositionNP->s = IPS_BUSY;
+            IDSetSwitch(sProp, "Moving focuser %s %d steps to position %g.", (dir == TCFS_INWARD) ? "inward" : "outward", ((int) nFocusSteps), nFocusTargetPosition);
+            return true;
+        }
+        else
+        {
+            IUResetSwitch(sProp);
+            sProp->s = IPS_ALERT;
+            IDSetSwitch(sProp, "Failed to move focuser %s!", (dir == TCFS_INWARD) ? "inward" : "outward");
+            return true;
+        }
+}
+
+bool TCFS::dispatch_command(TCFSCommand command_type)
+{
+   int err_code = 0, nbytes_written=0, nbytes_read=0;
+   char tcfs_error[TCFS_ERROR_BUFFER];
+   INumberVectorProperty *nProp = NULL;
+   ISwitchVectorProperty *sProp = NULL;
+
+   // Clear string
+   command[0] = '\0';
+
+   switch (command_type)
+   {
+        // Focuser Manual Mode
+        case FMMODE:
+                strncpy(command, "FMMODE", TCFS_MAX_CMD);
+		break;
+
+        // Focuser Free Mode
+        case FFMODE:
+                strncpy(command, "FFMODE", TCFS_MAX_CMD);
+                break;
+        // Focuser Auto-A Mode
+        case FAMODE:
+                strncpy(command, "FAMODE", TCFS_MAX_CMD);
+                break;
+
+       // Focuser Auto-A Mode
+       case FBMODE:
+                 strncpy(command, "FBMODE", TCFS_MAX_CMD);
+                 break;
+
+       // Focus Center
+       case FCENTR:
+                 strncpy(command, "FCENTR", TCFS_MAX_CMD);
+                 break;
+
+       // Focuser In ânnnnâ
+       case FIN:
+                 simulated_position = nFocusCurrentPosition;
+
+                    /* if ( (nFocusTargetPosition - nFocusSteps) >= FocusInfoNP->np[0].min)
+                            nFocusTargetPosition -= nFocusSteps;
+                     else
+                         return false;*/
+
+                 snprintf(command, TCFS_MAX_CMD, "FI%04d", ((int) nFocusSteps));
+                 break;
+
+      // Focuser Out ânnnnâ
+      case FOUT:
+                 simulated_position = nFocusCurrentPosition;
+
+                 /*if ( (nFocusTargetPosition + nFocusSteps) <= FocusInfoNP->np[0].max)
+                    nFocusTargetPosition += nFocusSteps;
+                 else
+                     return false;*/
+
+                 snprintf(command, TCFS_MAX_CMD, "FO%04d", ((int) nFocusSteps));
+                 break;
+
+       // Focuser Position Read Out
+       case FPOSRO:
+                 strncpy(command, "FPOSRO", TCFS_MAX_CMD);
+                 break;
+
+       // Focuser Position Read Out
+       case FTMPRO:
+                strncpy(command, "FTMPRO", TCFS_MAX_CMD);
+                break;
+
+       // Focuser Sleep
+       case FSLEEP:
+                strncpy(command, "FSLEEP", TCFS_MAX_CMD);
+                break;
+       // Focuser Wake Up
+       case FWAKUP:
+               strncpy(command, "FWAKUP", TCFS_MAX_CMD);
+               break;
+       // Focuser Home Command
+       case FHOME:
+               strncpy(command, "FHOME", TCFS_MAX_CMD);
+               break;
+   }
+		
+   if (isDebug())
+        IDLog("Dispatching command #%s#\n", command);
+
+   if (isSimulation())
+       return true;
+
+  tcflush(fd, TCIOFLUSH);
+
+   if  ( (err_code = tty_write(fd, command, TCFS_MAX_CMD, &nbytes_written) != TTY_OK))
+   {
+        tty_error_msg(err_code, tcfs_error, TCFS_ERROR_BUFFER);
+        if (isDebug())
+            IDLog("TTY error detected: %s\n", tcfs_error);
+   	return false;
+   }
+
+   return true;
+}
+
+
+
+void TCFS::ISPoll()
+{
+   if (!isConnected())
+       return;
+
+   int f_position=0;
+   float f_temperature=0;
+
+   if (FocusPositionNP->s != IPS_IDLE)
+   {
+       // Read Position
+       // Manual Mode
+       if (FocusModeSP->sp[0].s == ISS_ON)
+             dispatch_command(FPOSRO);
+
+       if (read_tcfs() == false)
+                   return;
+
+       if (isSimulation())
+       {
+            if (FocusPositionNP->s == IPS_BUSY)
+            {
+               if ( static_cast<int>(nFocusTargetPosition - simulated_position) > 0)
+                    simulated_position += FocusStepNP->np[0].step;
+               else if ( static_cast<int>(nFocusTargetPosition - simulated_position) < 0)
+                    simulated_position -= FocusStepNP->np[0].step;
+           }
+
+          snprintf(response, TCFS_MAX_CMD, "P=%04d", simulated_position);
+          if (isDebug())
+               IDLog("Target Position: %g -- Simulated position: #%s#\n", nFocusTargetPosition, response);
+       }
+
+        sscanf(response, "P=%d", &f_position);
+
+        nFocusCurrentPosition = f_position;
+
+        if (nFocusCurrentPosition == nFocusTargetPosition)
+        {
+             FocusPositionNP->s = IPS_OK;
+             FocusPositionRequestNP->s = IPS_OK;
+             IDSetNumber(FocusPositionRequestNP, NULL);
+         }
+
+        IDSetNumber(FocusPositionNP, NULL);
+     }
+
+
+   if (FocusTemperatureNP->s != IPS_IDLE)
+   {
+       // Read Temperature
+       // Manual Mode
+       if (FocusModeSP->sp[0].s == ISS_ON)
+            dispatch_command(FTMPRO);
+
+       if (read_tcfs() == false)
+           return;
+
+       if (isSimulation())
+       {
+           snprintf(response, TCFS_MAX_CMD, "T=%0.1f", simulated_temperature);
+           if (isDebug())
+               IDLog("Simulated temperature: #%s#\n", response);
+       }
+
+       sscanf(response, "T=%f", &f_temperature);
+
+       nFocusTemperature = f_temperature;      
+       IDSetNumber(FocusTemperatureNP, NULL);
+
+   }
+
+}
+
+bool TCFS::read_tcfs()
+{
+    int err_code = 0, nbytes_written=0, nbytes_read=0;
+    char err_msg[TCFS_ERROR_BUFFER];
+
+    // Clear string
+    response[0] = '\0';
+
+    if (isSimulation())
+    {
+         strncpy(response, "SIMULATION", TCFS_MAX_CMD);
+         return true;
+    }
+
+    // Read until encountring a CR
+    if ( (err_code = tty_read_section(fd, response, 0x0D, 15, &nbytes_read)) != TTY_OK)
+    {
+            tty_error_msg(err_code, err_msg, 32);
+            if (isDebug())
+            {
+                IDLog("TTY error detected: %s\n", err_msg);
+                IDMessage(mydev, "TTY error detected: %s\n", err_msg);
+            }
+            return false;
+    }
+
+    // Remove LF & CR
+    response[nbytes_read-2] = '\0';
+
+    if (isDebug())
+        IDLog("Bytes Read: %d - strlen(response): %d - Reponse from TCF-S: #%s#\n", nbytes_read, strlen(response), response);
+
+    return true;
+}
+
+const char * TCFS::getDefaultName()
+{
+    return "TCFS";
+}
Index: /BAORadio/libindi/libindi/drivers/focuser/tcfs.h
===================================================================
--- /BAORadio/libindi/libindi/drivers/focuser/tcfs.h	(revision 504)
+++ /BAORadio/libindi/libindi/drivers/focuser/tcfs.h	(revision 504)
@@ -0,0 +1,111 @@
+/*
+    INDI Driver for Optec TCF-S Focuser
+
+    Copyright (C) 2010 Jasem Mutlaq (mutlaqja@ikarustech.com)
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+*/
+
+#ifndef TCFS_H
+#define TCFS_H
+
+#include <string>
+
+#include <indidevapi.h>
+#include <indicom.h>
+#include <indibase/defaultdriver.h>
+
+using namespace std;
+
+#define TCFS_MAX_CMD        16
+#define TCFS_MAX_TRIES      3
+#define TCFS_ERROR_BUFFER   1024
+
+class TCFS : public INDI::DefaultDriver
+{
+
+public:
+
+    enum TCFSCommand {         FMMODE ,         // Focuser Manual Mode
+                               FFMODE,          // Focuser Free Mode
+                               FAMODE,          // Focuser Auto-A Mode
+                               FBMODE,          // Focuser Auto-B Mode
+                               FCENTR,          // Focus Center
+                               FIN,             // Focuser In ânnnnâ
+                               FOUT,            // Focuser Out ânnnnâ
+                               FPOSRO,          // Focuser Position Read Out
+                               FTMPRO,          // Focuser Temperature Read Out
+                               FSLEEP,          // Focuser Sleep
+                               FWAKUP,          // Focuser Wake Up
+                               FHOME,           // Focuser Home Command
+			     };
+
+    enum TCFSMode { TCFS_MANUAL_MODE, TCFS_A_MODE, TCFS_B_MODE };
+    enum TCFSMotion { TCFS_INWARD, TCFS_OUTWARD };
+    enum TCFSError { NO_ERROR, ER_1, ER_2, ER_3 };
+
+    TCFS();
+    ~TCFS();
+   
+    virtual bool Connect();
+    virtual bool Disconnect();
+
+    // Standard INDI interface fucntions
+    virtual void ISGetProperties(const char *dev);
+    virtual bool ISNewNumber (const char *name, double values[], char *names[], int n);
+    virtual bool ISNewText (const char *name, char *texts[], char *names[], int n);
+    virtual bool ISNewSwitch (const char *name, ISState *states, char *names[], int n);
+ 	
+
+    void ISPoll();
+
+
+private: 
+
+    ISwitchVectorProperty *ConnectSP;
+    ISwitchVectorProperty *FocusPowerSP;
+    ISwitchVectorProperty *FocusModeSP;
+    INumberVectorProperty *FocusStepNP;
+    INumberVectorProperty *FocusPositionNP;
+    INumberVectorProperty *FocusPositionRequestNP;
+    INumberVectorProperty *FocusTemperatureNP;
+
+    // Functions
+    void init_properties();
+    bool move_focuser(TCFSMotion dir);
+
+    const char *getDefaultName();
+    bool read_tcfs();
+    bool dispatch_command(TCFSCommand command);
+
+    // Variables
+    string default_port;
+			
+    int fd;
+    char command[TCFS_MAX_CMD];
+    char response[TCFS_MAX_CMD];
+
+    unsigned int simulated_position;
+    unsigned int target_position;
+    float simulated_temperature;
+
+    bool isTCFS3;
+
+};
+
+#endif
+
+
Index: /BAORadio/libindi/libindi/drivers/telescope/BAO.cpp
===================================================================
--- /BAORadio/libindi/libindi/drivers/telescope/BAO.cpp	(revision 503)
+++ /BAORadio/libindi/libindi/drivers/telescope/BAO.cpp	(revision 504)
@@ -1,42 +1,21 @@
-#if 0
-
+/*
 #############################
 ##
 ## BAORadio Indi driver
 ## Franck RICHARD
-## Mai 2010
+## franckrichard033@gmail.com
+## Juin 2011
 ##
 #############################
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#include <math.h>
-#include <unistd.h>
-#include <time.h>
-#include <memory>
-#include <pthread.h>
-#include <iostream>
-#include <time.h>
-#include <unistd.h>
-#include <sys/time.h>
-
-#include <config.h>
-
-#include "indicom.h"
-
-#include "Socket.h"
+*/
 
 #include "BAO.h"
 
-using namespace std;
 
 auto_ptr<BAO> telescope(0);
 
-const int POLLMS = 1;				// Period of update, 1 ms.
-
-const char *mydev = "BAO";			// Name of our device.
+const int POLLMS = 1;					// Period of update, 1 ms.
+
+const char *mydev = "BAO";				// Name of our device.
 
 const char *BASIC_GROUP    = "Main Control";		// Main Group
@@ -52,190 +31,44 @@
 static void ISPoll(void *);
 
-static void retry_connection(void *);
-
-/**************************************************************************************
-**
-***************************************************************************************/
-void *pThreadSocket (void * arg)
-{
-    try
-    {
-        int pos = SocketsNumber;
-
-        // Trouver Ã©ventuellement un emplacement disponible dans l'intervalle [1..SocketsNumber]
-
-        /*
-        for (int i=1; i<SocketsNumber; i++)
-        {
-        if (!Sockets[i].Connected)
-        {
-        pos = i;
-        break;
-        }
-        }*/
-
-        server.accept ( Sockets[pos].new_sock );
-
-        Sockets[pos].IP=server.recupip(Sockets[pos].new_sock);
-
-        Sockets[pos].Connected=true;
-
-        if (pos == SocketsNumber ) SocketsNumber++;
-
-        InitThreadOK=true;
-    }
-    catch ( SocketException& e )
-    {
-        //A activer pour vÃ©rif
-
-        /*std::string oss;
-        oss="pThreadSocket exception : " + e.description() + "\n";
-        size_t size = oss.size() + 1;
-        char* buffer = new char[size];
-        strncpy(buffer, oss.c_str(), size);
-
-        IDLog(buffer);
-
-        delete [] buffer;*/
-    }
-
-    return NULL;
-}
-
-
-/**************************************************************************************
-** Utilisation d'un thread pour Ã©viter de bloquer l'execution du pilote
-** avec la commande accept
-***************************************************************************************/
-
-void BAO::InitThread()
-{
-    if (pthread_create (&th1, NULL, pThreadSocket, NULL) < 0)
-    {
-        IDLog("pthread_create error for threadSocket\n");
-    }
-
-    pthread_join (th1, NULL);
-}
-
-/**************************************************************************************
-** Initialisation du pilote BAO
-***************************************************************************************/
-void ISInit()
-{
-    static int isInit=0;
-
-    if (isInit) return;
-
-    if (telescope.get() == 0) telescope.reset(new BAO());
-
-    isInit = 1;
-
-    IEAddTimer (POLLMS, ISPoll, NULL);
-}
-
-/**************************************************************************************
-**
-***************************************************************************************/
-void ISGetProperties (const char *dev)
-{
-    ISInit();
-    telescope->ISGetProperties(dev);
-}
-
-/**************************************************************************************
-**
-***************************************************************************************/
-void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n)
-{
-    ISInit();
-    telescope->ISNewSwitch(dev, name, states, names, n);
-}
-
-/**************************************************************************************
-**
-***************************************************************************************/
-void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n)
-{
-    ISInit();
-    telescope->ISNewText(dev, name, texts, names, n);
-}
-
-/**************************************************************************************
-**
-***************************************************************************************/
-void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n)
-{
-    ISInit();
-    telescope->ISNewNumber(dev, name, values, names, n);
-}
-
-/**************************************************************************************
-**
-***************************************************************************************/
-void ISPoll (void *p)
-{
-    INDI_UNUSED(p);
-
-    telescope->ISPoll();
-    IEAddTimer (POLLMS, ISPoll, NULL);
-}
-
-
-/**************************************************************************************
-**
-***************************************************************************************/
-void ISNewBLOB (const char *dev, const char *name, int sizes[], int blobsizes[], char *blobs[], char *formats[], char *names[], int n)
-{
-    INDI_UNUSED(dev);
-    INDI_UNUSED(name);
-    INDI_UNUSED(sizes);
-    INDI_UNUSED(blobsizes);
-    INDI_UNUSED(blobs);
-    INDI_UNUSED(formats);
-    INDI_UNUSED(names);
-    INDI_UNUSED(n);
-}
-
-/**************************************************************************************
-**
-***************************************************************************************/
-void ISSnoopDevice (XMLEle *root)
-{
-    INDI_UNUSED(root);
-}
+void* LancementThread(BAO * appli);
+
 
 /**************************************************************************************
 ** Initialisation de la classe BAO
 ***************************************************************************************/
+
 BAO::BAO()
 {
     init_properties();
 
-    ConnectSP.s = IPS_IDLE;
-
+    // tÃ©lescope en Ã©tat IDLE
+    ConnectSP.s    = IPS_IDLE;
+
+    // derniÃšre actualisation
+    lastRA         = 0.0;
+    lastDEC        = 0.0;
+    JJAnc          = 0.0;
+
+    currentSet     =  0;
     lastSet        = -1;
-    fd             = -1;
-    simulation     = false;
-    lastRA         = 0;
-    lastDEC        = 0;
-    currentSet     = 0;
-    JJAnc          = 0.0;
-
-    SocketsNumber  = 1;
-
-    ActualisationTM1 = 15.0*60.0;
-
+    SocketsNumber  =  1;
+    TrackingMode   =  1;
+
+    // dÃ©lais en sec entre deux actualisations de la
+    // position dans les modes transit et tracking
+
+    ActualisationTM1 = 15.0 * 60.0;
     ActualisationTM2 = 5.0;
 
-    InitThreadOK=false;
-    LecturePosition=false;
-    Abort=false;
-    Park=false;
-    Goto=false;
-    LastGotoOK=true;
-
-    TrackingMode=1;
-
+    UpdateGoto      = true;
+    InitThreadOK    = false;
+    ActualisationPosition = false;
+    Abort           = false;
+    Park            = false;
+    Suivi            = false;
+    Exit            = false;
+
+
+    // initialisation des sockets (Antennes)
     for (int i=0; i<MAXHOSTNAME; i++)
     {
@@ -244,24 +77,33 @@
     }
 
+    // initialisations supplÃ©mentaires
     InitAntennes();
 
-
+    // NumÃ©ro de version
     IDLog("Initilizing from BAO device...\n");
-    IDLog("Driver Version: 2010-11-10\n");
-
-    //enableSimulation(true);
-}
-
-/**************************************************************************************
-**
+    IDLog("Driver Version: 2011-06-27\n");
+
+    //connect_telescope();
+}
+
+
+/**************************************************************************************
+** Destructeur
+** Lorsque l'on lance indi_BAO depuis indiserver dans un terminal
+** Le destructeur ne semble jamais Ãªtre atteint lorsque l'on sort...
 ***************************************************************************************/
 BAO::~BAO()
 {
-
-}
+    Exit=true;
+    sleep(1);
+    pthread_join (th1, NULL);
+}
+
+
 
 /**************************************************************************************
 ** Initialisation des boutons et des zones d'affichage dans la boÃ®te de dialogue INDI
 ***************************************************************************************/
+
 void BAO::init_properties()
 {
@@ -288,5 +130,4 @@
     IUFillTextVector(&ObjectTP, ObjectT, NARRAY(ObjectT), mydev, "OBJECT_INFO", "Object", BASIC_GROUP, IP_RW, 0, IPS_IDLE);
 
-
     // Equatorial Coords - SET
     IUFillNumber(&EquatorialCoordsWN[0], "RA", "RA  H:M:S", "%10.6m",  0., 24., 0., 0.);
@@ -294,9 +135,4 @@
     IUFillNumberVector(&EquatorialCoordsWNP, EquatorialCoordsWN, NARRAY(EquatorialCoordsWN), mydev, "EQUATORIAL_EOD_COORD_REQUEST" , "Equatorial JNow", BASIC_GROUP, IP_WO, 0, IPS_IDLE);
 
-    // Equatorial Coords - READ
-    //    IUFillNumber(&EquatorialCoordsRN[0], "RA", "RA  H:M:S", "%10.6m",  0., 24., 0., 0.);
-    //    IUFillNumber(&EquatorialCoordsRN[1], "DEC", "Dec D:M:S", "%10.6m", -90., 90., 0., 0.);
-    //    IUFillNumberVector(&EquatorialCoordsRNP, EquatorialCoordsRN, NARRAY(EquatorialCoordsRN), mydev, "EQUATORIAL_EOD_COORD" , "Equatorial JNow", BASIC_GROUP, IP_RO, 0, IPS_IDLE);
-
     // Geographic coord - SET
     IUFillNumber(&GeographicCoordsWN[0], "LAT", "Lat  D", "%10.6m",  -90., 90., 0., 0.);
@@ -310,20 +146,11 @@
     IUFillNumber(&ActualisationN2[0], "DELAY", "Tracking mode delay (Sec)", "%10.6m",  0., 3600., 0., 0.);
     IUFillNumberVector(&ActualisationNP2, ActualisationN2, NARRAY(ActualisationN2), mydev, "DELAY2" , "", OPTIONS_GROUP, IP_WO, 0, IPS_IDLE);
-
-    // Transit threshold
-    //IUFillNumber(&SlewAccuracyN[0], "TransitRA",  "RA (arcmin)", "%10.6m",  0., 60., 1., 3.0);
-    //IUFillNumber(&SlewAccuracyN[1], "TransitDEC", "Dec (arcmin)", "%10.6m", 0., 60., 1., 3.0);
-    //IUFillNumberVector(&SlewAccuracyNP, SlewAccuracyN, NARRAY(SlewAccuracyN), mydev, "Transit Accuracy", "", OPTIONS_GROUP, IP_RW, 0, IPS_IDLE);
-
-    // Tracking threshold
-    //IUFillNumber(&TrackAccuracyN[0], "TrackingRA", "RA (arcmin)", "%10.6m",  0., 60., 1., 3.0);
-    //IUFillNumber(&TrackAccuracyN[1], "TrackingDEC", "Dec (arcmin)", "%10.6m", 0., 60., 1., 3.0);
-    //IUFillNumberVector(&TrackAccuracyNP, TrackAccuracyN, NARRAY(TrackAccuracyN), mydev, "Tracking Accuracy", "", OPTIONS_GROUP, IP_RW, 0, IPS_IDLE);
-
-}
+}
+
 
 /**************************************************************************************
 ** Initialisation de la boÃ®te de dialogue INDI (suite)
 ***************************************************************************************/
+
 void BAO::ISGetProperties(const char *dev)
 {
@@ -336,5 +163,4 @@
     IDDefText(&ObjectTP, NULL);
     IDDefNumber(&EquatorialCoordsWNP, NULL);
-    //IDDefNumber(&EquatorialCoordsRNP, NULL);
     IDDefNumber(&GeographicCoordsWNP, NULL);
     IDDefSwitch(&OnCoordSetSP, NULL);
@@ -343,6 +169,4 @@
 
     // Options
-    //IDDefNumber(&SlewAccuracyNP, NULL);
-    //IDDefNumber(&TrackAccuracyNP, NULL);
     IDDefNumber(&ActualisationNP1, NULL);
     IDDefNumber(&ActualisationNP2, NULL);
@@ -350,7 +174,11 @@
 }
 
-/**************************************************************************************
-** En cas de changement de texte dans la boÃ®te de dialogue
-***************************************************************************************/
+
+
+/**************************************************************************************
+** En cas de changement de texte dans la boÃ®te de dialogue. Exemple : changement du
+** nom de l'objet. Cette fonction n'est pas encore utilisÃ©e
+***************************************************************************************/
+
 void BAO::ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n)
 {
@@ -380,7 +208,11 @@
 }
 
+
 /**************************************************************************************
 ** En cas de changement d'une valeur numÃ©rique dans la boÃ®te de dialogue Indi
-***************************************************************************************/
+** Exemple : longitude, latitude, ar, dec etc...
+**
+***************************************************************************************/
+
 void BAO::ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n)
 {
@@ -416,5 +248,5 @@
                 nset += Latitude >= -90.0 && Latitude <= 90.0;
 
-                Latitude*=Pidiv180;
+                Latitude *= Pidiv180;
             }
             else if (eqp == &GeographicCoordsWN[1])
@@ -423,8 +255,9 @@
                 nset += Longitude >= 0.0 && Longitude <= 360.0;
 
-                Longitude*=-Pidiv180;
+                Longitude *= -Pidiv180;
             }
         }
 
+        // Si la longitude et la latitude sont correctes
         if (nset == 2)
         {
@@ -443,4 +276,6 @@
             Longitude=0.0;
         }
+
+        DefinirLongitudeLatitude(Longitude, Latitude);
 
         return;
@@ -471,11 +306,13 @@
         }
 
-        targetRA  = newRA;
-        targetDEC = newDEC;
-
+
+        // si les coordonnÃ©es de l'objet sont correctes
         if (nset == 2)
         {
             char RAStr[32], DecStr[32];
             double targetAZ, targetAlt;
+
+            targetRA  = newRA;
+            targetDEC = newDEC;
 
             fs_sexa(RAStr, newRA, 2, 3600);
@@ -521,5 +358,5 @@
                 if (newAct1 >= 0.0 && newAct1 <= 3600.0)
                 {
-                    ActualisationTM1=newAct1;
+                    ActualisationTM1 = newAct1;
 
                     ActualisationNP1.s = IPS_OK;
@@ -549,5 +386,5 @@
                 if (newAct2 >= 0.0 && newAct2 <= 3600.0)
                 {
-                    ActualisationTM2=newAct2;
+                    ActualisationTM2 = newAct2;
 
                     ActualisationNP2.s = IPS_OK;
@@ -561,11 +398,12 @@
             }
         }
-
-    } /* end EquatorialCoordsWNP */
-}
+    }
+}
+
 
 /**************************************************************************************
 ** L'utilisateur clique sur l'un des boutons de la boÃ®te Indi
 ***************************************************************************************/
+
 void BAO::ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n)
 {
@@ -583,4 +421,5 @@
 
         connect_telescope();
+
         return;
     }
@@ -615,18 +454,15 @@
         IUResetSwitch(&AbortSlewSP);
 
-        /*
-        if (EquatorialCoordsWNP.s == IPS_BUSY)
-        {
-
-        AbortSlewSP.s = IPS_OK;
-        EquatorialCoordsWNP.s       = IPS_IDLE;
-        EquatorialCoordsRNP.s       = IPS_IDLE;
-        HorizontalCoordsWNP.s       = IPS_IDLE;
-        IDSetSwitch(&AbortSlewSP, "Slew aborted.");
-        IDSetNumber(&EquatorialCoordsWNP, NULL);
-        IDSetNumber(&EquatorialCoordsRNP, NULL);
-        IDSetNumber(&HorizontalCoordsWNP, NULL);
-        }
-        */
+        if (EquatorialCoordsWNP.s == IPS_OK)
+        {
+            AbortSlewSP.s = IPS_OK;
+            EquatorialCoordsWNP.s       = IPS_IDLE;
+            ObjectTP.s = IPS_IDLE;
+
+            IDSetSwitch(&ConnectSP, "Envoi de la commande Abort\n");
+            IDSetNumber(&EquatorialCoordsWNP, NULL);
+            IDSetText(&ObjectTP, NULL);
+        }
+
         return;
     }
@@ -642,47 +478,28 @@
         IUResetSwitch(&ParkSP);
 
-        /*
-        if (EquatorialCoordsWNP.s == IPS_BUSY)
-        {
-
-        AbortSlewSP.s = IPS_OK;
-        EquatorialCoordsWNP.s       = IPS_IDLE;
-        EquatorialCoordsRNP.s       = IPS_IDLE;
-        HorizontalCoordsWNP.s       = IPS_IDLE;
-        IDSetSwitch(&AbortSlewSP, "Slew aborted.");
-        IDSetNumber(&EquatorialCoordsWNP, NULL);
-        IDSetNumber(&EquatorialCoordsRNP, NULL);
-        IDSetNumber(&HorizontalCoordsWNP, NULL);
-        }
-        */
+        if (EquatorialCoordsWNP.s == IPS_OK)
+        {
+            AbortSlewSP.s = IPS_OK;
+            EquatorialCoordsWNP.s       = IPS_IDLE;
+            ObjectTP.s = IPS_IDLE;
+
+            IDSetSwitch(&ConnectSP, "Envoi de la commande Park\n");
+            IDSetNumber(&EquatorialCoordsWNP, NULL);
+            IDSetText(&ObjectTP, NULL);
+        }
+
         return;
     }
 }
 
-/**************************************************************************************
-** fct peut-Ãªtre inutile
-***************************************************************************************/
-void BAO::handle_error(INumberVectorProperty *nvp, int err, const char *msg)
-{
-    nvp->s = IPS_ALERT;
-
-    /* If the error is a time out, then the device doesn't support this property */
-    if (err == -2)
-    {
-        nvp->s = IPS_ALERT;
-        IDSetNumber(nvp, "Device timed out. Current device may be busy or does not support %s. Will retry again.", msg);
-    }
-    else
-        /* Changing property failed, user should retry. */
-        IDSetNumber( nvp , "%s failed.", msg);
-
-    fault = true;
-}
 
 /**************************************************************************************
 ** Initialisation des vecteurs INDI
 ***************************************************************************************/
+
 void BAO::reset_all_properties()
 {
+    char chaine[10];
+
     ConnectSP.s			= IPS_IDLE;
     OnCoordSetSP.s		= IPS_IDLE;
@@ -691,8 +508,5 @@
     ObjectTP.s			= IPS_IDLE;
     EquatorialCoordsWNP.s	= IPS_IDLE;
-    //EquatorialCoordsRNP.s	= IPS_IDLE;
     GeographicCoordsWNP.s	= IPS_IDLE;
-    //SlewAccuracyNP.s		= IPS_IDLE;
-    //TrackAccuracyNP.s		= IPS_IDLE;
     ActualisationNP1.s		= IPS_IDLE;
     ActualisationNP2.s		= IPS_IDLE;
@@ -712,56 +526,75 @@
     IDSetText(&ObjectTP, NULL);
     IDSetNumber(&EquatorialCoordsWNP, NULL);
-    //IDSetNumber(&EquatorialCoordsRNP, NULL);
     IDSetNumber(&GeographicCoordsWNP, NULL);
-    //IDSetNumber(&SlewAccuracyNP, NULL);
-    //IDSetNumber(&TrackAccuracyNP, NULL);
     IDSetNumber(&ActualisationNP1, NULL);
     IDSetNumber(&ActualisationNP2, NULL);
-
-}
-
-/**************************************************************************************
+}
+
+
+
+
+
+/**************************************************************************************
+** Gestion du thread
+** permet de suivre la connexion/dÃ©connexion des antennes
 **
-***************************************************************************************/
-void BAO::correct_fault()
-{
-    fault = false;
-    IDMessage(mydev, "Telescope is online.");
-}
-
-/**************************************************************************************
+** l'utilisation d'un thread permet d'Ã©viter de bloquer l'exÃ©cution du pilote
+** avec la fonction accept qui est bloquante
+***************************************************************************************/
+
+void *BAO::pThreadSocket ()
+{
+    do
+    {
+        try
+        {
+            server.accept( Sockets[SocketsNumber].new_sock );
+
+            Sockets[SocketsNumber].IP = server.recupip(Sockets[SocketsNumber].new_sock);
+
+            Sockets[SocketsNumber++].Connected = true;
+
+            InitThreadOK = true;
+
+            usleep(100);
+        }
+        catch ( SocketException& e )
+        {
+            /*IDLog("Indi_BAO, pThreadSocket exception : ");
+            IDLog(e.description().c_str());
+            IDLog("\n");*/
+        }
+    }
+    while (!Exit);
+
+    pthread_exit (0);
+}
+
+
+
+
+/**************************************************************************************
+** Astuce pour lancer le thread depuis la classe BAO
 **
 ***************************************************************************************/
-bool BAO::is_connected()
-{
-    if (simulation) return true;
-
-    // return (ConnectSP.sp[0].s == ISS_ON);
-    return (ConnectSP.s == IPS_OK);
-}
-
-/**************************************************************************************
-**
-***************************************************************************************/
-static void retry_connection(void * p)
-{
-
-}
-
-
-/**************************************************************************************
-** Extraction de la position de l'antenne
-** dans le retour de la commande POS
-** POS/Valeur az/Valeur alt
-***************************************************************************************/
-
-Position BAO::ExtractPosition(std::string str)
-{
-    Position result;
-
-    std::string str2;
-
-    result.x = -1;
-    result.y = -1;
+
+void* LancementThread(BAO * appli)
+{
+    appli->pThreadSocket();
+
+
+    return 0;
+}
+
+
+/**************************************************************************************
+** Extraction de la position de l'antenne aprÃšs l'envoie de la commande P
+** Le retour de la commande P est POSITION/valeur_az/valeur_alt/
+** ExtractPosition retourne donc Valeur_az et Valeur_alt
+***************************************************************************************/
+
+bool BAO::ExtractPosition(string str, Position *result)
+{
+    string str2;
 
     int pos = str.find("/");
@@ -769,5 +602,5 @@
     if (pos != string::npos)
     {
-        str2 = str.substr(pos+1);
+        str2 = str.substr(pos + 1);
 
         pos = str2.find("/");
@@ -775,11 +608,15 @@
         if (pos != string::npos)
         {
-            result.x = atoi(str2.substr(0, pos).c_str());
-
-            result.y = atoi(str2.substr(pos+1).c_str());
-        }
-    }
-
-    return result;
+            result->x = atol(str2.substr(0, pos).c_str());
+
+            result->y = atol(str2.substr(pos + 1).c_str());
+	    
+	    return true;
+        }        
+    } 
+
+    IDLog((str +" fail\n").c_str());
+
+    return false;
 }
 
@@ -787,7 +624,8 @@
 
 /************************************************************************************
-* cette procÃ©dure convertit les coordonnÃ©es equatoriales de l'objet visÃ©
+* cette procÃ©dure convertit les coordonnÃ©es Ã©quatoriales de l'objet visÃ©
 * en unitÃ©s de codeurs des paraboles (nb de tours des deux axes moteurs depuis la position PARK)
 ************************************************************************************/
+
 void BAO::ADDEC2Motor(double newRA, double newDEC)
 {
@@ -797,12 +635,22 @@
     char AltStr[32];
 
+
     // Calcule la hauteur et l'azimut de la zone du ciel pointÃ©e (en fonction de la date et du lieu)
 
-    Azimut(tsl, Latitude, newRA * 15.0 * Pidiv180, newDEC * Pidiv180, &targetAz, &targetAlt);
+    Azimut( newRA * 15.0 * Pidiv180, newDEC * Pidiv180, &targetAz, &targetAlt);
+    
+    // Refraction atmosphÃ©rique
+    
+    targetAlt = RefractionAtmospherique(targetAlt);
+
+    // Petit calcul pour faire en sorte que le sud soit Ã  Â° d'azimut
+
+    targetAz = VerifAngle( targetAz + Pi );
 
     // En degrÃ©s
 
     targetAlt *= N180divPi;
-    targetAz *= N180divPi;
+    targetAz *=  N180divPi;
+
 
     // Affichage dans les logs
@@ -811,30 +659,48 @@
     fs_sexa(AltStr, targetAlt, 2, 3600);
 
-    IDLog("Horizontal coords : az %s - Alt %s\n", AzStr, AltStr);
-
-    // Le calcul est ici trÃšs sommaire et arbitraire :
-    // Je considÃšre qu'il y a 100 positions possibles sur les deux axes
-    // De plus, je considÃšre qu'il n'est pas possible de viser un objet Ã 
-    // moins de 30Â° de hauteur au-dessus de l'horizon
-
-    TargetPosition.x=(int)(targetAz*100.0/360.0);
-
-    targetAlt=((90.0-targetAlt)/60.0);
-
-    if (targetAlt>=1.0)
-    {
-        targetAlt=1.0; //on ne peut pas viser un objet situÃ© Ã  moins de 30Â°
-        //au-dessus de l'horizon
+    IDLog("Horizontal coords : az = %s     Alt = %s\n", AzStr, AltStr);
+
+
+    //Conversion des deux angles en pas codeurs
+
+    if (targetAlt < 30.0 )
+    {
+        // L'objet est trop bas (<30Â°). On annule le suivi...
 
         IDSetSwitch(&OnCoordSetSP, "Erreur ! L objet suivi est situe a moins de 30Â° au-dessus de l horizon. Goto annule.");
 
-        Goto=false;
-
-        LecturePosition=false;
+        Suivi = false;
+
+        ActualisationPosition = false;
 
         InitAntennes();
     }
-
-    TargetPosition.y=(int)(100.0*targetAlt);
+    else
+    {
+        // Si la hauteur est supÃ©rieure Ã  90Â°, on doit faire une rotation de l'azimut de 180Â° et corriger
+        // la hauteur en appliquant hauteur= 180Â° - hauteur
+
+        if (targetAlt > 90.0)
+        {
+            targetAlt = 180.0 - targetAlt;
+            targetAz += 180.0;
+        }
+
+        // On applique la formule de Marc pour convertir la hauteur en nombre de pas codeur alt
+
+        double I0 = 81.0;
+        double I2 = 128279.4 - 129723.4 * sin( (targetAlt - 20.2345) * Pidiv180 ) ;
+
+        double Codalt = (sqrt(I2) - I0) / 0.078947;
+
+
+        TargetPosition.y = (int) Arrondi(Codalt);
+
+        //4000 pas pour 360Â° sur l'axe az
+
+        TargetPosition.x = (int) Arrondi( targetAz * 4000.0 / 360.0);
+
+        IDLog("Nbre de pas codeurs az = %i        Alt = %i\n", TargetPosition.x, TargetPosition.y);
+    }
 }
 
@@ -842,10 +708,9 @@
 /************************************************************************************
 * Retourne simplement le nombre d'antennes connectÃ©es
-* et capables de communiquer
 ************************************************************************************/
 
 int BAO::AntennesConnectees()
 {
-    int num=0;
+    int num = 0;
 
     for (int i=1; i<SocketsNumber; i++) if (Sockets[i].Connected) num++;
@@ -861,21 +726,36 @@
 void BAO::InitAntennes()
 {
-    for (int i=0; i < MAXHOSTNAME ; i++)
-    {
-        Sockets[i].status=0;
-        Sockets[i].sendalertes=0;
-        Sockets[i].AttenteExecution=0;
-        Sockets[i].AnomaliesExecution=0;
-        Sockets[i].etape=0;
-
-        Sockets[i].ack_status=false;
-        Sockets[i].ack_pos=false;
-        Sockets[i].ack_park=false;
-        Sockets[i].ack_abort=false;
-        Sockets[i].ack_goto=false;
-
-        Sockets[i].PosValides=false;
-        Sockets[i].GotoOk=false;
-    }
+    for (int i=0; i < MAXHOSTNAME; i++)
+    {
+        Sockets[i].status             = 0;
+        Sockets[i].sendalertes        = 0;
+        Sockets[i].AttenteExecution   = 0;
+        Sockets[i].AnomaliesExecution = 0;
+        Sockets[i].etape              = 0;
+
+        Sockets[i].ack_status = false;
+        Sockets[i].ack_pos    = false;
+        Sockets[i].ack_park   = false;
+        Sockets[i].ack_abort  = false;
+        Sockets[i].ack_goto   = false;
+
+        Sockets[i].PosValides = false;
+        Sockets[i].GotoOk     = false;
+    }
+}
+
+
+
+/**************************************************************************************
+** En cas de problÃšme
+** DÃ©connecter l'antenne utilisant le socket num
+***************************************************************************************/
+
+void BAO::DeconnecterSocket(int num)
+{
+    IDLog("Deconnexion de l antenne : %s\n", Sockets[num].IP.c_str());
+    Sockets[num].new_sock.shutdown();
+    Sockets[num].Connected = false;
+    Sockets[num].IP = "";
 }
 
@@ -883,11 +763,13 @@
 /**************************************************************************************
 ** ProcÃ©dure principale
-** Elle est appelÃ©e toutes les POLLMS ms (ici 1 ms)
-***************************************************************************************/
+** Elle est appelÃ©e toutes les ms
+***************************************************************************************/
+
 void BAO::ISPoll()
 {
-    static bool ISPOLLRunning=false;
-    static int memSocketsNumber=-1;
-    static unsigned int compt=100;
+    static int memSocketsNumber = -1;       // Combien d'antennes Ã©taient-elles connectÃ©es Ã  l'appel prÃ©cÃ©dent d'ISPoll ?
+    static unsigned int compt   =  0;      // permet de rÃ©pondre toutes les 100ms aux demandes de nouvelles connexions
+
+    // utilise pour le travail sur les chaine
 
     int pos;
@@ -898,16 +780,13 @@
     struct timezone tz;
 
+    //si pas de connexion avec le seveur d'indi -> on sort
+
     if (is_connected() == false) return;
 
-    if (ISPOLLRunning) return;
-
-    ISPOLLRunning=true;
-
-    compt++;
-
-
-    //toutes les 100 millisec
-
-    if ( compt%100 == 0)
+
+    // toutes les 100 millisec, on actualise le jour julien
+    // le temps sidÃ©ral local etc...
+
+    if ( compt%100 == 0 )
     {
         //RÃ©cupÃ©ration de la date et de l'heure
@@ -917,34 +796,32 @@
         gettimeofday(&tv, &tz);
 
-        Annee=(double)(date.tm_year+1900);
-        Mois=(double)(date.tm_mon+1);
-        Jour=(double)date.tm_mday;
-        Heu=(double)date.tm_hour;
-        Min=(double)date.tm_min;
-        Sec=(double)date.tm_sec+tv.tv_usec/1.0E6;
-        UTCP=0.0;//(double)date.tm_isdst;
-
-
-        //Calcul du temps sidÃ©ral local
+        double Annee=(double)(date.tm_year+1900);
+        double Mois=(double)(date.tm_mon+1);
+        double Jour=(double)date.tm_mday;
+        double Heu=(double)date.tm_hour;
+        double Min=(double)date.tm_min;
+        double Sec=(double)date.tm_sec+tv.tv_usec/1.0E6;
+        double UTCP=0.0;//(double)date.tm_isdst;
+
+        // On transmet la date et l'heure Ã  la classe Astro
+
+        DefinirDateHeure(Annee, Mois, Jour, Heu, Min, Sec);
+
+        //Puis on calule le temps sidÃ©ral local, le JJ etc...
 
         CalculTSL();
-
-
-        //Y a-t-il de nouvelles tentatives de connexion sur le serveur ?
-
-        InitThread();
-    }
-
-
-
-
-    if (InitThreadOK)  // Il faut qu'il y ait eu au moins une connexion dÃ©tectÃ©e par le thread pour continuer
+    }
+
+
+    // Il faut que le thread soit actif
+
+    if (InitThreadOK)
     {
 
         // Nouvelle connexion sur le socket !
 
-        if (SocketsNumber>memSocketsNumber)
-        {
-            memSocketsNumber=SocketsNumber;
+        if (SocketsNumber > memSocketsNumber)
+        {
+            memSocketsNumber = SocketsNumber;
 
             IDSetSwitch(&ConnectSP, "Connexion de l antenne %s. (Antennes connectees : %i)",
@@ -953,265 +830,341 @@
 
 
-
+        /////////////////////////////////////////////////
         // DÃ©but des Ã©changes avec les microcontrÃŽleurs
 
         // Analyse des rÃ©ponses des microcontrÃŽleurs
 
-        for (int i=1; i<SocketsNumber; i++) /*if (Sockets[i].Connected)*/
-        {
-            try
+        for (int i=1; i<SocketsNumber; i++)
+        {
+            if (Sockets[i].Connected)
             {
-                std::string reponse, memreponse;
-                // on rÃ©cupÃšre la rÃ©ponse du microcontrÃŽleur
-
-                Sockets[i].new_sock >> reponse;
-
-                //IDSetSwitch(&OnCoordSetSP, "RÃ©ponse ISPOLL : %s\n", reponse.c_str());        // pour vÃ©rif
-
-                //Dans le cas oÃ¹ plusieurs trames seraient arrivÃ©es entre deux appels de POLLMS
-                //les traiter successivement
-
-                pos=reponse.find("\n");   // d'oÃ¹ l'intÃ©rÃªt de mettre un '\n' Ã  la fin des trames
-                //pour diffÃ©rencier une trame de la prÃ©cÃ©dente
-
-                while ((pos!=string::npos) && (reponse.length()>1))
+                try
                 {
-                    memreponse=reponse.substr(pos+1);
-
-                    reponse=reponse.substr(0, pos);
-
-
-                    // On traite ici les acknowledges
-
-                    if ((reponse.find("ACK")!=string::npos) && (reponse.find("NACK")==string::npos))
+                    string reponse, buffereponse;
+
+                    // on rÃ©cupÃšre la rÃ©ponse du microcontrÃŽleur
+
+                    Sockets[i].new_sock >> reponse;
+
+                    // Dans le cas oÃ¹ plusieurs trames seraient arrivÃ©es entre deux appels de POLLMS
+                    // les traiter successivement
+
+                    // d'oÃ¹ l'intÃ©rÃªt de mettre un '\n' Ã  la fin des trames
+                    // pour diffÃ©rencier une trame de la prÃ©cÃ©dente
+
+                    pos = reponse.find("\n");
+
+                    // S'il y a une rÃ©ponse
+
+                    while ((pos != string::npos) && (reponse.length() > 1))
                     {
-                        if (reponse.find("POSITION")!=string::npos)
+                        // on garde en stock la seconde partie trame pour un
+                        // traitement ultÃ©rieure
+                        buffereponse = reponse.substr(pos + 1);
+
+                        // Partie traitÃ©e
+                        reponse = reponse.substr(0, pos);
+			
+			IDLog("RÃ©ponse reÃ§ue de %s : %s\n", Sockets[i].IP.c_str(), reponse.c_str());
+
+                        // On analyse ici les acknowledges
+                        if ((reponse.find("ACK") != string::npos) && (reponse.find("NACK") == string::npos))
                         {
-                            Sockets[i].ack_pos=true;
+                            if (reponse.find("POSITION")  != string::npos)
+                            {
+                                Sockets[i].ack_pos=true;
+                            }
+                            else if (reponse.find("GOTO") != string::npos)
+                            {
+                                Sockets[i].ack_goto=true;
+                            }
+                            else if (reponse.find("PARK") != string::npos)
+                            {
+                                Sockets[i].ack_park=true;
+                            }
+                            else if (reponse.find("ABORT")!= string::npos)
+                            {
+                                Sockets[i].ack_abort=true;
+                            }
                         }
-                        else if (reponse.find("GOTO")!=string::npos)
+                        else
                         {
-                            Sockets[i].ack_goto=true;
-                        }
-                        else if (reponse.find("PARK")!=string::npos)
-                        {
-                            Sockets[i].ack_park=true;
-                        }
-                        else if (reponse.find("ABORT")!=string::npos)
-                        {
-                            Sockets[i].ack_abort=true;
-                        }
-                    }
-                    else
-                    {
-
-                        //rÃ©ponse Ã  la requÃªte POSITION
-                        if (reponse.find("POSITION")!=string::npos)
-                        {
-                            if (reponse.find("NACK")!=string::npos)
+                            //rÃ©ponse Ã  la requÃªte POSITION
+
+                            if (reponse.find("POSITION") != string::npos)
                             {
-                                OnCoordSetSP.s = IPS_ALERT;
-                                IDSetSwitch(&OnCoordSetSP, "ALERTE antenne %s : position de l antenne inconnue !\n",
-                                            Sockets[i].IP.c_str());
-                                Sockets[i].PosValides=false;
-                                // Si la position de l'antenne est inconnue, on dÃ©connecte l'antenne
-                                Sockets[i].Connected=false;
+                                if (reponse.find("NACK") != string::npos)
+                                {
+                                    //problÃšme concernant la rÃ©ponse Ã  la commande P
+                                    OnCoordSetSP.s = IPS_ALERT;
+                                    IDSetSwitch(&OnCoordSetSP, "ALERTE antenne %s : position de l antenne inconnue !\n",
+                                                Sockets[i].IP.c_str());
+                                    Sockets[i].PosValides = false;
+                                    // Si la position de l'antenne est inconnue, on dÃ©connecte l'antenne
+                                    Sockets[i].Connected  = false;
+                                }
+                                else if (Sockets[i].ack_pos)
+                                {                              
+				    if ( Sockets[i].PosValides = (ExtractPosition(reponse, &Sockets[i].Pos) == true) )
+                              	    {
+				      OnCoordSetSP.s = IPS_OK;
+                                      IDSetSwitch(&OnCoordSetSP, "Antenne %s : POSITION OK  (x=%i, y=%i)\n",
+                                                Sockets[i].IP.c_str(), Sockets[i].Pos.x, Sockets[i].Pos.y);
+				    }
+				    else
+				    {
+				      OnCoordSetSP.s = IPS_ALERT;
+                                      IDSetSwitch(&OnCoordSetSP, "Antenne %s : La position n est pas valide !\n",
+                                                Sockets[i].IP.c_str());
+				    }
+				      
+                                }
                             }
-                            else if (Sockets[i].ack_pos)
+
+                            //rÃ©ponse Ã  la requÃªte PARK
+
+                            if (reponse.find("PARK") != string::npos)
                             {
-                                OnCoordSetSP.s = IPS_OK;
-                                Sockets[i].Pos = ExtractPosition(reponse);
-                                Sockets[i].PosValides = true;
-                                IDSetSwitch(&ParkSP, "Antenne %s : POSITION OK  (x=%i, y=%i)\n",
-                                            Sockets[i].IP.c_str(), Sockets[i].Pos.x, Sockets[i].Pos.y);
+                                if (reponse.find("NACK") != string::npos)
+                                {
+                                    ParkSP.s = IPS_ALERT;
+                                    IDSetSwitch(&ParkSP, "ALERTE antenne %s : erreur PARK !\n", Sockets[i].IP.c_str());
+                                }
+                                else if (Sockets[i].ack_park && reponse.find("OK")!=string::npos)
+                                {
+                                    ParkSP.s = IPS_OK;
+                                    IDSetSwitch(&ParkSP, "Antenne %s : PARK OK\n",  Sockets[i].IP.c_str());
+                                }
                             }
 
-                        }//rÃ©ponse Ã  la requÃªte PARK
-                        else if (reponse.find("PARK")!=string::npos)
-                        {
-                            if (reponse.find("NACK")!=string::npos)
+                            //rÃ©ponse Ã  la requÃªte ABORT
+
+                            if (reponse.find("ABORT") != string::npos)
                             {
-                                ParkSP.s = IPS_ALERT;
-                                IDSetSwitch(&ParkSP, "ALERTE antenne %s : erreur PARK !\n", Sockets[i].IP.c_str());
+                                if (reponse.find("NACK") != string::npos)
+                                {
+                                    AbortSlewSP.s = IPS_ALERT;
+                                    IDSetSwitch(&AbortSlewSP, "ALERTE antenne %s : erreur ABORT !\n",  Sockets[i].IP.c_str());
+                                }
+                                else if (Sockets[i].ack_abort && reponse.find("OK")!=string::npos)
+                                {
+                                    AbortSlewSP.s = IPS_OK;
+                                    IDSetSwitch(&AbortSlewSP, "Antenne %s : ABORT OK\n",  Sockets[i].IP.c_str());
+                                }
+
                             }
-                            else if (reponse.find("OK")!=string::npos)
+
+                            //rÃ©ponse Ã  la requÃªte GOTO
+
+                            if (reponse.find("GOTO") != string::npos)
                             {
-                                ParkSP.s = IPS_OK;
-                                IDSetSwitch(&ParkSP, "Antenne %s : PARK OK\n",  Sockets[i].IP.c_str());
-                            }
-
-                        }//rÃ©ponse Ã  la requÃªte ABORT
-                        else if (reponse.find("ABORT")!=string::npos)
-                        {
-                            if (reponse.find("NACK")!=string::npos)
-                            {
-                                AbortSlewSP.s = IPS_ALERT;
-                                IDSetSwitch(&AbortSlewSP, "ALERTE antenne %s : erreur ABORT !\n",  Sockets[i].IP.c_str());
-                            }
-
-                            if (reponse.find("OK")!=string::npos)
-                            {
-                                AbortSlewSP.s = IPS_OK;
-                                IDSetSwitch(&AbortSlewSP, "Antenne %s : ABORT OK\n",  Sockets[i].IP.c_str());
-                            }
-
-                        } //rÃ©ponse Ã  la requÃªte GOTO
-                        else if (reponse.find("GOTO")!=string::npos)
-                        {
-                            if (reponse.find("NACK")!=string::npos)
-                            {
-                                OnCoordSetSP.s = IPS_ALERT;
-                                IDSetSwitch(&OnCoordSetSP, "ALERTE antenne %s : Erreur GOTO !\n",  Sockets[i].IP.c_str());
-                                Sockets[i].Connected=false;
-                            }
-                            else if (Sockets[i].ack_goto)
-                            {
-                                if (reponse.find("OK")!=string::npos)
+                                if (reponse.find("NACK") != string::npos)
                                 {
-                                    OnCoordSetSP.s = IPS_OK;
-
-                                    Sockets[i].GotoOk=true;
-
-                                    IDSetSwitch(&ParkSP, "Antenne %s : GOTO OK.\n",  Sockets[i].IP.c_str());
-
-                                    lastRA  = targetRA;
-                                    lastDEC = targetDEC;
-
-                                    //IDLog("We received JNow RA %s - DEC %s\n", RAStr, DecStr);*/
-
-                                    EquatorialCoordsWNP.s = IPS_OK;
-                                    IDSetNumber (&EquatorialCoordsWNP, NULL);
-
-                                    // Fin du Goto pour toutes les antennes ?
-
-                                    int num=0;
-
-                                    for (int j=1; j<SocketsNumber; j++) if (Sockets[j].Connected)
+                                    OnCoordSetSP.s = IPS_ALERT;
+                                    IDSetSwitch(&OnCoordSetSP, "ALERTE antenne %s : Erreur GOTO !\n",  Sockets[i].IP.c_str());
+                                    DeconnecterSocket(i);
+                                }
+                                else if (Sockets[i].ack_goto)
+                                {
+                                    if (reponse.find("OK") != string::npos)
+                                    {
+                                        // On a la confirmation que l'antenne 'i' a bien rÃ©alisÃ©
+                                        // le goto
+
+                                        // On prend note
+
+                                        Sockets[i].GotoOk = true;
+
+                                        // Message pour l'utilisateur
+					
+					OnCoordSetSP.s = IPS_OK;
+                                        IDSetSwitch(&OnCoordSetSP, "Antenne %s : GOTO OK.\n",  Sockets[i].IP.c_str());
+
+                                        // Fin du Goto pour toutes les antennes ?
+
+                                        int num=0;
+
+                                        for (int j=1; j<SocketsNumber; j++)
+					{
+					  if (Sockets[j].Connected)
+                                            {
+                                                if (Sockets[j].GotoOk) num++;
+                                            }
+					}
+
+                                        if ((num == AntennesConnectees()) && (num>0))
                                         {
-                                            if (Sockets[j].GotoOk) num++;
-                                        }
-
-                                    if ((num == AntennesConnectees()) && (num>0))
-                                    {
-                                        LecturePosition=false;
-
-                                        InitAntennes();
-
-                                        LastGotoOK=true;
-
-                                        IDSetSwitch(&OnCoordSetSP, "GOTO OK !");
+					    // C'est bon ! Tout marche bien...
+                                            // On actualise l'AR et la dec dans la boÃ®te de dialogue
+
+                                            lastRA  = targetRA;
+                                            lastDEC = targetDEC;
+
+                                            // On change en vert les voyants dans la boÃ®te de dialogue
+
+                                            OnCoordSetSP.s = IPS_OK;
+                                            EquatorialCoordsWNP.s = IPS_OK;
+                                            IDSetNumber (&EquatorialCoordsWNP, NULL);
+
+                                            // On a fini le mouvement. On attend le prochain goto...
+
+                                            ActualisationPosition=false;
+
+                                            // RÃ©initialisation des antennes en vue d'un prochain goto
+
+                                            InitAntennes();
+
+                                            UpdateGoto=true;
+
+                                            // Confirmation dans la boÃ®te de dialogue que toutes
+                                            // les antennes sont OK
+					    
+					    OnCoordSetSP.s = IPS_OK;
+                                            IDSetSwitch(&OnCoordSetSP, "GOTO OK !");
+                                        }                                        
                                     }
                                 }
                             }
                         }
+
+                        // On passe Ã  la trame suivante si memreponse n'est pas vide
+
+                        reponse=buffereponse;
+                        pos=reponse.find("\n");
                     }
-
-                    // On passe Ã©ventuellement Ã  la trame suivante
-
-                    reponse=memreponse;
-                    pos=reponse.find("\n");
-
+                }
+                catch (SocketException& e) //AÃ¯e
+                {
+                    DeconnecterSocket(i);
+
+                    IDLog("Indi_BAO, SocketException IsPoll : ");
+                    IDLog(e.description().c_str());
+                    IDLog("\n");
                 }
             }
-            catch (SocketException& e) //AÃ¯e
+        }
+
+
+        ///////////////////////////////////////
+        // L'utilisateur a demandÃ© l'annulation du mouvement
+        // en cours
+
+        if (Abort)
+        {
+            // On arrÃªte le suivi d'un objet
+
+            Suivi = false;
+
+            // On arrÃªte l'enchaÃ®nement des actions
+            // pour rÃ©aliser un goto
+
+            ActualisationPosition = false;
+
+            // On envoie l'ordre ABORT Ã  toutes les antennes
+
+            for (int i=1; i<SocketsNumber; i++)
             {
-                Sockets[i].new_sock.shutdown();
-                Sockets[i].new_sock.create();
-                Sockets[i].Connected = Sockets[i].new_sock.connect((std::string)Sockets[i].IP);
-
                 if (Sockets[i].Connected)
-                {
-                    Sockets[i].AttenteExecution=0;
-                    Sockets[i].AnomaliesExecution=0;
-                }
-
-                std::string oss;
-                oss="SocketException IsPoll : " + e.description() + "\n";
-                size_t size = oss.size() + 1;
-                char* buffer = new char[size];
-                strncpy(buffer, oss.c_str(), size);
-                IDLog(buffer);
-                delete [] buffer;
-            }
-        }
-
-
-
-        if (Abort)
-        {
-            IDSetSwitch(&ConnectSP, "Envoi de la commande Abort\n");
-
-            Goto=false;
-
-            for (int i=1; i<SocketsNumber; i++) if (Sockets[i].Connected)
                 {
                     if (!ABORT(i)) Sockets[i].sendalertes++;
                 }
-
-            LecturePosition=false;
+            }
+
+            IDSetSwitch(&OnCoordSetSP, "ABORT OK !");
+
+            // RÃ©inititialisation des paramÃštres des antennes
 
             InitAntennes();
 
+            //Pour permettre de refaire un abort
+
             Abort=false;
         }
 
+        ///////////////////////////////////////
+        // L'utilisateur a demandÃ© de mettre les antennes au repos
 
         if (Park)
         {
-            IDSetSwitch(&ConnectSP, "Envoi de la commande Park\n");
-
-            Goto=false;
-
-            for (int i=1; i<SocketsNumber; i++) if (Sockets[i].Connected)
+            // On arrÃªte le suivi d'un objet
+
+            Suivi = false;
+
+            // On arrÃªte l'enchaÃ®nement des actions
+            // pour rÃ©aliser un goto
+
+            ActualisationPosition = false;
+
+            // On envoie l'ordre PARK Ã  toutes les antennes
+
+            for (int i=1; i<SocketsNumber; i++)
+            {
+                if (Sockets[i].Connected)
                 {
                     if (!PARK(i)) Sockets[i].sendalertes++;
                 }
-
-            LecturePosition=false;
+            }
+
+            IDSetSwitch(&OnCoordSetSP, "PARK OK !");
+
+            // RÃ©inititialisation des paramÃštres des antennes
 
             InitAntennes();
 
+            //Pour permettre de refaire un park
+
             Park=false;
         }
 
 
+        ///////////////////////////////////////
         // Gestion du suivi
 
-        if ((Goto) && (LastGotoOK))
+        if ((Suivi) && (UpdateGoto))
         {
             // DurÃ©e entre deux actualisations
 
-            double delai=ActualisationTM1/3600.0/24.0;   // Actualisation toutes les 15 minutes en mode transit
-
-            if (TrackingMode==2) delai=ActualisationTM2/3600.0/24.0;   //et 5 secs en mode tracking
-
-
-            // On actualise la position
-
-            if (JJ-JJAnc > delai)
+            double delai=ActualisationTM1 / 3600.0 / 24.0;   // Actualisation toutes les 15 minutes en mode transit
+
+            if (TrackingMode==2) delai=ActualisationTM2 / 3600.0 / 24.0;   //et 5 secs en mode tracking
+
+
+            // On actualise la position si le delai est dÃ©passÃ©
+
+            if (GetJJ() - JJAnc > delai)
             {
-
-                LastGotoOK=false;
-
-                LecturePosition=true;
+                UpdateGoto = false;
+
+                // Conversion des coordonnÃ©es en pas moteur
 
                 ADDEC2Motor(targetRA, targetDEC);
 
+                // On rÃ©initialise les antennes en vue du goto
+
                 InitAntennes();
 
-                JJAnc=JJ;
+                ActualisationPosition = true;
+
+                // On sauvegarde la date
+
+                JJAnc = GetJJ();
             }
 
-            //Plus d'antenne !
+            //Plus d'antenne ! On arrÃªte le suivi
 
             if (AntennesConnectees() == 0)
             {
-                // LecturePosition=false;
-
-                // Goto=false;
-
-                // InitAntennes();
-
-                if ( compt % 1000 == 0)  IDSetSwitch(&OnCoordSetSP, "Erreur ! Plus d antennes connectees !");
+                if ( compt % 1000 == 0)
+                {
+                    IDSetSwitch(&OnCoordSetSP, "Erreur ! Plus d antennes connectees !");
+
+                    if (Suivi) IDLog("ArrÃªt du suivi !");
+
+                    ActualisationPosition=false;
+
+                    Suivi=false;
+
+                    InitAntennes();
+                }
             }
         }
@@ -1222,173 +1175,174 @@
         // puis envoi d'une commande Goto
 
-        if (LecturePosition)
-        {
-            for (int i=1; i<SocketsNumber; i++) /*if (Sockets[i].Connected)*/
+        if (ActualisationPosition)
+        {
+            for (int i=1; i<SocketsNumber; i++)
             {
-                switch (Sockets[i].etape)
+                if (Sockets[i].Connected)
                 {
-
-                    //Envoi de la commande POS
-                case 0 :
-                {
-                    Sockets[i].ack_pos=false;
-                    Sockets[i].PosValides=false;
-
-                    if (!POSITION(i)) Sockets[i].sendalertes++;
-
-                    Sockets[i].etape++;
-                }
-                break;
-
-                //ack POS
-                case 1 :
-                {
-                    if (Sockets[i].ack_pos)
+                    switch (Sockets[i].etape)
                     {
-                        Sockets[i].AttenteExecution=0;
-                        Sockets[i].AnomaliesExecution=0;
+
+                        //Envoi de la commande POS
+
+                    case 0 :
+                    {
+                        Sockets[i].ack_pos    = false;
+                        Sockets[i].PosValides = false;
+
+                        if (!POSITION(i)) Sockets[i].sendalertes++;
+
                         Sockets[i].etape++;
-                        i--;
                     }
-                    else
+                    break;
+
+
+                    // A-ton bien reÃ§u l'ack POS ?
+
+                    case 1 :
                     {
-                        // on rÃ©itÃšre l'ordre prÃ©cÃ©dent si rien ne se passe
-
-                        Sockets[i].AttenteExecution++;
-
-                        if (Sockets[i].AttenteExecution>MAXATTENTE)
+                        if (Sockets[i].ack_pos)
                         {
-                            Sockets[i].etape=0;
-                            Sockets[i].AttenteExecution=0;
-                            Sockets[i].AnomaliesExecution++;
+                            // tout marche bien
+                            Sockets[i].AttenteExecution = 0;
+                            Sockets[i].AnomaliesExecution = 0;
+                            Sockets[i].etape++;
+                            i--; //permet de revenir sur ce mÃªme socket malgrÃ© la boucle
+                            // -> plus rapide
                         }
-
-                        if (Sockets[i].AnomaliesExecution>MAXANOMALIES)
+                        else
                         {
-                            Sockets[i].etape=3;
-
-                            // if ( compt % 1000 == 0)
+                            // on rÃ©itÃšre l'ordre prÃ©cÃ©dent si rien ne se passe
+
+                            // On garde une trace de l'anomalie
+                            Sockets[i].AttenteExecution++;
+
+                            if (Sockets[i].AttenteExecution > MAXATTENTE)
                             {
+                                // on recommence depuis le dÃ©but
+                                Sockets[i].etape = 0;
+                                Sockets[i].AttenteExecution = 0;
+                                Sockets[i].AnomaliesExecution++;
+                            }
+
+                            // Toujours rien -> plus sÃ©rieux : il faut dÃ©connecter l'antenne
+                            if (Sockets[i].AnomaliesExecution > MAXANOMALIES)
+                            {
+			        OnCoordSetSP.s = IPS_ALERT;
                                 IDSetSwitch(&OnCoordSetSP, "Erreur sur l antenne %s : pas d acknowledge recu apres l ordre POSITION. \
-                                Deconnexion de l antenne.", Sockets[i].IP.c_str());
-                                Sockets[i].Connected=false;
+    Deconnexion de l antenne.", Sockets[i].IP.c_str());
+                                DeconnecterSocket(i);
                             }
                         }
                     }
-                }
-                break;
-
-                //Valeurs pos valides ?
-                case 2 :
-                {
-                    if (Sockets[i].PosValides)
+                    break;
+
+
+                    //Les valeurs retournÃ©es pas la commande POSITION sont-elles valides ?
+
+                    case 2 :
                     {
-                        Sockets[i].AttenteExecution=0;
-                        Sockets[i].etape++;
-                    }
-                    else
-                    {
-                        // on rÃ©itÃšre l'ordre prÃ©cÃ©dent si rien ne se passe
-
-                        Sockets[i].AttenteExecution++;
-
-                        if (Sockets[i].AttenteExecution>MAXATTENTE)
+                        if (Sockets[i].PosValides)
                         {
-                            Sockets[i].etape=2;
-                            Sockets[i].AttenteExecution=0;
-                            Sockets[i].AnomaliesExecution++;
+                            Sockets[i].AttenteExecution = 0;
+                            Sockets[i].AnomaliesExecution = 0;
+                            Sockets[i].etape++; // on passe Ã  l'Ã©tape suivante
                         }
-
-                        if (Sockets[i].AnomaliesExecution>MAXANOMALIES)
+                        else
                         {
-                            Sockets[i].etape=3;
-
-                            // if ( compt % 1000 == 0)
+                            // on rÃ©itÃšre l'ordre prÃ©cÃ©dent si rien ne se passe
+                            Sockets[i].AttenteExecution++;
+
+                            if (Sockets[i].AttenteExecution > MAXATTENTE)
                             {
+                                // on attend davantage la rÃ©ponse posvalides                                
+                                Sockets[i].etape = 2;
+                                Sockets[i].AttenteExecution = 0;
+                                Sockets[i].AnomaliesExecution++;
+                            }
+
+                            if (Sockets[i].AnomaliesExecution > MAXANOMALIES)
+                            {
+			        OnCoordSetSP.s = IPS_ALERT;
                                 IDSetSwitch(&OnCoordSetSP, "Erreur sur l antenne %s : la position retournee n est pas valide. \
-                                Deconnexion de l antenne.", Sockets[i].IP.c_str());
-                                Sockets[i].Connected=false;
+    Deconnexion de l antenne.", Sockets[i].IP.c_str());
+                                DeconnecterSocket(i);
                             }
                         }
                     }
-                }
-                break;
-
-                //ack goto  ?
-                case 4 :
-                {
-                    if (Sockets[i].ack_goto)
+                    break;
+
+
+                    // A-ton reÃ§u l'acknowledge de la commande goto ?
+
+                    case 4 :
                     {
-                        Sockets[i].AttenteExecution=0;
-                        Sockets[i].AnomaliesExecution=0;
-                        Sockets[i].etape++;
-                    }
-                    else
-                    {
-                        // on rÃ©itÃšre l'ordre prÃ©cÃ©dent si rien ne se passe
-
-                        Sockets[i].AttenteExecution++;
-
-                        if (Sockets[i].AttenteExecution>MAXATTENTE)
+                        if (Sockets[i].ack_goto)
                         {
-                            Sockets[i].etape=4;
-                            Sockets[i].AttenteExecution=0;
-                            Sockets[i].AnomaliesExecution++;
+                            Sockets[i].AttenteExecution = 0;
+                            Sockets[i].AnomaliesExecution = 0;
+                            Sockets[i].etape++; // on passe Ã  l'Ã©tape suivante
                         }
-
-                        if (Sockets[i].AnomaliesExecution>MAXANOMALIES)
+                        else
                         {
-                            Sockets[i].etape=6;
-
-                            // if ( compt % 1000 == 0)
+                            // on rÃ©itÃšre l'ordre prÃ©cÃ©dent si rien ne se passe
+                            Sockets[i].AttenteExecution++;
+
+                            if (Sockets[i].AttenteExecution > MAXATTENTE)
                             {
+                                // On prolonge l'attente                                
+                                Sockets[i].etape = 4;
+                                Sockets[i].AttenteExecution = 0;
+                                Sockets[i].AnomaliesExecution++;
+                            }
+
+                            if (Sockets[i].AnomaliesExecution > MAXANOMALIES)
+                            {
+			        OnCoordSetSP.s = IPS_ALERT;
                                 IDSetSwitch(&OnCoordSetSP, "Erreur sur l antenne %s : pas d acknowledge recu apres l ordre GOTO. \
-                                Deconnexion de l antenne.", Sockets[i].IP.c_str());
-                                Sockets[i].Connected=false;
+    Deconnexion de l antenne.", Sockets[i].IP.c_str());
+                                DeconnecterSocket(i);
                             }
                         }
                     }
-                }
-                break;
-
-                //goto ok  ?
-                case 5 :
-                {
-                    if (Sockets[i].GotoOk)
+                    break;
+
+
+                    //  Confirmation goto ok ?
+
+                    case 5 :
                     {
-                        Sockets[i].AttenteExecution=0;
-                        Sockets[i].AnomaliesExecution=0;
-                        Sockets[i].etape++;
-                    }
-                    else
-                    {
-                        // on rÃ©itÃšre l'ordre prÃ©cÃ©dent si rien ne se passe
-
-                        Sockets[i].AttenteExecution++;
-
-                        if (Sockets[i].AttenteExecution>MAXATTENTE)
+                        if (Sockets[i].GotoOk)
                         {
-                            Sockets[i].etape=5;
-                            Sockets[i].AttenteExecution=0;
-                            Sockets[i].AnomaliesExecution++;
+                            Sockets[i].AttenteExecution = 0;
+                            Sockets[i].AnomaliesExecution = 0;
+                            Sockets[i].etape++;
                         }
-
-                        if (Sockets[i].AnomaliesExecution>MAXANOMALIESGOTO)
+                        else
                         {
-                            Sockets[i].etape=6;
-
-                            // if ( compt % 1000 == 0)
+                            // on rÃ©itÃšre l'ordre prÃ©cÃ©dent si rien ne se passe
+                            Sockets[i].AttenteExecution++;
+
+                            if (Sockets[i].AttenteExecution > MAXATTENTE)
                             {
+                                // On prolonge l'attente
+                                
+                                Sockets[i].etape = 5;
+                                Sockets[i].AttenteExecution = 0;
+                                Sockets[i].AnomaliesExecution++;
+                            }
+
+			    // On dÃ©connecte l'antenne s'il n'y a pas de coonfirmation du goto au bout de 2 minutes			    
+                            if (Sockets[i].AnomaliesExecution > MAXANOMALIESGOTO)
+                            {
+			        OnCoordSetSP.s = IPS_ALERT;
                                 IDSetSwitch(&OnCoordSetSP, "Erreur sur l antenne %s : l antenne n a pas renvoye GOTO/OK. \
-                                Deconnexion de l antenne.", Sockets[i].IP.c_str());
-                                Sockets[i].Connected=false;
-
-
+    Deconnexion de l antenne.", Sockets[i].IP.c_str());
+                                DeconnecterSocket(i);
                             }
                         }
                     }
-                }
-                break;
-
+                    break;
+                    }
                 }
             }
@@ -1396,60 +1350,62 @@
 
 
-
-
-
-
-        // DÃ©tection d'anomalies concernant l'envoi de trames sur la socket. dÃ©connexion du micro-cont ?
-
-        for (int i=1; i<SocketsNumber; i++) if (Sockets[i].Connected)
+        ///////////////////////////////////////
+        //On attend que toutes les antennes soient prÃªtes pour lancer l'ordre Goto -> meilleure synchronisation
+
+        int num=0;
+
+        for (int i=1; i<SocketsNumber; i++)
+        {
+            if (Sockets[i].Connected)
+            {
+                if (Sockets[i].etape == 3) num++; //fin de la procÃ©dure ActualisationPosition.
+                // num antennes sont prÃªtes Ã  recevoir l'ordre GOTO
+            }
+        }
+
+        if ((num == AntennesConnectees()) && (num>0))
+        {
+            for (int i=1; i<SocketsNumber; i++ )
+            {
+                if (Sockets[i].Connected)
+                {
+                    Sockets[i].ack_goto = false;
+                    Sockets[i].AttenteExecution = 0;
+                    Sockets[i].AnomaliesExecution = 0;
+
+                    if (!GOTO(i, TargetPosition.x - Sockets[i].Pos.x , TargetPosition.y - Sockets[i].Pos.y )) Sockets[i].sendalertes++;
+
+                    Sockets[i].etape++;
+                }
+            }
+        }
+
+        ///////////////////////////////////////
+        // DÃ©tection d'anomalies sur la socket. DÃ©connexion du micro-cont ?
+
+        for (int i=1; i<SocketsNumber; i++)
+        {
+            if (Sockets[i].Connected)
             {
                 if (Sockets[i].sendalertes > 0)
                 {
-                    Sockets[i].etape=5;
-
-                    //  if ( compt % 1000 == 0)
-                    {
-                        IDSetSwitch(&OnCoordSetSP, "Erreur sur l antenne %s : deconnexion de l antenne.", Sockets[i].IP.c_str());
-
-                        Sockets[i].Connected=false;
-                    }
+		    OnCoordSetSP.s = IPS_ALERT;
+                    IDSetSwitch(&OnCoordSetSP, "Erreur sur l antenne %s : deconnexion de l antenne.", Sockets[i].IP.c_str());
+
+                    DeconnecterSocket(i);
                 }
             }
-
-
-
-        //On attend que toutes les antennes soient prÃªtes pour lancer l'ordre Goto -> meilleure synchronisation
-
-        int num=0;
-
-        for (int i=1; i<SocketsNumber; i++) if (Sockets[i].Connected)
-            {
-                if (Sockets[i].etape == 3) num++; //fin de la procÃ©dure LecturePosition. Les antennes sont prÃªtes
-                //Ã  recevoir l'ordre GOto
-            }
-
-        if ((num == AntennesConnectees()) && (num>0))
-        {
-            for (int i=1; i<SocketsNumber; i++ ) if (Sockets[i].Connected)
-                {
-                    Sockets[i].ack_goto=false;
-                    Sockets[i].AttenteExecution=0;
-                    Sockets[i].AnomaliesExecution=0;
-
-                    if (!GOTO(i, Sockets[i].Pos.x - TargetPosition.x, Sockets[i].Pos.y - TargetPosition.y )) Sockets[i].sendalertes++;
-
-                    Sockets[i].etape++;
-                }
-        }
-    }
-
-    ISPOLLRunning=false;
-}
-
-
-
-/**************************************************************************************
-**
-***************************************************************************************/
+        }
+    }
+
+    compt++;
+}
+
+
+
+/**************************************************************************************
+** Mode transit ou tracking
+***************************************************************************************/
+
 bool BAO::process_coords()
 {
@@ -1459,21 +1415,28 @@
     case BAO_TRANSIT:
 
+        //Eteindre les voyants dans la boÃ®te de dialogue Indi
         EquatorialCoordsWNP.s = IPS_BUSY;
+        AbortSlewSP.s = IPS_IDLE;
+        ParkSP.s = IPS_IDLE;
 
         IDSetNumber (&EquatorialCoordsWNP, NULL);
+        IDSetSwitch (&AbortSlewSP, NULL);
+        IDSetSwitch (&ParkSP, NULL);
+
+        // On prÃ©pare les antennes pour le prochain goto
 
         InitAntennes();
 
-        JJAnc=JJ;
+        JJAnc = GetJJ();
+	
+	ADDEC2Motor(targetRA, targetDEC);
 
         TrackingMode = 1;
 
-        Goto=true;
-
-        LastGotoOK=false;
-
-        LecturePosition=true;
-
-        ADDEC2Motor(targetRA, targetDEC);
+        Suivi = true;
+
+        UpdateGoto = false;
+
+        ActualisationPosition = true;
 
         break;
@@ -1482,21 +1445,26 @@
     case BAO_TRACKING:
 
+        //Eteindre les voyants dans la boÃ®te de dialogue Indi
         EquatorialCoordsWNP.s = IPS_BUSY;
+        AbortSlewSP.s = IPS_IDLE;
+        ParkSP.s = IPS_IDLE;
 
         IDSetNumber (&EquatorialCoordsWNP, NULL);
+        IDSetSwitch (&AbortSlewSP, NULL);
+        IDSetSwitch (&ParkSP, NULL);
 
         InitAntennes();
 
-        JJAnc=JJ;
+        JJAnc=GetJJ();
+	
+	ADDEC2Motor(targetRA, targetDEC);
 
         TrackingMode = 2;
 
-        Goto=true;
-
-        LastGotoOK=false;
-
-        LecturePosition=true;
-
-        ADDEC2Motor(targetRA, targetDEC);
+        Suivi = true;
+
+        UpdateGoto = false;
+
+        ActualisationPosition = true;       
 
         break;
@@ -1506,7 +1474,276 @@
 }
 
+
+
+/**************************************************************************************
+** Connexion / DÃ©connexion avec le tÃ©lescope
+***************************************************************************************/
+
+void BAO::connect_telescope()
+{
+    switch (ConnectSP.sp[0].s)
+    {
+    case ISS_ON:
+
+        // Etats des voyants
+
+        ConnectS[0].s = ISS_ON;
+        ConnectS[1].s = ISS_OFF;
+        ConnectSP.s = IPS_OK;
+        IDSetSwitch (&ConnectSP, "BAORadio is online. Retrieving basic data...");
+
+        // Petit message
+
+        IDLog("\nHello BAORadio !\n");
+
+        // On lance le thread !
+
+        Exit=false;
+
+        if (pthread_create (&th1, NULL, (void*(*)(void*))LancementThread, this) < 0)
+        {
+            IDLog("pthread_create error for threadSocket\n");
+        }
+
+        break;
+
+    case ISS_OFF:
+
+        // On sort du thread
+
+        Exit = true;
+        sleep(1);
+        pthread_join (th1, NULL);
+        InitThreadOK = false;
+
+        // Etat des voyants
+
+        ConnectS[0].s = ISS_OFF;
+        ConnectS[1].s = ISS_ON;
+        ConnectSP.s = IPS_IDLE;
+        IDSetSwitch (&ConnectSP, "BAORadio is offline.");
+        IDLog("Telescope is offline.");
+
+        // On dÃ©connecte tous les sockets
+
+        for (int i=0; i<MAXHOSTNAME; i++)
+        {
+            DeconnecterSocket(i);
+        }
+
+        // init
+
+        InitAntennes();
+
+        SocketsNumber = 1;
+
+        break;
+    }
+}
+
+
+
+
+/**************************************************************************************
+**  Envoie une commande sur le socket numsocket
+***************************************************************************************/
+
+bool BAO::COMMANDE(int numsocket, char* Commande, char* Params)
+{
+    char chaine[MAXCARACTERES];
+
+    try
+    {
+        sprintf(chaine, "%s%s\n", Commande, Params);
+	
+	Sockets[numsocket].new_sock << chaine;
+	
+	IDLog("Commande envoyÃ©e Ã  %s: %s", Sockets[numsocket].IP.c_str(), chaine);
+    }
+    catch (SocketException& e)
+    {
+        DeconnecterSocket(numsocket);
+
+        IDLog("Indi_BAO, COMMANDE exception : ");
+        IDLog(e.description().c_str());
+        IDLog("\n");
+
+        return false;
+    }
+
+    return true;
+}
+
+
+/**************************************************************************************
+** Commande POSITION
+***************************************************************************************/
+
+bool BAO::POSITION(int numsocket)
+{
+    return COMMANDE(numsocket, (char*)"P", (char*)"");
+}
+
+/**************************************************************************************
+** Commande PARK
+***************************************************************************************/
+
+bool BAO::PARK(int numsocket)
+{
+    return COMMANDE(numsocket, (char*)"Z", (char*)"");
+}
+
+/**************************************************************************************
+** Commande ABORT
+***************************************************************************************/
+
+bool BAO::ABORT(int numsocket)
+{
+    return COMMANDE(numsocket, (char*)"A", (char*)"");
+}
+
+
+/**************************************************************************************
+** Commande GOTO
+***************************************************************************************/
+
+bool BAO::GOTO(int numsocket, int deltaAz, int deltaAlt)
+{
+    char Params[MAXCARACTERES];
+    char sensAz;
+    char sensAlt;
+
+    sensAlt = 1;
+    sensAz  = 1;
+
+    if ( deltaAz < 0 )
+    {
+        deltaAz = -deltaAz;
+        sensAz  = 0;
+    }
+
+    if ( deltaAlt < 0 )
+    {
+        deltaAlt = -deltaAlt;
+        sensAlt  = 0;
+    }
+
+    // VÃ©rification du nombre de pas Ã  faire au niveau de l'axe azimut
+    // Rappel : un tour complet autour de l'axe az fait 4000 pas codeur (#define NBREPASCODEURSAZ dans BAO.h)
+
+    // problÃšme 1 : si deltaAz > Ã  un demi-tours - soit 2000 pas alors
+    // on fait le trajet dans le sens inverse pour aller plus vite
+
+    // problÃšme 2 : Passage au mÃ©ridien
+    // on se situe Ã  quelques secondes de degrÃ©s avant le sud par exemple (nb de pas 3995 par exemple)
+    // et on franchit le mÃ©ridien (nb de pas codeur = 5 par exemple)
+    // On risque alors de faire un tour complet en sens inverse pour rattraper l'objet -> Ã  Ã©viter
+
+    // Ã©vite de faire des tours complets en Az pour rien...
+    while (deltaAz > NBREPASCODEURSAZ) deltaAz -= NBREPASCODEURSAZ;
+
+    // Doit rÃ©soudre tous les problÃšmes...
+    if (deltaAz > NBREPASCODEURSAZ / 2 )
+    {
+        deltaAz = NBREPASCODEURSAZ - deltaAz;
+        sensAz = 1 - sensAz;
+    }
+
+    //on envoie les coordonnÃ©es au driver
+
+    if (sensAz == 1 )  sensAz='f';
+    else sensAz='b';
+    if (sensAlt == 1 ) sensAlt='f';
+    else sensAlt='b';
+
+    sprintf(Params, "%c%04i%c%04i", sensAz, deltaAz, sensAlt, deltaAlt);
+
+    return COMMANDE(numsocket, (char*)"G", Params);
+}
+
+
+
+/**************************************************************************************
+** Les fonctions qui suivent sont nÃ©cessaires pour construire un pilote Indi
+** Elles sont appelÃ©es par le noyau d'Indi
+***************************************************************************************/
+
+/**************************************************************************************
+** Initialisation du pilote BAO
+***************************************************************************************/
+
+void ISInit()
+{
+    //Il ne faut exÃ©cuter la fonction qu'une seule fois
+    static int isInit = 0;
+
+    if (isInit) return;
+
+    if (telescope.get() == 0) telescope.reset(new BAO());
+
+    isInit = 1;
+
+    //initialisation du timer
+
+    IEAddTimer (POLLMS, ISPoll, NULL);
+}
+
+
+void ISGetProperties (const char *dev)
+{
+    ISInit();
+
+    telescope->ISGetProperties(dev);
+}
+
+void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n)
+{
+    ISInit();
+    telescope->ISNewSwitch(dev, name, states, names, n);
+}
+
+void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n)
+{
+    ISInit();
+    telescope->ISNewText(dev, name, texts, names, n);
+}
+
+void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n)
+{
+    ISInit();
+    telescope->ISNewNumber(dev, name, values, names, n);
+}
+
+void ISNewBLOB (const char *dev, const char *name, int sizes[], int blobsizes[], char *blobs[], char *formats[], char *names[], int n)
+{
+    INDI_UNUSED(dev);
+    INDI_UNUSED(name);
+    INDI_UNUSED(sizes);
+    INDI_UNUSED(blobsizes);
+    INDI_UNUSED(blobs);
+    INDI_UNUSED(formats);
+    INDI_UNUSED(names);
+    INDI_UNUSED(n);
+}
+
+void ISSnoopDevice (XMLEle *root)
+{
+    INDI_UNUSED(root);
+}
+
+void ISPoll (void *p)
+{
+    INDI_UNUSED(p);
+
+    telescope->ISPoll();
+
+    IEAddTimer (POLLMS, ISPoll, NULL);
+}
+
+
 /**************************************************************************************
 **
 ***************************************************************************************/
+
 int BAO::get_switch_index(ISwitchVectorProperty *sp)
 {
@@ -1518,45 +1755,4 @@
 }
 
-/**************************************************************************************
-** Activation de l'interface
-***************************************************************************************/
-void BAO::connect_telescope()
-{
-    switch (ConnectSP.sp[0].s)
-    {
-    case ISS_ON:
-        ConnectS[0].s = ISS_ON;
-        ConnectS[1].s = ISS_OFF;
-        IDLog("\nHello BAORadio !\n");
-
-        ConnectSP.s = IPS_OK;
-        IDSetSwitch (&ConnectSP, "BAORadio is online. Retrieving basic data...");
-
-
-        break;
-
-    case ISS_OFF:
-        ConnectS[0].s = ISS_OFF;
-        ConnectS[1].s = ISS_ON;
-        ConnectSP.s = IPS_IDLE;
-
-        SocketsNumber=1;
-        InitThreadOK=false;
-
-        for (int i=0; i<MAXHOSTNAME; i++)
-        {
-            Sockets[i].Connected=false;
-            Sockets[i].IP="";
-            Sockets[i].new_sock.shutdown();
-        }
-
-        InitAntennes();
-
-        IDSetSwitch (&ConnectSP, "BAORadio is offline.");
-        IDLog("Telescope is offline.");
-
-        break;
-    }
-}
 
 /**************************************************************************************
@@ -1566,6 +1762,4 @@
 {
     //  IDSetNumber (&EquatorialCoordsRNP, NULL);
-
-
 }
 
@@ -1588,12 +1782,9 @@
 **
 ***************************************************************************************/
-void BAO::enable_simulation(bool enable)
-{
-    simulation = enable;
-
-    if (simulation)
-        IDLog("Warning: Simulation is activated.\n");
-    else
-        IDLog("Simulation is disabled.\n");
+
+bool BAO::is_connected()
+{
+    // return (ConnectSP.sp[0].s == ISS_ON);
+    return (ConnectSP.s == IPS_OK);
 }
 
@@ -1605,4 +1796,5 @@
     ConnectSP.s = IPS_IDLE;
     IDSetSwitch(&ConnectSP, "The connection to the telescope is lost.");
+    IDLog("arret");
     return;
 }
@@ -1622,106 +1814,35 @@
 
 /**************************************************************************************
-**  Envoi d'une commande sur le socket puis attente de l'acknowledge
-***************************************************************************************/
-
-bool BAO::COMMANDE(int numsocket, char* Commande, char* Params)
-{
-    char chaine[MAXCARACTERES];
-
-    try
-    {
-        sprintf(chaine, "%s%s\n", Commande, Params);
-
-        Sockets[numsocket].new_sock << chaine;
-    }
-    catch (SocketException& e)
-    {
-        Sockets[numsocket].new_sock.shutdown();
-        Sockets[numsocket].new_sock.create();
-        Sockets[numsocket].Connected = Sockets[numsocket].new_sock.connect((std::string)Sockets[numsocket].IP);
-
-        if (Sockets[numsocket].Connected)
-        {
-            Sockets[numsocket].AttenteExecution=0;
-            Sockets[numsocket].AnomaliesExecution=0;
-        }
-
-        //  if (AntennesConnectees() == 0) { InitAntennes(); InitThreadOK=false;}
-
-        std::string oss;
-        oss="COMMANDE exception : " + e.description() + "\n";
-        size_t size = oss.size() + 1;
-        char* buffer = new char[size];
-        strncpy(buffer, oss.c_str(), size);
-
-        IDLog(buffer);
-
-        delete [] buffer;
-
-        return false;
-    }
-
-    return true;
-}
-
-
-/**************************************************************************************
-** Commande POSITION
-***************************************************************************************/
-
-bool BAO::POSITION(int numsocket)
-{
-    return COMMANDE(numsocket, (char*)"P", (char*)"");
-}
-
-/**************************************************************************************
-** Commande PARK
-***************************************************************************************/
-
-bool BAO::PARK(int numsocket)
-{
-    return COMMANDE(numsocket, (char*)"Z", (char*)"");
-}
-
-/**************************************************************************************
-** Commande ABORT
-***************************************************************************************/
-
-bool BAO::ABORT(int numsocket)
-{
-    return COMMANDE(numsocket, (char*)"A", (char*)"");
-}
-
-
-/**************************************************************************************
-** Commande GOTO
-***************************************************************************************/
-
-bool BAO::GOTO(int numsocket, int deltaAz, int deltaAlt)
-{
-    char Params[MAXCARACTERES];
-    char sensAz;
-    char sensAlt;
-
-    sensAlt='b';
-    sensAz='b';
-
-    if (deltaAz<0)
-    {
-        deltaAz=-deltaAz;
-        sensAz='f';
-    }
-
-    if (deltaAlt<0)
-    {
-        deltaAlt=-deltaAlt;
-        sensAlt='f';
-    }
-
-    sprintf(Params, "%c%04i%c%04i", sensAz, deltaAz, sensAlt, deltaAlt);
-
-    return COMMANDE(numsocket, (char*)"G", Params);
-}
-
-
-
+** GÃšre les erreurs de communication avec la boÃ®te Indi
+***************************************************************************************/
+/*
+void BAO::handle_error(INumberVectorProperty *nvp, int err, const char *msg)
+{
+    nvp->s = IPS_ALERT;
+
+    // If the error is a time out, then the device doesn't support this property
+    if (err == -2)
+    {
+        nvp->s = IPS_ALERT;
+        IDSetNumber(nvp, "Device timed out. Current device may be busy or does not support %s. Will retry again.", msg);
+    }
+    else
+        // Changing property failed, user should retry.
+        IDSetNumber( nvp , "%s failed.", msg);
+
+    fault = true;
+}*/
+
+
+/**************************************************************************************
+**
+***************************************************************************************/
+/*
+void BAO::correct_fault()
+{
+    fault = false;
+    IDMessage(mydev, "Telescope is online.");
+}*/
+
+
+
Index: /BAORadio/libindi/libindi/drivers/telescope/BAO.h
===================================================================
--- /BAORadio/libindi/libindi/drivers/telescope/BAO.h	(revision 503)
+++ /BAORadio/libindi/libindi/drivers/telescope/BAO.h	(revision 504)
@@ -1,20 +1,6 @@
 /*
-    LX200 Basic Driver
-    Copyright (C) 2005 Jasem Mutlaq (mutlaqja@ikarustech.com)
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License as published by the Free Software Foundation; either
-    version 2.1 of the License, or (at your option) any later version.
-
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-
+ Pilote Indi BAORadio
+ franckrichard033@gmail.com
+ Juin 2011
 */
 
@@ -22,4 +8,23 @@
 #define BAO_H
 
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <math.h>
+#include <unistd.h>
+#include <time.h>
+#include <memory>
+#include <pthread.h>
+#include <iostream>
+#include <time.h>
+#include <unistd.h>
+#include <sys/time.h>
+
+#include <config.h>
+
+#include "indicom.h"
+
+#include "Socket.h"
 #include "indidevapi.h"
 #include "indicom.h"
@@ -28,45 +33,48 @@
 #include "astro.h"
 
+
 #define MAXCARACTERES 1024
 
-#define MAXATTENTE 80                //Si une commande ne recoit pas d'acknowledge. Alors refaire 80 tentatives en renvoyant la commande
-#define MAXANOMALIES 2               //Si pas de rÃ©ponse au bout de 80 tentatives -> erreur critique -> socket perdu ?
+#define MAXATTENTE 80                // Si une commande ne recoit pas d'acknowledge. Alors refaire 80 tentatives en renvoyant la commande
+#define MAXANOMALIES 2               // Si pas de rÃ©ponse au bout de 80 tentatives -> erreur critique -> socket perdu ?
 #define MAXANOMALIESGOTO 1500
+
+#define NBREPASCODEURSAZ  4000
+   
+
+using namespace std;
 
 struct Position
 {
-    int x;
-    int y;
+    long int x;
+    long int y;
 };
 
 struct DefSocket
 {
-    ServerSocket new_sock;
-    
-    std::string IP;              //IP de l'antenne
-    
-    bool Connected;              //le micro-contrÃŽleur est-il connectÃ© ?
-    bool PosValides;             //le micro-contrÃŽleur a-t-il donnÃ© une position valide ?
-    char status;                 //status='B' pour busy  'R' pour READY
-    int sendalertes;             //une requÃªte "send" a gÃ©nÃ©rÃ© une erreur sur le rÃ©seau
-    int AttenteExecution;	 //L'antenne parvient-elle Ã  executer un cycle de commandes ?
-    int AnomaliesExecution;	 //Erreur critique. L'antenne ne rÃ©pond plus !
-                    
-    Position Pos;                //derniÃšre position retournÃ©e par le microcontrÃŽleur    
-    int etape;
-    
-    bool ack_status;             //Etat des acknowledges ?
-    bool ack_pos;
-    bool ack_park;
-    bool ack_abort;
-    bool ack_goto;
-    bool GotoOk;                 //Est-ce que le dernier goto est OK ?
+    ServerSocket new_sock;           // socket permettant de gÃ©rer la connexion avec une antennes
+
+    string IP;                       // IP de l'antenne
+
+    bool Connected;                  // le micro-contrÃŽleur est-il connectÃ© ?
+    bool PosValides;                 // le micro-contrÃŽleur a-t-il donnÃ© une position des moteurs valide ?
+    char status;                     // status='B' pour busy  'R' pour READY
+    int sendalertes;                 // une requÃªte 'send' a gÃ©nÃ©rÃ© une erreur sur le rÃ©seau
+    int AttenteExecution;	     // L'antenne parvient-elle Ã  executer un cycle de commandes ?
+    int AnomaliesExecution;	     // Erreur critique. L'antenne ne rÃ©pond plus !
+
+    Position Pos;                    // derniÃšre position retournÃ©e par le microcontrÃŽleur
+    int etape;                       //Ã©tape dans le cycle de commandes/rÃ©ponses entre PC et microcontroleurs
+
+    bool ack_status;                 // Etat des acknowledges ?
+    bool ack_pos;                    // le PC a reÃ§u une confirmation du microcont aprÃšs un ordre POSITION
+    bool ack_park;	             // le PC a reÃ§u une confirmation du microcont aprÃšs un ordre PARK
+    bool ack_abort;                  // le PC a reÃ§u une confirmation du microcont aprÃšs un ordre ABORT
+    bool ack_goto;                   // le PC a reÃ§u une confirmation du microcont aprÃšs un ordre GOTO
+    bool GotoOk;                     // Est-ce que le dernier goto est OK ?
 };
 
-ServerSocket server( 8000 );
-int SocketsNumber;
-bool InitThreadOK;
-DefSocket Sockets[MAXHOSTNAME + 1];
-pthread_t th1;
+
+ServerSocket server( 8000 );         // Le PC et les antennes communiquent par le biais du port 8000 sur le rÃ©seau tcp
 
 class BAO : public Astro
@@ -75,5 +83,5 @@
     BAO();
     ~BAO();
-    
+
     void ISGetProperties (const char *dev);
     void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n);
@@ -81,12 +89,14 @@
     void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n);
     void ISPoll ();
-    void InitThread();
- 
+
+    void *pThreadSocket ();
+    void *pThreadExit ();
+
     bool COMMANDE(int numsocket, char* Commande, char* Params);
-    Position ExtractPosition(std::string str);
-  
+    bool ExtractPosition(string str, Position *result);
+
     void connection_lost();
     void connection_resumed();
-    
+
     bool STATUS(int numsocket);
     bool POSITION(int numsocket);
@@ -96,8 +106,36 @@
     void ADDEC2Motor(double newRA, double newDEC);
     int  AntennesConnectees();
+    void DeconnecterSocket(int num);
     void InitAntennes();
-    
-        
-    
+
+    /*******************************************************/
+    /* Connection Routines
+    ********************************************************/
+    void init_properties();
+    void get_initial_data();
+    void connect_telescope();
+    bool is_connected(void);
+
+    /*******************************************************/
+    /* Misc routines
+    ********************************************************/
+    bool process_coords();
+    int get_switch_index(ISwitchVectorProperty *sp);
+
+    /*******************************************************/
+    /* Simulation Routines
+    ********************************************************/
+    void enable_simulation(bool enable);
+
+    /*******************************************************/
+    /* Error handling routines
+    ********************************************************/
+    void slew_error(int slewCode);
+    void reset_all_properties();
+    void handle_error(INumberVectorProperty *nvp, int err, const char *msg);
+    void correct_fault();
+
+
+
 private:
 
@@ -120,5 +158,5 @@
     INumber ActualisationN1[1];
     INumber ActualisationN2[1];
-    
+
     //INumber SlewAccuracyN[2];
     //INumber TrackAccuracyN[2];
@@ -138,5 +176,5 @@
     INumberVectorProperty ActualisationNP1;
     INumberVectorProperty ActualisationNP2;
-   
+
 
     /* Text Vectors */
@@ -144,54 +182,32 @@
     ITextVectorProperty ObjectTP;
 
-    /*******************************************************/
-    /* Connection Routines
-    ********************************************************/
-    void init_properties();
-    void get_initial_data();
-    void connect_telescope();
-    bool is_connected(void);
-
-    /*******************************************************/
-    /* Misc routines
-    ********************************************************/
-    bool process_coords();
-    int get_switch_index(ISwitchVectorProperty *sp);
-
-    /*******************************************************/
-    /* Simulation Routines
-    ********************************************************/
-    void enable_simulation(bool enable);
-
-    /*******************************************************/
-    /* Error handling routines
-    ********************************************************/
-    void slew_error(int slewCode);
-    void reset_all_properties();
-    void handle_error(INumberVectorProperty *nvp, int err, const char *msg);
-    void correct_fault();
+
 
 protected:
-
-    double JD;				/* Julian Date */
-    double lastRA;
+    int SocketsNumber;                   // nbre de sockets utilisÃ©s pour connecter les antennes
+    bool InitThreadOK;                   // Le thread est bien actif
+    DefSocket Sockets[MAXHOSTNAME + 1];  // Etat de chaque socket. Un socket permet la communication avec une antenne
+    pthread_t th1;                       // le pointeur du thread
+
+    double JD;				 // Jour julien
+    double lastRA;                       // Sauvegarde de la derniÃšre position avant actualisation
     double lastDEC;
-    double JJAnc;                       // Sauvegarde du jour julien de la derniÃšre actualisation de la position (fct Goto)
-    double ActualisationTM1;
+    double JJAnc;                        // Sauvegarde du jour julien lors de la derniÃšre actualisation de la position (fct Goto)
+    double ActualisationTM1;             // DÃ©lais entre deux actualisations dans les modes transit et tracking
     double ActualisationTM2;
-    bool   simulation;
-    bool   fault;
-    bool   LecturePosition;             // Ã©tape dans le processus d'actualisation de la position
-    bool   Abort;
-    bool   Park;
-    bool   Goto;
-    bool   BAOConnected;
-    bool   LastGotoOK;
-    
-    int    fd;				/* Telescope tty file descriptor */
-    int    currentSet;
-    int    lastSet; 
-    int    TrackingMode;                //1 : Transit           2: Tracking
-     
-    Position TargetPosition;            //Position Ã  atteindre en coordonnÃ©es Ã©quatoriales 
+    double Longitude;			 // Longitude et latitude du lieu d'observation
+    double Latitude;
+    bool   ActualisationPosition;        // Permet de faire les Ã©tapes nÃ©cessaires pour rÃ©aliser un mouvement
+    bool   Abort;			 // Annulation du mouvement en cours
+    bool   Park;			 // On place les antennes dans une position de repos
+    bool   Suivi;			 // Suivi d'un objet en cours...
+    bool   UpdateGoto;			 // On peut exÃ©cuter un Goto
+    bool   Exit;                         // On ferme le driver
+
+    int    currentSet;                   // Variable interne de l'interface indi
+    int    lastSet;                      // Variable interne de l'interface indi
+    int    TrackingMode;                 //1 : Transit           2: Tracking
+
+    Position TargetPosition;             //Position Ã  atteindre en coordonnÃ©es Ã©quatoriales
 };
 
Index: /BAORadio/libindi/libindi/drivers/telescope/astro.cpp
===================================================================
--- /BAORadio/libindi/libindi/drivers/telescope/astro.cpp	(revision 503)
+++ /BAORadio/libindi/libindi/drivers/telescope/astro.cpp	(revision 504)
@@ -1,26 +1,43 @@
+////////////////////////////////
+// Classe Astro               //
+// Franck RICHARD             //
+// franckrichard033@gmail.com //
+// BAORadio                   //
+// juin 2011                  //
+////////////////////////////////
+
+
 #include "astro.h"
 
-////////////////////
-// Routines Astro //
-////////////////////
+
+/**************************************************************************************
+** Constructeur de la classe Astro
+***************************************************************************************/
 
 Astro::Astro()
 {
-    Longitude=0.0;
-    Latitude=0.0;
-    Lst=0.0;
-    JJ=0.0;
-    CorP=0.0;
-    CorEP=0.0;
-    Annee=0.0;
-    Mois=0.0;
-    Jour=0.0;
-    Heu=0.0;
-    Min=0.0;
-    Sec=0.0;
-    ep=0.0;
-    hs=0.0;
-    UTCP=0.0;
-    tsl=0.0;
+    //Initialisation des variables
+    
+    Longitude = 0.0;                     // CordonnÃ©es du lieu d'observation
+    Latitude  = 0.0;
+    
+    Annee     = 0.0;                     // Date et heure de l'observation
+    Mois      = 0.0;
+    Jour      = 0.0;
+    Heure     = 0.0;
+    Min       = 0.0;
+    Sec       = 0.0;
+    UTCP      = 0.0;			 // permet de gÃ©rer le fuseau horaire
+                                         // mais semble inutile sous Linux
+    
+    hs        = 0.0;                     // fraction du jour en cours hs=(heure+min/60+secs/3600)/24.
+    ep        = 0.0;                     // obliquitÃ© de l'Ã©cliptique
+    tsl       = 0.0;                     // temps sidÃ©ral local
+    JJ        = 0.0;                     // Jour Julien
+    
+    CorP      = 0.0;                     // Nutation en longitude 
+    CorEP     = 0.0; 			 // Nutation en inclinaison
+     
+    LongitudeSoleil = 0.0;
 }
 
@@ -30,5 +47,37 @@
 
 
-//0<=Angle<=2*PI
+/**************************************************************************************
+** Initialisation des variables globales de la classe Astro
+***************************************************************************************/
+
+void Astro::DefinirDateHeure(double A, double M, double J, double H, double Mi, double S)
+{
+    Annee = A;
+    Mois = M;
+    Jour = J;
+    Heure = H;
+    Min = Mi;
+    Sec = S;
+}
+
+void Astro::DefinirPressionTemp(double P, double T)
+{
+    Pression = P;
+    Temp = T;
+}
+
+void Astro::DefinirLongitudeLatitude(double log, double lat)
+{
+    Longitude = log;
+    Latitude = lat;
+}
+
+
+
+/**************************************************************************************
+** ParamÃštre : angle en radians
+** retourne angle dans un intervalle 0 <= Angle <= 2*PI
+***************************************************************************************/
+
 double Astro::VerifAngle(double Angle)
 {
@@ -40,64 +89,284 @@
 
 
-//////////////////////////////////////////////////////////////////////
-//Nutation
+
+/**************************************************************************************
+** retourne l'arrondi du nombre donnÃ© en paramÃštre
+** Exemples: Arrondi(5.7) =  6
+**           Arrondi(-5.7)= -6
+***************************************************************************************/
+
+double Astro::Arrondi(double a)
+{
+    double b;
+
+    if (a>=0.0)
+    {
+        b=a-floor(a);
+        if (b>=0.5) return ceil(a);
+        else return floor(a);
+    }
+    else
+    {
+        b=ceil(a)-a;
+        if (b>=0.5) return floor(a);
+        else return ceil(a);
+    }
+}
+
+
+
+/**************************************************************************************
+** converti un angle (exprimÃ© en degrÃ©s) dans le format hh:mm:ss ou deg:mm:ss
+** selon la valeur de HMS
+***************************************************************************************/
+
+string Astro::DHMS(double mema, bool HMS)
+{
+    double d, m, s, a;
+
+    a=mema;
+
+    if (HMS) a=a / 15.0;
+    a=fabs(a * 3600.0);
+    s=Arrondi(fmod(a, 60.0) * 10.0) / 10.0;
+    a=floor(a / 60.0);
+    m=fmod(a, 60.0);
+    d=floor(a / 60.0);
+
+    if (s == 60.0)
+    {
+        s=0.0;
+        m+=1.0;
+        if (m==60.0)
+        {
+            m=0.0;
+            d+=1.0;
+
+            if (HMS && d>23.0) d=0.0;
+        }
+    }
+
+    stringstream strsTemp;
+
+    if (mema < 0) strsTemp << '-';
+
+    strsTemp << setfill('0') << setw(2) << d << ":" << m << ":" << s;
+
+    return (strsTemp.str());
+}
+
+
+/**************************************************************************************
+** Calcul de la longitude du Soleil
+** La quantitÃ© PS n'est pas indispensable. Elle permet d'amÃ©liorer la prÃ©cision
+***************************************************************************************/
+
+double Astro::CalculLongitudeSoleil()
+{
+    double T = (JJ - 2415020.0) / 36525.0;
+
+    double A = 153.23 + 22518.7541 * T;
+    double B = 216.57 + 44037.5082 * T;
+    double C = 312.69 + 32964.3577 * T;
+    double D = 350.74 + ( 445267.1142 - 0.00144 * T ) * T;
+    double E = 231.19 + 20.2 * T;
+
+
+    double L = 279.69668 + ( 36000.76892 + 0.0003025 * T ) * T;
+    double M = 358.47583 + (((( -0.0000033 * T) -0.00015 )  * T ) + 35999.04975 ) * T;
+
+    double CC =   (1.919460 + ((-0.000014 * T) - 0.004789 ) * T ) * sin(M * Pidiv180)
+                  + (0.020094 - 0.0001 * T) * sin(2.0 * M * Pidiv180)
+                  + 0.000293 * sin(3.0 * M * Pidiv180);
+
+    double PS =  0.00134 * cos(A * Pidiv180)
+                +0.00154 * cos(B * Pidiv180)
+                +0.00200 * cos(C * Pidiv180)
+                +0.00179 * sin(D * Pidiv180)
+                +0.00178 * sin(E * Pidiv180);
+
+
+    double LS = VerifAngle( (L + CC + PS) * Pidiv180);
+    
+    return LS;
+}
+
+
+
+/**************************************************************************************
+** Calcul de l'AD et la dÃ©clinaison du Soleil
+** indispensable pour exÃ©cuter la commande "goto sun"
+***************************************************************************************/
+
+void Astro::CalculARDecSoleil(Coordonnees *Soleil)
+{
+    double ar;
+    double de;
+    
+    ar = atan( cos(ep) * sin(LongitudeSoleil) / cos(LongitudeSoleil));
+    
+    if ( cos(LongitudeSoleil) < 0.0) ar += Pi;
+    
+    de = asin( sin(ep) * sin(LongitudeSoleil));
+
+    Soleil->ar = DHMS( VerifAngle(ar) * N180divPi, true );
+    
+    Soleil->dec = DHMS( de * N180divPi, false );
+}
+    
+
+
+
+/**************************************************************************************
+** Calcul de la nutation en longitude et en inclinaison
+** NÃ©cessaire pour calculer la position apparente d'un objet (Ã©toile, galaxie etc...)
+***************************************************************************************/
 
 void Astro::Nutation()
 {
-    double T,L,LP,M,MP,O,L2,LP2,O2;
-
-    T=(JJ-2415020.0)/36525.0;
-
-    L=(279.6967+(36000.7689+0.000303*T)*T)*Pidiv180;
-    LP=(270.4342+(481267.8831-0.001133*T)*T)*Pidiv180;
-    M=(358.4758+(35999.0498-0.000150*T)*T)*Pidiv180;
-    MP=(296.1046+(477198.8491+0.009192*T)*T)*Pidiv180;
-    O=(259.1833+(-1934.1420+0.002078*T)*T)*Pidiv180;
-
-    L2=2.0*L;
-    LP2=2.0*LP;
-    O2=2.0*O;
-
-    CorP=-(17.2327+0.01737*T)*sin(O)
-         -(1.2729+0.00013*T)*sin(L2)
-         +0.2088*sin(O2)
-         -0.2037*sin(LP2)
-         +(0.1261-0.00031*T)*sin(M)
-         +0.0675*sin(MP)
-         -(0.0497-0.00012*T)*sin(L2+M)
-         -0.0342*sin(LP2-O)
-         -0.0261*sin(LP2+MP)
-         +0.0214*sin(L2-M)
-         -0.0149*sin(L2-LP2+MP)
-         +0.0124*sin(L2-O)
-         +0.0114*sin(LP2-MP);
-
-    CorEP=(9.2100+0.00091*T)*cos(O)
-          +(0.5522-0.00029*T)*cos(L2)
-          -0.0904*cos(O2)
-          +0.0884*cos(LP2)
-          +0.0216*cos(L2+M)
-          +0.0183*cos(LP2-O)
-          +0.0113*cos(LP2+MP)
-          -0.0093*cos(L2-M)
-          -0.0066*cos(L2-O);
-
-    CorP=CorP/3600.0*Pidiv180;
-    CorEP=CorEP/3600.0*Pidiv180;
-}
-
-
-//////////////////////////////////////////////////////////////////////
-// calcul Jour julien
+    double T = (JJ-2415020.0) / 36525.0;
+
+    double L  = (279.6967 + (36000.7689 + 0.000303 * T ) * T ) * Pidiv180;
+    double LP = (270.4342 + (481267.8831 - 0.001133 * T ) * T ) * Pidiv180;
+    double M  = (358.4758 + (35999.0498 - 0.000150 * T ) * T ) * Pidiv180;
+    double MP = (296.1046 + (477198.8491 + 0.009192 * T ) * T ) * Pidiv180;
+    double O  = (259.1833 + (-1934.1420 + 0.002078 * T ) * T ) * Pidiv180;
+
+    double L2  = 2.0 * L;
+    double LP2 = 2.0 * LP;
+    double O2  = 2.0 * O;
+    
+    // Nutation en longitude
+
+    CorP = -(17.2327 + 0.01737 * T) * sin(O)
+           -(1.2729+0.00013 * T) * sin(L2)
+           +0.2088 * sin(O2)
+           -0.2037 * sin(LP2)
+           +(0.1261 - 0.00031 * T) * sin(M)
+           +0.0675 * sin(MP)
+           -(0.0497 - 0.00012 * T) * sin(L2 + M)
+           -0.0342 * sin(LP2 - O)
+           -0.0261 * sin(LP2 + MP)
+           +0.0214 * sin(L2 - M)
+           -0.0149 * sin(L2 - LP2 + MP)
+           +0.0124 * sin(L2 - O)
+           +0.0114 * sin(LP2 - MP);
+	   
+    //Nutation en inclinaison
+
+    CorEP = (9.2100 + 0.00091 * T) * cos(O)
+            +(0.5522 - 0.00029 * T) * cos(L2)
+            -0.0904 * cos(O2)
+            +0.0884 * cos(LP2)
+            +0.0216 * cos(L2+M)
+            +0.0183 * cos(LP2-O)
+            +0.0113 * cos(LP2+MP)
+            -0.0093 * cos(L2-M)
+            -0.0066 * cos(L2-O);
+
+    CorP  = CorP / 3600.0 * Pidiv180;
+    CorEP = CorEP / 3600.0 * Pidiv180;
+}
+
+
+
+/**************************************************************************************
+** Nutation des Ã©toiles - on utilise les quantitÃ©s calculÃ©es prÃ©cÃ©demment
+** ar et de sont exprimÃ©s en radians
+***************************************************************************************/
+
+void Astro::NutationEtoile(double *ar, double *de)
+{
+    double a = (cos(ep) + sin(ep) * sin(*ar) * tan(*de)) * CorP - (cos(*ar) * tan(*de)) * CorEP;
+    double b = (sin(ep) * cos(*ar)) * CorP + sin(*ar) * CorEP;
+
+    *ar = VerifAngle(*ar+a);
+    *de += b;
+}
+
+
+/**************************************************************************************
+** PrÃ©cession des Ã©quinoxes
+** ar et de sont exprimÃ©s en radians
+***************************************************************************************/
+
+void Astro::Precession(double *ar, double *de)
+{
+    double t = (JJ - 2451544.5) / 36524.2199;
+
+    double ze = ((((0.018 * t) + 0.302) * t + 2304.948) * t) / 3600.0 * Pidiv180;
+    double z = ((((0.019 * t) + 1.093) * t + 2304.948) * t) / 3600.0 * Pidiv180;
+    double delta = ((((-0.042 * t) - 0.426) * t + 2004.255) * t) / 3600.0 * Pidiv180;
+
+
+    double A = cos(*de) * sin(*ar + ze);
+    double B = cos(delta) * cos(*de) * cos (*ar + ze) - sin(delta) * sin(*de);
+    double C = sin(delta) * cos(*de) * cos (*ar + ze) + cos(delta) * sin(*de);
+
+    double AMZ = atan(A / B);
+
+    if (B<0.0) AMZ += Pi;
+
+    *ar=VerifAngle(AMZ + z);
+    *de=asin(C);
+}
+
+
+
+/**************************************************************************************
+** ObliquitÃ©
+** calcul de l'inclinaison de l'axe terrestre par rapport Ã  au plan de l'Ã©cliptique
+** QuantitÃ© indispensable pour calculer le temps sidÃ©ral local et les coordonnÃ©es
+** horaires du soleil
+***************************************************************************************/
+
+void Astro::Obliquite(double JJ)
+{
+    double T;
+
+    T = (JJ - 2415020.0) / 36525.0;
+
+    ep = (23.452294+ (((0.000000503 * T ) - 0.00000164 ) * T - 0.0130125 ) * T ) * Pidiv180;
+}
+
+
+
+
+/**************************************************************************************
+** Aberration annuelle des Ã©toiles
+** ar et de sont exprimÃ©s en radians
+***************************************************************************************/
+
+void Astro::AberrationAnnuelle(double *ar, double *de)
+{
+    double c = -20.49 / 3600.0 * Pidiv180;
+    double a = c * ( cos(*ar) * cos(LongitudeSoleil) * cos(ep)
+                     + sin(*ar) * sin(LongitudeSoleil)
+                   ) / cos(*de);
+
+    double b = c * ( cos(LongitudeSoleil) * cos(ep) * (tan(ep) * cos(*de) - sin(*ar) * sin(*de))
+                     + cos(*ar) * sin(*de) * sin(LongitudeSoleil));
+
+    *ar = VerifAngle(*ar + a);
+    *de += b;
+}
+
+
+/**************************************************************************************
+** calcul Jour julien
+***************************************************************************************/
 
 void Astro::CalculJJ(double Heure)
 {
-
+    JJ = CalculJJ(Annee, Mois, Jour, Heure);    
+}
+
+double Astro::CalculJJ(double A, double M, double J, double Heure)
+{
     long y, a, b, c, e, m;
 
-    long year = (long)Annee;
-    int month = (int)Mois;
-    double day = Jour + Heure;
-
+    long year = (long)A;
+    int month = (int)M;
+    double day = J + Heure;
 
     y = year + 4800;
@@ -131,36 +400,25 @@
 
 gregor:
-        b = (a/4) - a;
+        b = (a / 4) - a;
     }
 
-    c = (36525L * y)/100;
-
-    JJ = b + c + e + day - 32167.5;
-}
-
-
-///////////////////////////////////////////////////////////////////////
-//ObliquitÃ©
-
-void Astro::Obliquite(double JJ)
-{
-    double T;
-
-    T = (JJ-2415020.0) / 36525.0;
-
-    ep = (23.452294+ (((0.000000503 * T ) - 0.00000164 ) * T - 0.0130125 ) * T ) * Pidiv180;
-}
-
-///////////////////////////////////////////////////////////////////////
-//Temps sidÃ©ral local
+    c = (36525L * y) / 100;
+    
+    return b + c + e + day - 32167.5;
+}
+
+
+
+/**************************************************************************************
+** Temps sidÃ©ral local
+***************************************************************************************/
 
 double Astro::TSL(double JJ, double HeureSiderale, double Longitude)
 {
-    double rd,T;
-
-    T = (JJ - 2415020.0 ) / 36525.0;
-    rd = 0.276919398 + ( 100.0021359 + 0.000001075 * T ) * T;
+    double T = (JJ - 2415020.0 ) / 36525.0;
+    double rd = 0.276919398 + ( 100.0021359 + 0.000001075 * T ) * T;
     rd += HeureSiderale;
     rd *= Pi2;
+    // temps sidÃ©ral apparent
     rd += CorP * cos(ep);
     rd -= Longitude;
@@ -170,9 +428,13 @@
 
 
+/**************************************************************************************
+** routine principale des calculs
+***************************************************************************************/
+
 void Astro::CalculTSL()
 {
-    hs=(Heu+Min/60.0+Sec/3600.0)/24.0;
-
-    hs-=UTCP/24.0;
+    hs = (Heure + Min / 60.0 + Sec / 3600.0) / 24.0;
+
+    hs -= UTCP / 24.0;
 
     CalculJJ(hs);
@@ -182,29 +444,536 @@
     Nutation();
 
-    tsl=TSL(JJ, hs, Longitude);
-}
-
-
-///////////////////////////////////////////////////////////////////////
-//Azimut et hauteur Ã  partir de AR et Dec
-
-void Astro::Azimut(double ts, double Latitude, double Ar, double De, double *azi, double *hau)
-{
-    double ah, ht, a1, az, zc, ac;
-
-    ah=ts-Ar;
-
-    zc=sin(Latitude)*sin(De)+cos(Latitude)*cos(De)*cos(ah);
-    ht=atan(zc/sqrt((-zc*zc)+1.0));
-
-    a1=cos(De)*sin(ah)/cos(ht);
-    ac=(-cos(Latitude)*sin(De)+sin(Latitude)*cos(De)*cos(ah))/cos(ht);
-    az=atan(a1/sqrt((-a1*a1)+1.0));
+    tsl = TSL(JJ, hs, Longitude);
+
+    LongitudeSoleil = CalculLongitudeSoleil();
+}
+
+
+
+/**************************************************************************************
+** Calcule la hauteur et l'azimut des Ã©toiles en fct du lieu d'observation
+***************************************************************************************/
+
+void Astro::Azimut(double Ar, double De, double *azi, double *hau)
+{
+    double ah = tsl - Ar;
+
+    double zc = sin(Latitude) * sin(De) + cos(Latitude) * cos(De) * cos(ah);
+    double ht = atan(zc / sqrt((-zc * zc) + 1.0));
+
+    double a1 = cos(De) * sin(ah) / cos(ht);
+    double ac = (-cos(Latitude) * sin(De) + sin(Latitude) * cos(De) * cos(ah)) / cos(ht);
+    double az = atan(a1 / sqrt((-a1*a1)+1.0));
+
     if (ac<0.0) az=Pi-az;
 
-    az=VerifAngle(Pi+az);
-
-    *azi=az;
+    *azi=VerifAngle(Pi+az);
     *hau=ht;
 }
 
+
+/**************************************************************************************
+** rÃ©fraction atmosphÃ©rique : formule simple de Jean Meeus
+** la hauteur ht est exprimÃ©e en radians
+***************************************************************************************/
+
+double Astro::RefractionAtmospherique(double ht)
+{
+    double gamma, R0, a, b, PressionTempCalc, tanHT;
+
+    if (Pression!=0.0)
+    {
+        PressionTempCalc = (Pression / 1013.25) * 273.0 / (273.0 + Temp);
+
+        if (ht <= 15.0 * Pidiv180)
+        {
+            gamma = 2.6;
+            a = 7.5262;
+            b = -2.2204;
+
+            if (ht >= 4.0 * Pidiv180)
+            {
+                gamma=-1.1;
+                a=4.4010;
+                b=-0.9603;
+            }
+
+            R0 = (pow((a+b*log(ht*N180divPi+gamma)), 2.0)) / 60.0 * Pidiv180;
+            ht += R0 * PressionTempCalc;
+        }
+        else
+        {
+            tanHT = fabs(tan(Pidiv2 - ht));
+            R0 = (0.0161877777777777777777-0.000022888888888888888 * tanHT * tanHT)
+                 * tanHT * Pidiv180;
+            ht += R0 * PressionTempCalc;
+        }
+    }
+
+    return ht;
+}
+
+
+
+
+double Astro::slaDrange(double angle )
+{
+    return fmod(angle, Pi);
+}
+
+float  Astro::slaRange(float angle )
+{
+    return fmodf(angle, Pi);
+}
+
+void Astro::slaRefro ( double zobs, double hm, double tdk, double pmb,
+                       double rh, double wl, double phi, double tlr,
+                       double eps, double *ref )
+/*
+**  - - - - - - - - -
+**   s l a R e f r o
+**  - - - - - - - - -
+**
+**  Atmospheric refraction for radio and optical wavelengths.
+**
+**  Given:
+**    zobs    double  observed zenith distance of the source (radian)
+**    hm      double  height of the observer above sea level (metre)
+**    tdk     double  ambient temperature at the observer (deg K)
+**    pmb     double  pressure at the observer (millibar)
+**    rh      double  relative humidity at the observer (range 0-1)
+**    wl      double  effective wavelength of the source (micrometre)
+**    phi     double  latitude of the observer (radian, astronomical)
+**    tlr     double  temperature lapse rate in the troposphere (degK/met
+**    eps     double  precision required to terminate iteration (radian)
+**
+**  Returned:
+**    ref     double  refraction: in vacuo ZD minus observed ZD (radian)
+**
+**  Notes:
+**
+**  1  A suggested value for the tlr argument is 0.0065D0.  The
+**     refraction is significantly affected by tlr, and if studies
+**     of the local atmosphere have been carried out a better tlr
+**     value may be available.
+**
+**  2  A suggested value for the eps argument is 1e-8.  The result is
+**     usually at least two orders of magnitude more computationally
+**     precise than the supplied eps value.
+**
+**  3  The routine computes the refraction for zenith distances up
+**     to and a little beyond 90 deg using the method of Hohenkerk
+**     and Sinclair (NAO Technical Notes 59 and 63, subsequently adopted
+**     in the Explanatory Supplement, 1992 edition - see section 3.281).
+**
+**  4  The C code is an adaptation of the Fortran optical refraction
+**     subroutine AREF of C.Hohenkerk (HMNAO, September 1984), with
+**     extensions to support the radio case.  The following modifications
+**     to the original HMNAO optical refraction algorithm have been made:
+**
+**     .  The angle arguments have been changed to radians.
+**
+**     .  Any value of zobs is allowed (see note 6, below).
+**
+**     .  Other argument values have been limited to safe values.
+**
+**     .  Murray's values for the gas constants have been used
+**        (Vectorial Astrometry, Adam Hilger, 1983).
+**
+**     .  The numerical integration phase has been rearranged for
+**        extra clarity.
+**
+**     .  A better model for Ps(T) has been adopted (taken from
+**        Gill, Atmosphere-Ocean Dynamics, Academic Press, 1982).
+**
+**     .  More accurate expressions for Pwo have been adopted
+**        (again from Gill 1982).
+**
+**     .  Provision for radio wavelengths has been added using
+**        expressions devised by A.T.Sinclair, RGO (private
+**        communication 1989), based on the Essen & Froome
+**        refractivity formula adopted in Resolution 1 of the
+**        13th International Geodesy Association General Assembly
+**        (Bulletin Geodesique 1963 p390).
+**
+**     .  Various small changes have been made to gain speed.
+**
+**     None of the changes significantly affects the optical results
+**     with respect to the algorithm given in the 1992 Explanatory
+**     Supplement.  For example, at 70 deg zenith distance the present
+**     routine agrees with the ES algorithm to better than 0.05 arcsec
+**     for any reasonable combination of parameters.  However, the
+**     improved water-vapour expressions do make a significant difference
+**     in the radio band, at 70 deg zenith distance reaching almost
+**     4 arcsec for a hot, humid, low-altitude site during a period of
+**     low pressure.
+**
+**  5  The radio refraction is chosen by specifying wl > 100 micrometres.
+**     Because the algorithm takes no account of the ionosphere, the
+**     accuracy deteriorates at low frequencies, below about 30 MHz.
+**
+**  6  Before use, the value of zobs is expressed in the range +/- pi.
+**     If this ranged zobs is -ve, the result ref is computed from its
+**     absolute value before being made -ve to match.  In addition, if
+**     it has an absolute value greater than 93 deg, a fixed ref value
+**     equal to the result for zobs = 93 deg is returned, appropriately
+**     signed.
+**
+**  7  As in the original Hohenkerk and Sinclair algorithm, fixed values
+**     of the water vapour polytrope exponent, the height of the
+**     tropopause, and the height at which refraction is negligible are
+**     used.
+**
+**  8  The radio refraction has been tested against work done by
+**     Iain Coulson, JACH, (private communication 1995) for the
+**     James Clerk Maxwell Telescope, Mauna Kea.  For typical conditions,
+**     agreement at the 0.1 arcsec level is achieved for moderate ZD,
+**     worsening to perhaps 0.5-1.0 arcsec at ZD 80 deg.  At hot and
+**     humid sea-level sites the accuracy will not be as good.
+**
+**  9  It should be noted that the relative humidity rh is formally
+**     defined in terms of "mixing ratio" rather than pressures or
+**     densities as is often stated.  It is the mass of water per unit
+**     mass of dry air divided by that for saturated air at the same
+**     temperature and pressure (see Gill 1982).
+**
+**  Called:  slaDrange, atmt, atms
+**
+**  Defined in slamac.h:  TRUE, FALSE
+**
+**  Last revision:   30 January 1997
+**
+**  Copyright P.T.Wallace.  All rights reserved.
+*/
+{
+    /* Fixed parameters */
+
+    static double d93 = 1.623156204; /* 93 degrees in radians        */
+    static double gcr = 8314.32;     /* Universal gas constant       */
+    static double dmd = 28.9644;     /* Molecular weight of dry air  */
+    static double dmw = 18.0152;     /* Molecular weight of water
+                                                             vapour */
+    static double s = 6378120.0;     /* Mean Earth radius (metre)    */
+    static double delta = 18.36;     /* Exponent of temperature
+                                         dependence of water vapour
+                                                           pressure */
+    static double ht = 11000.0;      /* Height of tropopause (metre) */
+    static double hs = 80000.0;      /* Upper limit for refractive
+                                                    effects (metre) */
+
+    /* Variables used when calling the internal routine atmt */
+    double robs;   /* height of observer from centre of Earth (metre) */
+    double tdkok;  /* temperature at the observer (deg K) */
+    double alpha;  /* alpha          |        */
+    double gamm2;  /* gamma minus 2  | see ES */
+    double delm2;  /* delta minus 2  |        */
+    double c1,c2,c3,c4,c5,c6;  /* various */
+
+    /* Variables used when calling the internal routine atms */
+    double rt;     /* height of tropopause from centre of Earth (metre) */
+    double tt;     /* temperature at the tropopause (deg k) */
+    double dnt;    /* refractive index at the tropopause */
+    double gamal;  /* constant of the atmospheric model = g*md/r */
+
+    int is, k, n, i, j, optic;
+    double zobs1, zobs2, hmok, pmbok, rhok, wlok, tol, wlsq, gb,
+    a, gamma, tdc, psat, pwo, w, tempo, dn0, rdndr0, sk0,
+    f0, rdndrt, zt, ft, dnts, rdndrp, zts, fts, rs,
+    dns, rdndrs, zs, fs, refold, z0, zrange, fb, ff, fo,
+    fe, h, r, sz, rg, dr, tg, dn, rdndr, t, f, refp, reft;
+
+    /* The refraction integrand */
+#define refi(R,DN,RDNDR) ((RDNDR)/(DN+RDNDR));
+
+
+
+    /* Transform zobs into the normal range */
+    zobs1 = slaDrange ( zobs );
+    zobs2 = fabs ( zobs1 );
+    zobs2 = gmin ( zobs2, d93 );
+
+    /* Keep other arguments within safe bounds */
+    hmok = gmax ( hm, -1000.0 );
+    hmok = gmin ( hmok, 10000.0 );
+    tdkok = gmax ( tdk, 100.0 );
+    tdkok = gmin ( tdkok, 500.0 );
+    pmbok = gmax ( pmb, 0.0 );
+    pmbok = gmin ( pmbok, 10000.0 );
+    rhok  = gmax ( rh, 0.0 );
+    rhok  = gmin ( rhok, 1.0 );
+    wlok  = gmax ( wl, 0.1 );
+    alpha = fabs ( tlr );
+    alpha = gmax ( alpha, 0.001 );
+    alpha = gmin ( alpha, 0.01 );
+
+    /* Tolerance for iteration */
+    w = fabs ( eps );
+    tol = gmin ( w, 0.1 ) / 2.0;
+
+    /* Decide whether optical or radio case - switch at 100 micron */
+    optic = ( wlok <= 100.0 );
+
+    /* Set up model atmosphere parameters defined at the observer */
+    wlsq = wlok * wlok;
+    gb = 9.784 * ( 1.0 - 0.0026 * cos ( 2.0 * phi ) - 2.8e-7 * hmok );
+    a = ( optic ) ?
+        ( ( 287.604 + 1.6288 / wlsq + 0.0136 / ( wlsq * wlsq ) )
+          * 273.15 / 1013.25 ) * 1e-6
+        :
+        77.624e-6;
+    gamal = gb * dmd / gcr;
+    gamma = gamal / alpha;
+    gamm2 = gamma - 2.0;
+    delm2 = delta - 2.0;
+    tdc = tdkok - 273.15;
+    psat = pow ( 10.0, ( 0.7859 + 0.03477 * tdc ) /
+                 ( 1.0 + 0.00412 * tdc ) ) *
+           ( 1.0 + pmbok * ( 4.5e-6 + 6e-10 * tdc * tdc ) );
+    pwo = ( pmbok > 0.0 ) ?
+          rhok * psat / ( 1.0 - ( 1.0 - rhok ) * psat / pmbok ) :
+          0.0;
+    w = pwo * ( 1.0 - dmw / dmd ) * gamma / ( delta - gamma );
+    c1 = a * ( pmbok + w ) / tdkok;
+    c2 = ( a * w + ( optic ? 11.2684e-6 : 12.92e-6 ) * pwo ) / tdkok;
+    c3 = ( gamma - 1.0 ) * alpha * c1 / tdkok;
+    c4 = ( delta - 1.0 ) * alpha * c2 / tdkok;
+    c5 = optic ? 0.0 : 371897e-6 * pwo / tdkok;
+    c6 = c5 * delm2 * alpha / ( tdkok * tdkok );
+
+    /* Conditions at the observer */
+    robs = s + hmok;
+    atmt ( robs, tdkok, alpha, gamm2, delm2, c1, c2, c3, c4, c5, c6, robs,
+           &tempo, &dn0, &rdndr0 );
+    sk0 = dn0 * robs * sin ( zobs2 );
+    f0 = refi ( robs, dn0, rdndr0 );
+
+    /* Conditions at the tropopause in the troposphere */
+    rt = s + ht;
+    atmt ( robs, tdkok, alpha, gamm2, delm2, c1, c2, c3, c4, c5, c6, rt,
+           &tt, &dnt, &rdndrt );
+    zt = asin ( sk0 / ( rt * dnt ) );
+    ft = refi ( rt, dnt, rdndrt );
+
+    /* Conditions at the tropopause in the stratosphere */
+    atms ( rt, tt, dnt, gamal, rt, &dnts, &rdndrp );
+    zts = asin ( sk0 / ( rt * dnts ) );
+    fts = refi ( rt, dnts, rdndrp );
+
+    /* At the stratosphere limit */
+    rs = s + hs;
+    atms ( rt, tt, dnt, gamal, rs, &dns, &rdndrs );
+    zs = asin ( sk0 / ( rs * dns ) );
+    fs = refi ( rs, dns, rdndrs );
+
+    /*
+    ** Integrate the refraction integral in two parts;  first in the
+    ** troposphere (k=1), then in the stratosphere (k=2).
+    */
+
+    /* Initialize previous refraction to ensure at least two iterations */
+    refold = 1e6;
+
+    /*
+    ** Start off with 8 strips for the troposphere integration, and then
+    ** use the final troposphere value for the stratosphere integration,
+    ** which tends to need more strips.
+    */
+    is = 8;
+
+    /* Troposphere then stratosphere */
+    for ( k = 1; k <= 2; k++ ) {
+
+        /* Start z, z range, and start and end values */
+        if ( k == 1 ) {
+            z0 = zobs2;
+            zrange = zt - z0;
+            fb = f0;
+            ff = ft;
+        } else {
+            z0 = zts;
+            zrange = zs - z0;
+            fb = fts;
+            ff = fs;
+        }
+
+        /* Sums of odd and even values */
+        fo = 0.0;
+        fe = 0.0;
+
+        /* First time through loop we have to do every point */
+        n = 1;
+
+        /* Start of iteration loop (terminates at specified precision) */
+        for ( ; ; ) {
+
+            /* Strip width */
+            h = zrange / (double) is;
+
+            /* Initialize distance from Earth centre for quadrature pass */
+            r = ( k == 1 ) ? robs : rt;
+
+            /* One pass (no need to compute evens after first time) */
+            for ( i = 1; i < is; i += n ) {
+
+                /* Sine of observed zenith distance */
+                sz = sin ( z0 + h * (double) i );
+
+                /* Find r (to nearest metre, maximum four iterations) */
+                if ( sz > 1e-20 ) {
+                    w = sk0 / sz;
+                    rg = r;
+                    j = 0;
+                    do {
+                        if ( k == 1 ) {
+                            atmt ( robs, tdkok, alpha, gamm2, delm2,
+                                   c1, c2, c3, c4, c5, c6, rg,
+                                   &tg, &dn, &rdndr );
+                        } else {
+                            atms ( rt, tt, dnt, gamal, rg, &dn, &rdndr );
+                        }
+                        dr = ( rg * dn - w ) / ( dn + rdndr );
+                        rg -= dr;
+                    } while ( fabs ( dr ) > 1.0 && j++ <= 4 );
+                    r = rg;
+                }
+
+                /* Find refractive index and integrand at r */
+                if ( k == 1 ) {
+                    atmt ( robs, tdkok, alpha, gamm2, delm2,
+                           c1, c2, c3, c4, c5, c6, r,
+                           &t, &dn, &rdndr );
+                } else {
+                    atms ( rt, tt, dnt, gamal, r, &dn, &rdndr );
+                }
+                f = refi ( r, dn, rdndr );
+
+                /* Accumulate odd and (first time only) even values */
+                if ( n == 1 && i % 2 == 0 ) {
+                    fe += f;
+                } else {
+                    fo += f;
+                }
+            }
+
+            /* Evaluate the integrand using Simpson's Rule */
+            refp = h * ( fb + 4.0 * fo + 2.0 * fe + ff ) / 3.0;
+
+            /* Has the required precision been reached? */
+            if ( fabs ( refp - refold ) > tol ) {
+
+                /* No: prepare for next iteration */
+                refold = refp;   /* Save current value for convergence test */
+                is += is;        /* Double the number of strips */
+                fe += fo;        /* Sum of all = sum of evens next time */
+                fo = 0.0;        /* Reset odds accumulator */
+                n = 2;           /* Skip even values next time */
+
+            } else {
+
+                /* Yes: save troposphere component and terminate loop */
+                if ( k == 1 ) reft = refp;
+                break;
+            }
+        }
+    }
+
+    /* Result */
+    *ref = reft + refp;
+    if ( zobs1 < 0.0 ) *ref = - ( *ref );
+
+    *ref+=Pidiv2-zobs1;
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Astro::atmt ( double robs, double tdkok, double alpha, double gamm2,
+                   double delm2, double c1, double c2, double c3,
+                   double c4, double c5, double c6, double r,
+                   double *t, double *dn, double *rdndr )
+/*
+**  - - - - -
+**   a t m t
+**  - - - - -
+**
+**  Internal routine used by slaRefro:
+**
+**    refractive index and derivative with respect to height for the
+**    troposphere.
+**
+**  Given:
+**    robs    double   height of observer from centre of the Earth (metre)
+**    tdkok   double   temperature at the observer (deg K)
+**    alpha   double   alpha          )
+**    gamm2   double   gamma minus 2  ) see ES
+**    delm2   double   delta minus 2  )
+**    c1      double   useful term  )
+**    c2      double   useful term  )
+**    c3      double   useful term  ) see source of
+**    c4      double   useful term  ) slaRefro main routine
+**    c5      double   useful term  )
+**    c6      double   useful term  )
+**    r       double   current distance from the centre of the Earth (metre)
+**
+**  Returned:
+**    *t      double   temperature at r (deg K)
+**    *dn     double   refractive index at r
+**    *rdndr  double   r * rate the refractive index is changing at r
+**
+**  This routine is derived from the ATMOSTRO routine (C.Hohenkerk,
+**  HMNAO), with enhancements specified by A.T.Sinclair (RGO) to
+**  handle the radio case.
+**
+**  Note that in the optical case c5 and c6 are zero.
+*/
+{
+    double w, tt0, tt0gm2, tt0dm2;
+
+    w = tdkok - alpha * ( r - robs );
+    w = gmin ( w, 320.0 );
+    w = gmax ( w, 200.0 );
+    tt0 = w / tdkok;
+    tt0gm2 = pow ( tt0, gamm2 );
+    tt0dm2 = pow ( tt0, delm2 );
+    *t = w;
+    *dn = 1.0 + ( c1 * tt0gm2 - ( c2 - c5 / w ) * tt0dm2 ) * tt0;
+    *rdndr = r * ( - c3 * tt0gm2 + ( c4 - c6 / tt0 ) * tt0dm2 );
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Astro::atms ( double rt, double tt, double dnt, double gamal, double r,
+                   double *dn, double *rdndr )
+/*
+**  - - - - -
+**   a t m s
+**  - - - - -
+**
+**  Internal routine used by slaRefro:
+**
+**   refractive index and derivative with respect to height for the
+**   stratosphere.
+**
+**  Given:
+**    rt      double   height of tropopause from centre of the Earth (metre)
+**    tt      double   temperature at the tropopause (deg k)
+**    dnt     double   refractive index at the tropopause
+**    gamal   double   constant of the atmospheric model = g*md/r
+**    r       double   current distance from the centre of the Earth (metre)
+**
+**  Returned:
+**    *dn     double   refractive index at r
+**    *rdndr  double   r * rate the refractive index is changing at r
+**
+**  This routine is derived from the ATMOSSTR routine (C.Hohenkerk, HMNAO).
+*/
+{
+    double b, w;
+
+    b = gamal / tt;
+    w = ( dnt - 1.0 ) * exp ( - b * ( r - rt ) );
+    *dn = 1.0 + w;
+    *rdndr = - r * b * w;
+}
+
+
+
Index: /BAORadio/libindi/libindi/drivers/telescope/astro.h
===================================================================
--- /BAORadio/libindi/libindi/drivers/telescope/astro.h	(revision 503)
+++ /BAORadio/libindi/libindi/drivers/telescope/astro.h	(revision 504)
@@ -1,5 +1,9 @@
-// Definition of the Astro class
-// Franck RICHARD
-// BAORadio
+////////////////////////////////
+// Classe Astro               //
+// Franck RICHARD             //
+// BAORadio                   //
+// franckrichard033@gmail.com //
+// juin 2011                  //
+////////////////////////////////
 
 #ifndef Astro_class
@@ -7,4 +11,11 @@
 
 #include "math.h"
+#include "stdio.h"
+#include <iostream>
+#include <string.h>
+#include <sstream>
+#include <iomanip>
+
+using namespace std;
 
 //////////////////////////////
@@ -18,6 +29,16 @@
 #define Pidiv2		1.57079632679489661923132169163
 
+#define gmax(A,B) ((A)>(B)?(A):(B))
 
-class Astro
+#define gmin(A,B) ((A)<(B)?(A):(B))
+
+
+struct Coordonnees
+{
+    string ar;				// CoordonnÃ©es horaires d'un objet
+    string dec;
+};
+
+class Astro 
 {
 public:
@@ -25,15 +46,50 @@
     ~Astro();
 
+    void   DefinirDateHeure(double Annee, double Mois, double Jour, double Heu, double Min, double Sec);
+    void   DefinirPressionTemp(double P, double T);
+    void   DefinirLongitudeLatitude(double log, double lat);
     double VerifAngle(double Angle);
-    void  Azimut(double ts, double Latitude, double Ar, double De, double *azi, double *hau);
-    void  CalculJJ(double Heure);
+    double Arrondi(double a);
+    string DHMS(double mema, bool HMS);
+    void   Azimut(double Ar, double De, double *azi, double *hau);
+    void   Precession(double *ar, double *de);
+    void   NutationEtoile(double *ar, double *de);
+    void   AberrationAnnuelle(double *ar, double *de);
+    void   CalculJJ(double Heure);
+    double CalculJJ(double A, double M, double J, double Heure);
+    void   CalculTSL();  
+    double RefractionAtmospherique(double ht);
+    double CalculLongitudeSoleil();
     double TSL(double JJ,double HeureSiderale,double Longitude);
-    void Nutation();
-    void Obliquite(double JJ);
-    void CalculTSL();
+    void   Nutation();
+    void   Obliquite(double JJ);
+    void   atms ( double rt, double tt, double dnt, double gamal, double r,
+                   double *dn, double *rdndr );
+    void   atmt ( double robs, double tdkok, double alpha, double gamm2,
+                   double delm2, double c1, double c2, double c3,
+                   double c4, double c5, double c6, double r,
+                   double *t, double *dn, double *rdndr );
+    void   slaRefro ( double zobs, double hm, double tdk, double pmb,
+                double rh, double wl, double phi, double tlr,
+                double eps, double *ref );
+    float  slaRange(float angle );
+    double slaDrange(double angle );
+    void   CalculARDecSoleil(Coordonnees *Soleil);
     
+    
+    double GetAnnee() { return Annee; }
+    double GetMois()  { return Mois;  }
+    double GetJour()  { return Jour;  }
+    double GetHeure() { return Heure; }
+    double GetMin()   { return Min;   }
+    double GetSec()   { return Sec;   }
+    double GetJJ()    { return JJ;    }  
+
+  
+    
+    
+private:
     double Longitude;
     double Latitude;
-    double Lst;
     double JJ;
     double CorP;
@@ -42,5 +98,5 @@
     double Mois;
     double Jour;
-    double Heu;
+    double Heure;
     double Min;
     double Sec;
@@ -49,4 +105,7 @@
     double UTCP;
     double tsl;
+    double LongitudeSoleil;
+    double Pression;
+    double Temp;
 };
 
Index: /BAORadio/libindi/libindi/drivers/telescope/lx200generic.cpp
===================================================================
--- /BAORadio/libindi/libindi/drivers/telescope/lx200generic.cpp	(revision 503)
+++ /BAORadio/libindi/libindi/drivers/telescope/lx200generic.cpp	(revision 504)
@@ -165,5 +165,4 @@
  Property: Movement (Arrow keys on handset). West/East
 *********************************************/
-
 static ISwitch MovementWES[]       = {{"MOTION_WEST", "West", ISS_OFF, 0, 0}, {"MOTION_EAST", "East", ISS_OFF, 0, 0}};
 ISwitchVectorProperty MovementWESP      = { mydev, "TELESCOPE_MOTION_WE", "West/East", MOTION_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, MovementWES, NARRAY(MovementWES), "", 0};
@@ -315,5 +314,4 @@
   strcpy(TimeTP.device , newName );
   strcpy(UTCOffsetNP.device , newName );
-
   strcpy(SDTimeNP.device , newName );
 
Index: /BAORadio/libindi/libindi/drivers/telescope/synscanmount.cpp
===================================================================
--- /BAORadio/libindi/libindi/drivers/telescope/synscanmount.cpp	(revision 504)
+++ /BAORadio/libindi/libindi/drivers/telescope/synscanmount.cpp	(revision 504)
@@ -0,0 +1,280 @@
+/*******************************************************************************
+  Copyright(c) 2010 Gerry Rozema. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published by the Free
+  Software Foundation; either version 2 of the License, or (at your option)
+  any later version.
+
+  This program is distributed in the hope that it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc., 59
+  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+  The full GNU General Public License is included in this distribution in the
+  file called LICENSE.
+*******************************************************************************/
+#include "synscanmount.h"
+#include "libs/indicom.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <math.h>
+#include <unistd.h>
+#include <time.h>
+#include <memory>
+
+#include <string.h>
+#include <sys/stat.h>
+
+// We declare an auto pointer to Synscan.
+std::auto_ptr<SynscanMount> synscan(0);
+
+void ISPoll(void *p);
+
+
+void ISInit()
+{
+   static int isInit =0;
+
+   if (isInit == 1)
+       return;
+
+    isInit = 1;
+    if(synscan.get() == 0) synscan.reset(new SynscanMount());
+    //IEAddTimer(POLLMS, ISPoll, NULL);
+
+}
+
+void ISGetProperties(const char *dev)
+{
+        ISInit();
+        synscan->ISGetProperties(dev);
+}
+
+void ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int num)
+{
+        ISInit();
+        synscan->ISNewSwitch(dev, name, states, names, num);
+}
+
+void ISNewText(	const char *dev, const char *name, char *texts[], char *names[], int num)
+{
+        ISInit();
+        synscan->ISNewText(dev, name, texts, names, num);
+}
+
+void ISNewNumber(const char *dev, const char *name, double values[], char *names[], int num)
+{
+        ISInit();
+        synscan->ISNewNumber(dev, name, values, names, num);
+}
+
+void ISNewBLOB (const char *dev, const char *name, int sizes[], int blobsizes[], char *blobs[], char *formats[], char *names[], int n)
+{
+  INDI_UNUSED(dev);
+  INDI_UNUSED(name);
+  INDI_UNUSED(sizes);
+  INDI_UNUSED(blobsizes);
+  INDI_UNUSED(blobs);
+  INDI_UNUSED(formats);
+  INDI_UNUSED(names);
+  INDI_UNUSED(n);
+}
+void ISSnoopDevice (XMLEle *root)
+{
+    INDI_UNUSED(root);
+}
+
+SynscanMount::SynscanMount()
+{
+    //ctor
+}
+
+SynscanMount::~SynscanMount()
+{
+    //dtor
+}
+
+const char * SynscanMount::getDefaultName()
+{
+    return "SynScan";
+}
+
+bool SynscanMount::initProperties()
+{
+    if (isDebug())
+        IDLog("Synscan::init_properties\n");
+
+    //setDeviceName("Synscan");
+    INDI::Telescope::initProperties();
+
+    return true;
+}
+void SynscanMount::ISGetProperties (const char *dev)
+{
+    if (isDebug())
+        IDLog("Enter SynscanMount::ISGetProperties %s\n",dev);
+
+    //  First we let our parent class do it's thing
+    INDI::Telescope::ISGetProperties(dev);
+
+    //  Now we add anything that's specific to this telescope
+    //  or we could just load from a skeleton file too
+    return;
+}
+
+bool SynscanMount::ReadScopeStatus()
+{
+    char str[20];
+    int bytesWritten, bytesRead;
+    int numread;
+    double ra,dec;
+    int n1,n2;
+
+    //IDLog("Read Status\n");
+    //tty_write(PortFD,(unsigned char *)"Ka",2, &bytesWritten);  //  test for an echo
+
+    tty_write(PortFD,"Ka",2, &bytesWritten);  //  test for an echo
+    tty_read(PortFD,str,2,2, &bytesRead);  //  Read 2 bytes of response
+    if(str[1] != '#')
+    {
+        //  this is not a correct echo
+        if (isDebug())
+            IDLog("ReadStatus Echo Fail\n");
+        IDMessage(deviceName(),"Mount Not Responding");
+        return false;
+    }
+
+    if(TrackState==SCOPE_SLEWING)
+    {
+        //  We have a slew in progress
+        //  lets see if it's complete
+        //  This only works for ra/dec goto commands
+        //  The goto complete flag doesn't trip for ALT/AZ commands
+        memset(str,0,3);
+        tty_write(PortFD,"L",1, &bytesWritten);
+        numread=tty_read(PortFD,str,2,3, &bytesRead);
+        if(str[0]!=48)
+        {
+            //  Nothing to do here
+        } else
+        {
+            if(TrackState==SCOPE_PARKING) TrackState=SCOPE_PARKED;
+            else TrackState=SCOPE_TRACKING;
+        }
+    }
+    if(TrackState==SCOPE_PARKING)
+    {
+        //  ok, lets try read where we are
+        //  and see if we have reached the park position
+        memset(str,0,20);
+        tty_write(PortFD,"Z",1, &bytesWritten);
+        numread=tty_read(PortFD,str,10,2, &bytesRead);
+        //IDLog("PARK READ %s\n",str);
+        if(strncmp((char *)str,"0000,4000",9)==0)
+        {
+            TrackState=SCOPE_PARKED;
+            ParkSV->s=IPS_OK;
+            IDSetSwitch(ParkSV,NULL);
+            IDMessage(deviceName(),"Telescope is Parked.");
+        }
+
+    }
+
+    memset(str,0,20);
+    tty_write(PortFD,"e",1, &bytesWritten);
+    numread=tty_read(PortFD,str,18,1, &bytesRead);
+    if (numread!=18)
+    {
+        IDLog("read status bytes didn't get a full read\n");
+        return false;
+    }
+    // bytes read is as expected
+    sscanf((char *)str,"%x",&n1);
+    sscanf((char *)&str[9],"%x",&n2);
+    ra=(double)n1/0x100000000*24.0;
+    dec=(double)n2/0x100000000*360.0;
+    NewRaDec(ra,dec);
+    return true;
+}
+
+bool SynscanMount::Goto(double ra,double dec)
+{
+    char str[20];
+    int n1,n2;
+    int numread, bytesWritten, bytesRead;
+
+    //  not fleshed in yet
+    tty_write(PortFD,"Ka",2, &bytesWritten);  //  test for an echo
+    tty_read(PortFD,str,2,2, &bytesRead);  //  Read 2 bytes of response
+    if(str[1] != '#') {
+        //  this is not a correct echo
+        //  so we are not talking to a mount properly
+        return false;
+    }
+    //  Ok, mount is alive and well
+    //  so, lets format up a goto command
+    n1=ra*0x1000000/24;
+    n2=dec*0x1000000/360;
+    n1=n1<<8;
+    n2=n2<<8;
+    sprintf((char *)str,"r%08X,%08X",n1,n2);
+    tty_write(PortFD,str,18, &bytesWritten);
+    TrackState=SCOPE_SLEWING;
+    numread=tty_read(PortFD,str,1,60, &bytesRead);
+    if (numread!=1||str[0]!='#')
+    {
+        if (isDebug())
+            IDLog("Timeout waiting for scope to complete slewing.");
+        return false;
+    }
+
+    return true;
+}
+
+bool SynscanMount::Park()
+{
+    char str[20];
+    int numread, bytesWritten, bytesRead;
+
+
+    memset(str,0,3);
+    tty_write(PortFD,"Ka",2, &bytesWritten);  //  test for an echo
+    tty_read(PortFD,str,2,2, &bytesRead);  //  Read 2 bytes of response
+    if(str[1] != '#')
+    {
+        //  this is not a correct echo
+        //  so we are not talking to a mount properly
+        return false;
+    }
+    //  Now we stop tracking
+    tty_write(PortFD,"T0",2, &bytesWritten);
+    numread=tty_read(PortFD,str,1,60, &bytesRead);
+    if (numread!=1||str[0]!='#')
+    {
+        if (isDebug())
+            IDLog("Timeout waiting for scope to stop tracking.");
+        return false;
+    }
+
+    //sprintf((char *)str,"b%08X,%08X",0x0,0x40000000);
+    tty_write(PortFD,"B0000,4000",10, &bytesWritten);
+    numread=tty_read(PortFD,str,1,60, &bytesRead);
+    if (numread!=1||str[0]!='#')
+    {
+        if (isDebug())
+            IDLog("Timeout waiting for scope to respond to park.");
+        return false;
+    }
+
+    TrackState=SCOPE_PARKING;
+    IDMessage(deviceName(),"Parking Telescope...");
+    return true;
+}
Index: /BAORadio/libindi/libindi/drivers/telescope/synscanmount.h
===================================================================
--- /BAORadio/libindi/libindi/drivers/telescope/synscanmount.h	(revision 504)
+++ /BAORadio/libindi/libindi/drivers/telescope/synscanmount.h	(revision 504)
@@ -0,0 +1,48 @@
+/*******************************************************************************
+  Copyright(c) 2010 Gerry Rozema. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published by the Free
+  Software Foundation; either version 2 of the License, or (at your option)
+  any later version.
+
+  This program is distributed in the hope that it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc., 59
+  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+  The full GNU General Public License is included in this distribution in the
+  file called LICENSE.
+*******************************************************************************/
+
+#ifndef SYNSCANMOUNT_H
+#define SYNSCANMOUNT_H
+
+#include "indibase/inditelescope.h"
+
+
+class SynscanMount : public INDI::Telescope
+{
+    protected:
+    private:
+    public:
+        SynscanMount();
+        virtual ~SynscanMount();
+
+        //  overrides of base class virtual functions
+        bool initProperties();
+        void ISGetProperties (const char *dev);
+        const char *getDefaultName();
+
+        bool ReadScopeStatus();
+        bool Goto(double,double);
+        bool Park();
+
+
+};
+
+#endif // SYNSCANMOUNT_H
Index: /BAORadio/libindi/libindi/drivers/telescope/telescope_simulator.cpp
===================================================================
--- /BAORadio/libindi/libindi/drivers/telescope/telescope_simulator.cpp	(revision 504)
+++ /BAORadio/libindi/libindi/drivers/telescope/telescope_simulator.cpp	(revision 504)
@@ -0,0 +1,241 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <time.h>
+
+#include "telescope_simulator.h"
+#include "indicom.h"
+
+// We declare an auto pointer to ScopeSim.
+std::auto_ptr<ScopeSim> telescope_sim(0);
+
+#define	SLEWRATE	1				/* slew rate, degrees/s */
+#define	POLLMS		250				/* poll period, ms */
+#define SIDRATE		0.004178			/* sidereal rate, degrees/s */
+
+
+void ISPoll(void *p);
+
+void ISInit()
+{
+   static int isInit =0;
+
+   if (isInit == 1)
+       return;
+
+    isInit = 1;
+    if(telescope_sim.get() == 0) telescope_sim.reset(new ScopeSim());
+    //IEAddTimer(POLLMS, ISPoll, NULL);
+
+}
+
+void ISGetProperties(const char *dev)
+{
+        ISInit();
+        telescope_sim->ISGetProperties(dev);
+}
+
+void ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int num)
+{
+        ISInit();
+        telescope_sim->ISNewSwitch(dev, name, states, names, num);
+}
+
+void ISNewText(	const char *dev, const char *name, char *texts[], char *names[], int num)
+{
+        ISInit();
+        telescope_sim->ISNewText(dev, name, texts, names, num);
+}
+
+void ISNewNumber(const char *dev, const char *name, double values[], char *names[], int num)
+{
+        ISInit();
+        telescope_sim->ISNewNumber(dev, name, values, names, num);
+}
+
+void ISNewBLOB (const char *dev, const char *name, int sizes[], int blobsizes[], char *blobs[], char *formats[], char *names[], int n)
+{
+  INDI_UNUSED(dev);
+  INDI_UNUSED(name);
+  INDI_UNUSED(sizes);
+  INDI_UNUSED(blobsizes);
+  INDI_UNUSED(blobs);
+  INDI_UNUSED(formats);
+  INDI_UNUSED(names);
+  INDI_UNUSED(n);
+}
+void ISSnoopDevice (XMLEle *root)
+{
+    INDI_UNUSED(root);
+}
+
+
+ScopeSim::ScopeSim()
+{
+    //ctor
+    currentRA=15;
+    currentDEC=15;
+    Parked=false;
+}
+
+ScopeSim::~ScopeSim()
+{
+    //dtor
+}
+
+const char * ScopeSim::getDefaultName()
+{
+    return (char *)"Telescope Simulator";
+}
+
+bool ScopeSim::Connect(char *)
+{
+    return true;
+}
+
+bool ScopeSim::Disconnect()
+{
+    return true;
+}
+
+bool ScopeSim::ReadScopeStatus()
+{
+    static struct timeval ltv;
+    struct timeval tv;
+    double dt, da, dx;
+    int nlocked;
+
+
+    /* update elapsed time since last poll, don't presume exactly POLLMS */
+    gettimeofday (&tv, NULL);
+
+    if (ltv.tv_sec == 0 && ltv.tv_usec == 0)
+        ltv = tv;
+
+    dt = tv.tv_sec - ltv.tv_sec + (tv.tv_usec - ltv.tv_usec)/1e6;
+    ltv = tv;
+    da = SLEWRATE*dt;
+
+    /* Process per current state. We check the state of EQUATORIAL_EOD_COORDS_REQUEST and act acoordingly */
+    switch (TrackState)
+    {
+    case SCOPE_SLEWING:
+    case SCOPE_PARKING:
+        /* slewing - nail it when both within one pulse @ SLEWRATE */
+        nlocked = 0;
+
+        dx = targetRA - currentRA;
+
+        if (fabs(dx) <= da)
+        {
+            currentRA = targetRA;
+            nlocked++;
+        }
+        else if (dx > 0)
+            currentRA += da/15.;
+        else
+            currentRA -= da/15.;
+
+
+        dx = targetDEC - currentDEC;
+        if (fabs(dx) <= da)
+        {
+            currentDEC = targetDEC;
+            nlocked++;
+        }
+        else if (dx > 0)
+          currentDEC += da;
+        else
+          currentDEC -= da;
+
+        if (nlocked == 2)
+        {
+            //eqNP.s = IPS_OK;
+            //eqNPR.s = IPS_OK;
+            //IDSetNumber(&eqNP, NULL);
+            //IDSetNumber(&eqNPR, "Now tracking");
+            if (TrackState == SCOPE_SLEWING)
+            {
+                TrackState = SCOPE_TRACKING;
+                IDMessage(deviceName(), "Telescope slew is complete. Tracking...");
+            }
+            else
+            {
+                TrackState = SCOPE_PARKED;
+                IDMessage(deviceName(), "Telescope parked successfully.");
+            }
+        }
+        //else
+          //  IDSetNumber(&eqNP, NULL);
+
+        break;
+
+    case SCOPE_TRACKING:
+        /* tracking */
+        /* RA moves at sidereal, Dec stands still */
+         currentRA += (SIDRATE*dt/15.);
+         break;
+
+    default:
+        break;
+    }
+
+    NewRaDec(currentRA, currentDEC);
+    return true;
+}
+
+bool ScopeSim::Goto(double r,double d)
+{
+    //IDLog("ScopeSim Goto\n");
+    targetRA=r;
+    targetDEC=d;
+    char RAStr[64], DecStr[64];
+
+    fs_sexa(RAStr, targetRA, 2, 3600);
+    fs_sexa(DecStr, targetDEC, 2, 3600);
+
+    Parked=false;
+    TrackState = SCOPE_SLEWING;
+    IDMessage(deviceName(), "Slewing to RA: %s - DEC: %s", RAStr, DecStr);
+    return true;
+}
+
+bool ScopeSim::Park()
+{
+    targetRA=0;
+    targetDEC=90;
+    Parked=true;
+    TrackState = SCOPE_PARKING;
+    IDMessage(deviceName(), "Parking telescope in progress...");
+    return true;
+}
+
+bool ScopeSim::Connect()
+{
+    //  Parent class is wanting a connection
+    //IDLog("INDI::Telescope calling connect with %s\n",PortT[0].text);
+    bool rc=false;
+
+    if(isConnected()) return true;
+
+    //IDLog("Calling Connect\n");
+
+    rc=Connect(PortT[0].text);
+
+    if(rc)
+        SetTimer(POLLMS);
+    return rc;
+}
+
+
+
+/* update the "mount" over time */
+void mountSim (void *p)
+{
+
+}
+
+
Index: /BAORadio/libindi/libindi/drivers/telescope/telescope_simulator.h
===================================================================
--- /BAORadio/libindi/libindi/drivers/telescope/telescope_simulator.h	(revision 504)
+++ /BAORadio/libindi/libindi/drivers/telescope/telescope_simulator.h	(revision 504)
@@ -0,0 +1,32 @@
+#ifndef SCOPESIM_H
+#define SCOPESIM_H
+
+#include "indibase/inditelescope.h"
+
+
+class ScopeSim : public INDI::Telescope
+{
+    protected:
+    private:
+        double currentRA;
+        double currentDEC;
+        double targetRA;
+        double targetDEC;
+
+        bool Parked;
+    public:
+        ScopeSim();
+        virtual ~ScopeSim();
+
+        virtual const char *getDefaultName();
+        virtual bool Connect();
+        virtual bool Connect(char *);
+        virtual bool Disconnect();
+        virtual bool ReadScopeStatus();
+
+        bool Goto(double,double);
+        bool Park();
+
+};
+
+#endif // SCOPESIM_H
Index: /BAORadio/libindi/libindi/examples/README
===================================================================
--- /BAORadio/libindi/libindi/examples/README	(revision 503)
+++ /BAORadio/libindi/libindi/examples/README	(revision 504)
@@ -16,7 +16,9 @@
 tutorial_one: We construct a most basic (and useless) device driver to illustate basic INDI structures.
 tutorial_two:  We create a simple simulator. We will use a few handy utility functions provided by INDI like timers, string <---> number conversion, and more.
-tutorial_three:  We create a simple device, and establish a data channel with the client to transmit a FITS file. 
+tutorial_three:  We create a simple CCD simulator, and establish a data channel with the client to transmit a FITS file. 
 
 tutorial_dome and tutorial_rain are part of the inter-driver communication tutorial. 
+
+tutorial_client: We create a simple client to set the temperature of a CCD simulator (tutorial_three).
 
 Usage
@@ -45,7 +47,22 @@
 where num is the tutorial number (tutorial_one, tutorial_two, or tutorial_three).
 
+------------------------------------------------------------------------------------------
+
 For the inter-driver communications tutorial, type instead:
 
 $ indiserver -v -p 8000 ./tutorial_dome ./tutorial_rain
+
+------------------------------------------------------------------------------------------
+
+For tutorial_client. Run tutorial_three first:
+
+$ indiserver -v ./tutorial_three
+
+Then open another console tab, and run the client:
+
+$ ./tutorial_client
+
+You can connect to tutorial_three via a GUI client (e.g. KStars) before running tutorial_client. This will enable you to watch 
+changes in the driver as they occur from tutorial_client. Make sure to set the port to 7624 in KStars.
 
 ------------------------------------------------------------------------------------------
Index: /BAORadio/libindi/libindi/examples/tutorial_client.cpp
===================================================================
--- /BAORadio/libindi/libindi/examples/tutorial_client.cpp	(revision 504)
+++ /BAORadio/libindi/libindi/examples/tutorial_client.cpp	(revision 504)
@@ -0,0 +1,169 @@
+#if 0
+    Simple Client Tutorial
+    Demonstration of libindi v0.7 capabilities.
+
+    Copyright (C) 2010 Jasem Mutlaq (mutlaqja@ikarustech.com)
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+#endif
+
+
+#include <string>
+#include <iostream>
+
+#include <string.h>
+#include <stdarg.h>
+#include <math.h>
+#include <unistd.h>
+#include <time.h>
+#include <memory>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <config.h>
+
+#include "indibase/baseclient.h"
+#include "indibase/basedriver.h"
+
+/* INDI Common Library Routines */
+#include "indicom.h"
+
+#include "tutorial_client.h"
+
+using namespace std;
+
+#define MYCCD "CCD Simulator"
+
+/* Our client auto pointer */
+auto_ptr<MyClient> camera_client(0);
+
+int main(int argc, char *argv[])
+{
+
+    if (camera_client.get() == 0)
+        camera_client.reset(new MyClient());
+
+
+  camera_client->setServer("localhost", 7624);
+
+  camera_client->watchDevice(MYCCD);
+
+  camera_client->connectServer();
+
+  cout << "Press any key to terminate the client.\n";
+  string term;
+  cin >> term;
+
+
+}
+
+
+/**************************************************************************************
+**
+***************************************************************************************/
+MyClient::MyClient()
+{
+    ccd_simulator = NULL;
+}
+
+/**************************************************************************************
+**
+***************************************************************************************/
+MyClient::~MyClient()
+{
+
+}
+
+/**************************************************************************************
+**
+***************************************************************************************/
+void MyClient::setTemperature()
+{
+   INumberVectorProperty *ccd_temperature = NULL;
+
+   ccd_temperature = ccd_simulator->getNumber("CCD_TEMPERATURE");
+
+   if (ccd_temperature == NULL)
+   {
+       IDLog("Error: unable to find CCD Simulator CCD_TEMPERATURE property...\n");
+       return;
+   }
+
+   ccd_temperature->np[0].value = -20;
+   sendNewNumber(ccd_temperature);
+}
+
+/**************************************************************************************
+**
+***************************************************************************************/
+void MyClient::newDevice(const char *device_name)
+{
+    if (!strcmp(device_name, "CCD Simulator"))
+    {
+        IDLog("Receiving CCD Simulator Device...\n");
+
+        ccd_simulator = getDriver(MYCCD);
+
+        if (ccd_simulator == NULL)
+        {
+            IDLog("Error: unable to find CCD Simulator device...\n");
+            return;
+        }
+    }
+}
+
+/**************************************************************************************
+**
+***************************************************************************************/
+void MyClient::newProperty(const char *device_name, const char *property_name)
+{
+     if (!strcmp(device_name, "CCD Simulator") && !strcmp(property_name, "CCD_TEMPERATURE"))
+     {
+             IDLog("CCD_TEMPERATURE standard property defined. Attempting connection to CCD...\n");
+             setDriverConnection(true, MYCCD);
+     }
+}
+
+/**************************************************************************************
+**
+***************************************************************************************/
+void MyClient::newSwitch(ISwitchVectorProperty *svp)
+{
+    // Let's check if we're ON
+    if (!strcmp(svp->name, "CONNECTION"))
+    {
+        if (svp->sp[0].s == ISS_ON)
+        {
+            IDLog("CCD is connected. Setting temperature to -20 C.\n");
+            setTemperature();
+        }
+    }
+}
+
+/**************************************************************************************
+**
+***************************************************************************************/
+void MyClient::newNumber(INumberVectorProperty *nvp)
+{
+    // Let's check if we get any new values for CCD_TEMPERATURE
+    if (!strcmp(nvp->name, "CCD_TEMPERATURE"))
+    {
+       IDLog("Receving new CCD Temperature: %g C\n", nvp->np[0].value);
+
+       if (nvp->np[0].value == -20)
+           IDLog("CCD temperature reached desired value!\n");
+   }
+}
Index: /BAORadio/libindi/libindi/examples/tutorial_client.h
===================================================================
--- /BAORadio/libindi/libindi/examples/tutorial_client.h	(revision 504)
+++ /BAORadio/libindi/libindi/examples/tutorial_client.h	(revision 504)
@@ -0,0 +1,54 @@
+/*
+    Tutorial Client
+    Copyright (C) 2010 Jasem Mutlaq (mutlaqja@ikarustech.com)
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+*/
+
+#ifndef TUTORIAL_CLIENT_H
+#define TUTORIAL_CLIENT_H
+
+#include "indidevapi.h"
+#include "indicom.h"
+#include "indibase/baseclient.h"
+
+class MyClient : public INDI::BaseClient
+{
+ public:
+
+    MyClient();
+    ~MyClient();
+
+    void setTemperature();
+
+protected:
+
+    virtual void newDevice(const char *device_name);
+    virtual void newProperty(const char *device_name, const char *property_name);
+    virtual void newBLOB(IBLOB *bp) {}
+    virtual void newSwitch(ISwitchVectorProperty *svp);
+    virtual void newNumber(INumberVectorProperty *nvp);
+    virtual void newText(ITextVectorProperty *tvp) {}
+    virtual void newLight(ILightVectorProperty *lvp) {}
+    virtual void serverConnected() {}
+    virtual void serverDisconnected() {}
+
+private:
+   INDI::BaseDriver * ccd_simulator;
+
+};
+
+#endif
Index: /BAORadio/libindi/libindi/examples/tutorial_four.cpp
===================================================================
--- /BAORadio/libindi/libindi/examples/tutorial_four.cpp	(revision 503)
+++ /BAORadio/libindi/libindi/examples/tutorial_four.cpp	(revision 504)
@@ -133,5 +133,5 @@
     IDLog("Initilizing from My Scope device...\n");
 
-    init_properties();
+    //init_properties();
 
  }
@@ -147,7 +147,8 @@
 /**************************************************************************************
 ** Initialize all properties & set default values.
-***************************************************************************************/
-void MyScope::init_properties()
-{
+**************************************************************************************/
+bool MyScope::initProperties()
+{
+    DefaultDriver::initProperties();
     // This is the default driver skeleton file location
     // Convention is: drivername_sk_xml
@@ -169,4 +170,6 @@
     addAuxControls();
 
+    return true;
+
 }
 
@@ -247,5 +250,5 @@
             return false;
 
-        // Are we update CONNECTION?
+        /* Are we update CONNECTION?
         if (!strcmp(svp->name, "CONNECTION"))
         {
@@ -253,40 +256,32 @@
             connect_telescope();
             return true;
-        }
-
-
-}
-
-
-/**************************************************************************************
-**
-***************************************************************************************/
-void MyScope::connect_telescope()
-{
-    ISwitchVectorProperty *svp = getSwitch("CONNECTION");
-
-    ISwitch *sp = IUFindOnSwitch(svp);
-
-    if (!sp)
-        return;
-
-    // Are we connecting?
-    if (!strcmp(sp->name, "CONNECT"))
-    {
-        // Make sure to call setConnected(true) before informing client about successful connection
-        setConnected(true);
-        IDSetSwitch(svp, "Connecting.... telescope is online.");
-        IDLog("Connecting.... telescope is online.\n");
-
-
-    }
-    // Are we disconnecting?
-    else
-    {
-        setConnected(false);
-        IDSetSwitch(svp, "Disconnecting... telescope is offline.");
-        IDLog("Disconnecting... telescope is offline.\n");
-    }
-}
-
-
+        }*/
+
+
+}
+
+
+/**************************************************************************************
+**
+***************************************************************************************/
+bool MyScope::Connect()
+{
+    return true;
+}
+
+bool MyScope::Disconnect()
+{
+    return true;
+}
+
+const char * MyScope::getDefaultName()
+{
+    return "My Scope";
+}
+
+
+
+
+
+
+
Index: /BAORadio/libindi/libindi/examples/tutorial_four.h
===================================================================
--- /BAORadio/libindi/libindi/examples/tutorial_four.h	(revision 503)
+++ /BAORadio/libindi/libindi/examples/tutorial_four.h	(revision 504)
@@ -38,6 +38,8 @@
 
 private:
- void init_properties();
- void connect_telescope();
+ const char *getDefaultName();
+ virtual bool initProperties();
+ virtual bool Connect();
+ virtual bool Disconnect();
 
 };
Index: /BAORadio/libindi/libindi/examples/tutorial_three.c
===================================================================
--- /BAORadio/libindi/libindi/examples/tutorial_three.c	(revision 503)
+++ /BAORadio/libindi/libindi/examples/tutorial_three.c	(revision 504)
@@ -66,7 +66,11 @@
 
 /* BLOB for sending image */
-static IBLOB imageB = {"CCD1", "Feed", "", 0, 0, 0, 0, 0, 0, 0};
-static IBLOBVectorProperty imageBP = {mydev, "Video", "Video", COMM_GROUP,
-  IP_RO, 0, IPS_IDLE, &imageB, 1, "", 0};
+static IBLOB imagePrimaryB = {"CCD1", "Primary", "", 0, 0, 0, 0, 0, 0, 0};
+static IBLOBVectorProperty imagePrimaryBP = {mydev, "CCD1", "", COMM_GROUP,
+  IP_RO, 0, IPS_IDLE, &imagePrimaryB, 1, "", 0};
+
+static IBLOB imageGuideB = {"CCD2", "Guide", "", 0, 0, 0, 0, 0, 0, 0};
+static IBLOBVectorProperty imageGuideBP = {mydev, "CCD2", "", COMM_GROUP,
+  IP_RO, 0, IPS_IDLE, &imageGuideB, 1, "", 0};
 
 void ISGetProperties (const char *dev)
@@ -80,5 +84,6 @@
   IDDefNumber(&ExposeTimeNP, NULL);
   IDDefNumber(&TemperatureNP, NULL);
-  IDDefBLOB(&imageBP, NULL);
+  IDDefBLOB(&imagePrimaryBP, NULL);
+  IDDefBLOB(&imageGuideBP, NULL);
 
   IEAddTimer(1000, ISPoll, NULL);
@@ -236,12 +241,27 @@
    
    /* #6 Send it */
-   imageB.blob = compressedData;
-   imageB.bloblen = compressedBytes;
-   imageB.size = totalBytes;
-   strcpy(imageB.format, ".fits.z");
+
+   if (!strcmp(filename, "ngc1316o.fits"))
+   {
+   imagePrimaryB.blob = compressedData;
+   imagePrimaryB.bloblen = compressedBytes;
+   imagePrimaryB.size = totalBytes;
+   strcpy(imagePrimaryB.format, ".fits.z");
 
    /* #7 Set BLOB state to Ok */
-   imageBP.s = IPS_OK;
-   IDSetBLOB (&imageBP, NULL);
+   imagePrimaryBP.s = IPS_OK;
+   IDSetBLOB (&imagePrimaryBP, NULL);
+   }
+   else
+   {
+       imageGuideB.blob = compressedData;
+       imageGuideB.bloblen = compressedBytes;
+       imageGuideB.size = totalBytes;
+       strcpy(imageGuideB.format, ".fits.z");
+
+       /* #7 Set BLOB state to Ok */
+       imageGuideBP.s = IPS_OK;
+       IDSetBLOB (&imageGuideBP, NULL);
+   }
 
    /* #8 Set Exposure status to Ok */
@@ -274,6 +294,8 @@
 
         /* Are we done yet? */
-        if (ExposeTimeN[0].value == 0)
+        if (ExposeTimeN[0].value <= 0)
         {
+          ExposeTimeN[0].value = 0;
+
           /* Let's set the state of OK and report that to the client */
           ExposeTimeNP.s = IPS_OK;
@@ -281,4 +303,5 @@
           /* Upload a sample FITS file */
           uploadFile("ngc1316o.fits");
+          uploadFile("x0cj010ct_d0h.fit");
 
           IDSetNumber(&ExposeTimeNP, NULL);
Index: /BAORadio/libindi/libindi/examples/tutorial_two.c
===================================================================
--- /BAORadio/libindi/libindi/examples/tutorial_two.c	(revision 503)
+++ /BAORadio/libindi/libindi/examples/tutorial_two.c	(revision 504)
@@ -102,5 +102,5 @@
 static INumber eqNR[] = {{"RA" ,"RA  H:M:S" , "%10.6m" ,0. , 24., 0., 0., 0, 0, 0},
 			 {"DEC", "Dec D:M:S", "%10.6m", -90., 90., 0., 0., 0, 0, 0}};
-static INumberVectorProperty eqNPR = {  mydev, "EQUATORIAL_EOD_COORD_REQUEST", "Equatorial Request",  MAIN_GROUP , IP_RW, 0, IPS_IDLE,  eqNR, NARRAY(eqNR), "", 0};
+static INumberVectorProperty eqNPR = {  mydev, "EQUATORIAL_EOD_COORD_REQUEST", "Equatorial Request",  MAIN_GROUP , IP_WO, 0, IPS_IDLE,  eqNR, NARRAY(eqNR), "", 0};
 
 /* Property naming convention. All property names are lower case with a postfix to indicate their type. connectS is a switch, 
@@ -122,4 +122,8 @@
 ISwitchVectorProperty MovementWESP      = { mydev, "TELESCOPE_MOTION_WE", "West/East", MAIN_GROUP, IP_RW, ISR_ATMOST1, 0, IPS_IDLE, MovementWES, NARRAY(MovementWES), "", 0};
 
+static ISwitch OnCoordSetS[] = {{"TRACK", "Track", ISS_ON, 0, 0}};
+static ISwitchVectorProperty OnCoordSetSP = {mydev, "ON_COORD_SET", "On Set", MAIN_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_OK, OnCoordSetS, NARRAY(OnCoordSetS), "", 0};
+
+
 /* Initlization routine */
 static void mountInit()
@@ -149,4 +153,5 @@
 	IDDefSwitch (&MovementNSSP, NULL);
 	IDDefSwitch (&MovementWESP, NULL);
+        IDDefSwitch(&OnCoordSetSP, NULL);
 	
 }
@@ -276,4 +281,9 @@
 		}
 	}
+        else if (! strcmp(name, OnCoordSetSP.name))
+        {
+            OnCoordSetSP.s = IPS_OK;
+            IDSetSwitch(&OnCoordSetSP, NULL);
+        }
 	
 	
Index: /BAORadio/libindi/libindi/examples/x0cj010ct_d0h.fit
===================================================================
--- /BAORadio/libindi/libindi/examples/x0cj010ct_d0h.fit	(revision 504)
+++ /BAORadio/libindi/libindi/examples/x0cj010ct_d0h.fit	(revision 504)
@@ -0,0 +1,104 @@
+SIMPLE  =                    T /  FITS STANDARD                                 BITPIX  =                   16 /  FITS BITS/PIXEL                               NAXIS   =                    2 /  NUMBER OF AXES                                NAXIS1  =                  512 /                                                NAXIS2  =                  512 /                                                BLOCKED =                    T /  Tape may be blocked                           EXTEND  =                    T /  There maybe standard extensions               BSCALE  =   1.4282676717429E-2 /  REAL = TAPE*BSCALE + BZERO                    BZERO   =    4.6800000000000E2 /                                                OPSIZE  =                 1152 /  PSIZE of original image                       ORIGIN  = 'STScI-STSDAS'       /                                                FITSDATE= '21/09/90'           / Date FITS file was created                     IRAFNAME= 'x0cj010ct_cvt.d0h'  / NAME OF IRAF IMAGE FILE                        IRAF-MAX=           9.360000E2 /  DATA MAX                                      IRAF-MIN=           0.000000E0 /  DATA MIN                                      IRAF-B/P=                   32 /  DATA BITS/PIXEL                               IRAFTYPE= 'FLOATING'           /                                                SDASMGNU=                    1 /  Number of groups in original image            CRVAL1  =     12.6869651851956                                                  CRVAL2  =    -52.1012661989035                                                  CRVAL3  =     87038170.4511719                                                  CRPIX1  =                 257.                                                  CRPIX2  =                 257.                                                  CD1_1   =          2.383380E-6                                                  CD1_2   =          5.689839E-6                                                  CD2_1   =         -5.385026E-6                                                  CD2_2   =          2.518288E-6                                                  DATAMIN =           0.000000E0 /  DATA MAX                                      DATAMAX =           9.360000E2 /  DATA MAX                                      MIR_REVR=                    0                                                  ORIENTAT=             66.12611                                                  FILLCNT =                    0                                                  ERRCNT  =                    0                                                  FPKTTIME= '28-AUG-1990 21:27:29.81 '                                            LPKTTIME= '25-APR-1990 17:30:15.61 '                                            CTYPE1  = 'RA---TAN'                                                            CTYPE2  = 'DEC--TAN'                                                            CTYPE3  = 'TIME    '                                                                                                                                                                           / GROUP PARAMETERS: OSS                                                                                                                                         / FOC DATA DESCRIPTOR KEYWORDS                   INSTRUME= 'FOC               ' / instrument in use                              ROOTNAME= 'X0CJ010CT         ' / rootname of the observation set                FILETYPE= 'SCI               ' / shp, udl, sci                                  NSEGPGRP=                    0 / not computed - used only by OSS                                                                                                                               / CALIBRATION FLAGS AND INDICATORS               OPTCRLY = 'F96               ' / optical relay: F48, F96                        SMMMODE = 'NOTUSED           ' / spectro. mirror mechanism: INBEAM, NOTUSED     SHTMODE = 'NOTUSED           ' / shutter mode: INBEAM, NOTUSED                  LEDMODE = 'NOTUSED           ' / led calibration status: ACTIVE, NOTUSED        PXFORMT = 'NORMAL            ' / format of the image: NORMAL, ZOOM              OPTELT1 =                    7 / filter element, wheel 1 f48: (0-7), f96: (0-11)OPTELT2 =                    0 / filter element, wheel 2 f48: (0-7), f96: (0-11)OPTELT3 =                    0 / filter element, wheel 3 f48: (0),   f96: (0-11)OPTELT4 =                    1 / filter element, wheel 4 f48: (0),   f96: (0-11)FILTNAM1= 'F4ND              ' / filter element name for wheel 1                FILTNAM2= 'CLEAR2            ' / filter element name for wheel 2                FILTNAM3= 'CLEAR3            ' / filter element name for wheel 3                FILTNAM4= 'F346M             ' / filter element name for wheel 4                CAMMODE = 'NOTUSED           ' / coronographic apodizer mask: INBEAM, NOTUSED   SAMPOFF =        0.2560000E+03 / sample offset (0.0-1023.75)                    LINEOFF =        0.2560000E+03 / line offset (0.0-1023.75)                      SAMPPLN =                  512 / samples per line (64, 128, 256, or 512)        LINEPFM =                  512 / lines per frame (64, 128, 256, 512, or 1024)                                                                                                                  / CALIBRATION REFERENCE FILES                    GRAPHTAB= 'mtab$a3c1003jm.tmg' / the HST graph table                            COMPTAB = 'mtab$a3c10030m.tmc' / the HST components table                       UNITAB  = 'xtab$a3f1011cx.cxu' / table of relative detective efficiency filenameBACHFILE= 'xref$91b1313sx.r0h' / background reference header file               ITFHFILE= 'xref$91b13138x.r1h' / itf reference header file                      BLMHFILE= 'xref$a1m1626px.r7h' / blemish header file                            UNIHFILE= 'N/A               ' / uniform de reference header file               SDEHFILE= 'N/A               ' / sde reference header file                      RESHFILE= 'N/A               ' / input reseau header file                       GEOHFILE= 'xref$a3f0949jx.r5h' / geometric reference header file                MODHFILE= 'N/A               ' / reseau mark model header file                                                                                                                                 / CALIBRATION SWITCHES: perform,omit,complete    BACCORR = 'PERFORM           ' / background subtraction correction              ITFCORR = 'PERFORM           ' / intensity transfer function correction         PXLCORR = 'OMIT              ' / split zoom-format pixels                       UNICORR = 'PERFORM           ' / uniform de correction                          WAVCORR = 'PERFORM           ' / compute photometric parameters                 GEOCORR = 'PERFORM           ' / geometric correction                           SDECORR = 'OMIT              ' / spectrograph de correction                     RESCORR = 'OMIT              ' / locate reseau marks                                                                                                                                           / CALIBRATION KEYWORDS                           SAMPBEG =                  257 / first sample number                            LINEBEG =                  257 / first line number                              DNFORMT =                   16 / bits in each data number (8/16)                EXPTIME =        0.7230000E+03 / total exposure time in seconds                 GEODEFV =        0.0000000E+00 / geo DN value for areas outside sci image                                                                                                                      / STATISTICAL KEYWORDS                           DATE    = '28/08/90          ' / date this file was written (dd/mm/yy)          PODPSFF = '0                 ' / 0=(no podps fill), 1=(podps fill present)      STDCFFF = '0                 ' / 0=(no st dcf fill), 1=(st dcf fill present)    STDCFFP = '0000              ' / st dcf fill pattern (hex)                                                                                                                                     / DISPLAY KEYWORDS                               PLOTID  = 'FOC               ' / plot title                                                                                                                                                    / FOC INSTRUMENT DESCRIPTOR KEYWORDS                                            / FOC PHOTOMETRY KEYWORDS                        LEDCOLOR= '                  ' / LED color (a color, blank , NONE or ERROR)                                                                                     PHOTMODE= '                  ' / observation mode                               PHOTFLAM=        0.0000000E+00 / Inverse Sensitivity                            PHOTZPT =        0.0000000E+00 / ST magnitude zero point                        PHOTPLAM=        0.0000000E+00 / Pivot Wavelength                               PHOTBW  =        0.0000000E+00 / RMS Bandwidth of the Filter and Detector                                                                                                                      / DMF EXPOSURE DATA                              PROPOSID= '03039             ' / PEP proposal identifier                        PEP_EXPO= '7.0000000#001     ' / PEP exposure identifier including sequence     TARGNAM1= 'BPM16274          ' / proposer's target name (first 18 char)         TARGNAMC= '                  ' / target name continuation (last 12 char)        PLAN_EXP=  0.9000000000000E+03 / proposed time per exposure                     PLAN_SN =  0.1000000000000E+03 / proposed signal-to-noise ratio                 PRIORITY=                    1 / proposer's priority for exposure               RA      =        0.1251325E+02 / right ascension of the target (degrees)        DEC     =       -0.5213817E+02 / declination of the target (degrees)            EXPOSURE=        0.7230000E+03 / exposure duration (seconds)--calculated        EXPSTRT =        0.8703093E-05 / exposure start time (seconds)                  EXPEND  =        0.8703811E-05 / exposure end time (seconds)                    SUNANGLE=        0.1287219E+03 / angle between sun and V1 axis (degrees)        MOONANGL=        0.8711864E+02 / angle between moon and V1 axis (degrees)       END                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             HHHHHHÔHHHHHÔHHHÔHHHHH`HHÔ``HÔ`HŠÔÔÔHHHHÔ`ŠHÔÔÔÔìHÔÔŠH`ÔHHÔÔÔÔÔHÔÔHHÔÔÔHÔÔHHH`ÔÔHHÔHHHÔHÔHÔHHHÔHHHHHHHHÔHÔÔHHHH`HHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHÔHÔHHHHÔHHHHHHHHHHÔHHHHHHHHHHÔHHHHHHÔHHHHHHHHHÔ`HHÔHHÔHHHÔHHHHHHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHHHÔHHHH`HHHHHHHHHHHHHHHHHÔHHHHHHHÔHHÔÔÔÔÔHHHHHHHHHHHHHHHHHHHHHHHÔ`ÔHHÔHHHHHHHHÔHHHHHÔHHÔHHHHHHHHHH`HHHHHHHH`HHHHHHH`HHHHHH`ÔHÔHHÔHHHH`HHHÔHÔHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔHHHHÔHHHHHHHHHÔHHHHHHHHHHÔHHHHHHHHHHHHHHHÔHHHÔHHÔHHHÔHÔHHÔHHÔHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHH`HHHHHHÔHHHHHHHHHHHHHHHHÔHHHìHHHHHHHÔHHHHHHHHHÔÔ`HHHHHHHHHHHHHHÔHÔHHHHHHHHHHHHHHÔHHHHHÔHHHHHHHHHHHHHHHHÔHHHÔHÔHHHHHHHHHHHHHHHHÔHHHÔHHÔHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHÔHHHHÔHHHHHHHHHHHHHHH`HHHHHHHHŠHHHHHHÔHHÔÔHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔHHÔHHHÔHHÔHHHHÔHÔHHHHHHHHHÔHHHHHH`HHHHHHHHHHÔÔHHHHHŠÔHH`HHHHHHHHHHHHHHHHÔÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHÔHÔHHHHHHHHHÔHHÔŠHHHHHHÔHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHHÔHHHHHHHHÔHH`HHHHHHHHHHHHÔHHÔHÔHHHHHHHHHHHHHÔÔHHHHHÔHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔHÔHHHHHÔHHHHHHHHHÔHHHHHŠHHHHÔHHHHHHHÔHHHHHHHHHÔHHHHHHHHHÔHHHHHHHHHHHHHHHHHÔHHHHHHHHHHÔHHHHHHHHHÔHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHHÔHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHHHHHHH`HHHHÔHHÔHHHHHHHHHHHHHHHHHHHÔHHÔHHHHHÔÔÔHHHHHHHHHÔHHHHHHHHHHHHHHHHÔHHHHÔHHHHHHHHHHÔHHHHHHHHHHHHHHHÔHHHHHHHHÔHHHHHHHHHHHÔHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHŠHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔHHHHHHHHÔHHHHHHHHHHHÔHHHHÔHHHHHHHHHHHHHHH`HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHÔHHÔHHHHÔHHÔHHHHHÔHHHHHHHHHHHÔHHHHHHHHHŠHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHH`HHHHHHHHHHHÔHHHÔHÔHHHHÔÔHHHHHHHÔHHHHHHHHHHHHHHHHHHÔHHHHÔHHÔHHHÔHHHHHHHHHHHHHHÔHHHHHHHHHHÔHHHHHHHHHHHHÔHHHHHHHHÔHHHHHHHHHHHHHHHHHHÔHHHHÔHHHHHHÔHHHHHHHHÔHHHHHHHHHHHHHHÔHHHHHHÔHÔHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔHHHHÔHÔŠHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHÔHHHHÔHHHHHHHHHHHHHHHHHHHHHHÔÔÔ`HHHHHHHHHHHHHHHHHÔHHHHHHHHHHHÔÔHHHHÔÔHHHHHŠHÔHHHHHHHH`HHHHHHÔHHHHHÔHHHHHHÔHHHHHHHHHHHHHHÔHHHHÔHHHHHHHHHHHHHHHHHÔHÔHHHHHHHHÔHHHHÔHHHHHHHHHHHHHHHÔHHHHHHHHHHHÔHHHHHHÔHHHHÔHHHHHHHHHHHÔHÔHHHHHÔHHHHHHHHHHHHHHHHHHÔÔHHHÔHHÔHHHHÔHHHHHHHHÔHHHHHHHHHHHHHHHÔHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHŠHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔHHHH`HHHÔHHHHHHHHHHHHHHHHHHHHÔÔHÔHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHÔÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHÔHHHHHÔHHÔHHHÔHÔHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHÔHHÔHHHHHHHHHÔHHHHHHÔHHHHHÔHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHŠHHHHHHHHHHHHHHHHHHÔHHHHHÔHHHHHHHHHÔHÔHHHHHHHHHHHHHHÔHHHHHHHHHÔHHHHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHÔHHHHHHÔHHHHHHHHHÔHHHÔHHHHHHÔHHHHHHÔHHHHHÔHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHÔ`HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHÔHHÔHHHHHHHHHHHHHHHHHHHHHÔHHHÔHHHHHHÔHHHHHHHHHÔHHÔHHHHÔHHHHHHHHHHHHHHHHHHHHÔHHHÔHHHHHÔHÔHHHHHH`HHHHHHHHHHHHHHHHHHHÔÔHHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHÔÔHHHHÔHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔHHHÔHHÔHHHHHHHHHHHHHHHHHHHÔHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHÔHHHHÔHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHHHHHÔHHHHHÔÔHHHHHHHHHHHHÔŠHHÔHHHHHHHHÔHÔHHÔHHHHHHHÔHHHHHHHÔÔHHHHHHHHHHHHHHHHÔHHHÔHHHHHHHHÔHHHHHHHHÔHHHHHHHHHHHÔÔHÔÔHHHHHHHHHHHHHHÔÔÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHÔHHHÔHHHHHÔÔHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH`HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHH`ÔHHHHHHHÔHHHHHHHHÔHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHÔHHHHHÔHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHÔHHHHHHHHHHÔHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHH`ÔHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔHHÔÔHHÔHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔHHÔHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHHÔHHHHHHHHÔHH`HHHHHHHHHHHHÔHHHHHHHHÔHHÔHHHHHHHHHHHHHHHHHHHHHÔÔHHHHHHHHHHHHHHHHHHHHHHHÔHHÔÔHHHHHÔHHHHHHHHHHÔHHÔHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔÔHHHHÔHHHHHHHÔHHHHHHHHHÔHHHHHHHHHHHHHÔÔHÔHHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHHHHÔHHÔHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHÔHÔHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHÔHHHHHÔÔHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHÔHHÔHHHÔHHHHHHHHÔHHHHHHHHÔHHHÔHHHHHÔHHHHHÔHHHHHHHHÔHHHÔHHHHHHHHÔHHHHHHHHHHHHÔÔHHHHHHHHHHHÔHHHHHHÔHHHHHHÔHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHÔHÔHHHHHHHHHHHHÔHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHÔHHHHHHHÔHHÔHHHHHÔHÔHÔHHHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHHHHHHHHHHHHHÔÔHHHHHÔHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHÔHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHÔHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHÔHHHHÔHHHHÔHHHHÔHHHÔÔH`HHHHHHHHHHHHÔHHHÔHHHHHHHHHHHÔHHHHÔÔHHHÔHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHÔHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHHHHHHHHHÔHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHÔHHHHHH`HHÔHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHÔHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHÔÔHHHÔHHHHHHÔHHHHHHHHHÔHHHHHHHHHÔHÔHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHÔHHHHHHÔHHHHHHHHHÔHHHÔHHHHHÔHHHHHHHHHHHHHHHHHHHÔHHÔHHHHHHH`HHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHÔHHHHHHÔHHHHÔÔHHHHHHHHÔHHHHHÔHHHHHHHÔHHHHHÔHHHHHÔHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔHHHHHHHHHHHHHHHÔHHHHHHHHH`HHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHÔHHHÔHHHHHHHHHHÔHHÔHHHHÔHHHHHHHHHHŠHHHHHHÔHHHHHHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHÔHÔHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHHHHHHHHHHHHÔÔ`HHHÔHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔÔHHHHHHHHHHÔHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHH2HHHHHHHHHÔHHHÔHHHHHHHHHÔÔHHHHÔHHHHHHHÔHHHHHHHHHHÔHHHHHHHHHHHHÔÔHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔHHHHHHÔÔÔHHHHHHÔHHHHHHHŠHHHHHHHHHHHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHÔHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHHHHHHHÔHHHÔHHHHHHHHHÔŠHHÔHHHHHHÔHHHHHHHHHHHHHHHHHHHHÔHHHHHÔHHHHHHHHHHÔHHHHHHHHÔHHHHHHHHHHÔHHHHHHHHHHHHÔHHHHHHHŠHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHÔHHHHHÔHHHHHHHHHHHHHHHHHÔHHÔHHHÔHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHÔHHHHHHÔHHHÔHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔÔÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHH`HHHHHHHHHHHHHHHHHÔ`HHHHHÔHHHHHÔHHHHHHHHHÔHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHÔHHHHHHÔHÔHHHHHHHÔÔHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHÔÔHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHÔHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHÔHHÔÔHHÔHHHHÔHHHHHHÔ`HHHHÔHHHHHHHÔHHHHHHHHHÔHHHHHHHHHÔÔHÔHHHHÔÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHÔHHHHHHÔHHHHHHHÔHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHÔHÔHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHÔHHHHÔHHÔHHH`HHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔHHÔHHHHHHÔHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHÔHHHHHHHHHHHHHÔHHHHHÔÔHHHHÔHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHHÔHHHHHHHÔHHHHHHHHHHÔHÔHHHHHHHHÔHHHHHHÔHHHHÔHHHHHHÔHHÔHHHHHHÔHHHÔHHHHHHHHHHHHHHHÔHHHHHHHHÔHHHHHHHHHHÔHHHHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHÔÔHÔHHHHHHHHHHHHÔH`HHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHÔHHHHHHHHHHHHÔHHHHHÔHHHÔHHHHHHHHHHHHHHHÔHHHHHHHÔHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHH`HHÔHHHH`HHHHHHHHHHHHHHHHHHHHHHHHHHÔHHH`HHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHÔHHHHHÔHHHHHÔHHHHHHHHÔHHHHHHHHHHHÔHÔHHHHHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHÔÔHHHHÔHÔHHÔHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHÔHHHÔHHHHHÔHHHHÔHHHHHHHHHHHHÔHHHHHHÔHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHÔÔÔÔHHHÔHHHHHÔHHHHHHHHHHHHHHHHHHÔHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHÔ`HHÔHHHHHHHHÔHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHÔHÔHHHHHHÔHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHÔHHHHHHHHÔHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHH`HHHHHHHHHHÔHHHHHHHHÔHHHHHHHHHHHHÔHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHÔHHHHHHHHHHHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHHHHHÔHHHHHHHHHHHÔHHHHHHHÔHHHHHHHHHHHHHHHÔÔHHÔHHÔHÔHHHHHHHHHHHÔHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHÔHHHHHHÔHHHHHHHHHÔHÔHHHHHHHHHHHHÔÔHHHHHHHÔHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHÔHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔÔHHHHHHHHÔHHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHÔHHHHHHHHHHHHHHHÔHHHHHHHHHHHHÔHHHHHHH`HHHHHHÔÔHHHHHHHHHHHHHHHHHHHHÔHHHHHÔHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHÔHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔHHHHHHHHÔHHÔHHHHHHÔHHHHHHHHHHHHÔHHÔHHHHHHHŠHHHHHHHHHÔHHHHHHHHHHHÔHHHHÔHHHH`HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHHHHHHHHHHHHÔHHHHHHHHHÔHHHHÔHHHHHHHHHHÔHHHHHHHHHÔHHHHHHHHHHÔHHHHHHHHHHÔHHHHHHHHHHHHHÔHÔHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHHHHHÔÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔÔHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHÔHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHH`HHHHHHHHHHHHHHHHHHHÔHHÔHHHHÔHHHHÔÔHHHHHÔHHÔHÔÔHHHHHÔHHÔHHHÔHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHÔÔÔHHHHHHHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHÔHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHÔHÔHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHÔHHHÔH`HHHHHÔHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHHHHHHÔHHHHHHÔHHHÔHHÔHHHHHHÔHHHHHHHHHHHHÔHHHHHHHHHHHÔHHHHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHH`HHHÔHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHÔHÔHHHHHÔHHHHHHHHÔÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔHHHHHHHHHHÔH`HHHHHHHHHÔHHHHHHÔHHHÔHHHHHHHHHHHHHHHHÔHHHHÔHHHHHÔHHHHHHHHHHHHHHÔHHHHÔHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔHÔHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHÔHHHHHHHHHHHHHHHHHHÔHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHÔÔHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHÔHHHHHHHHHHHHHÔHHHHÔHHHHHÔHHHHHHHÔHHHHHHHHHHHHÔHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHHÔHHHHHHHHHÔHHHHHHÔH`ÔHHHHHHHHHHHÔHHHHHHHHHHHÔHHHHHHHÔHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHHÔHHHHHHÔHHHHH`HHHHHHHHHHÔHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHÔÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHH`HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHÔHHHHHÔHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHÔHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHÔHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHH`HHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHÔHHHHHHHHHHHHHHÔHHHHHHHHHHHHHÔHHHHÔÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHHHHHHHHHHHHHHHHHH`HHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHÔHHHHÔHHHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHÔHHÔHHHÔHHÔHHÔHHHÔHHHHHHÔÔHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHÔHHHHHÔHÔHHHHHHHHHHHHHHHHHHHHÔHHHHÔ`ÔHHHHÔHHHHHÔHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHÔHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHHHHHHHHÔHHHHHHHÔHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHÔHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHHHHÔHHHHHHHHÔÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHÔHHHHHHHHHHHHÔHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHÔHHHHHHÔHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHÔHHHHHHHHHHÔHHHÔÔHHHHHHHÔHÔHHHHHHHHÔHHHÔHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHÔHHÔHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHÔHÔHHHHHHHHHHHÔHHHÔHÔHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHÔHÔHHHHHHHHHHHHHŠHHHHHÔHHHHHHHHHHHHHHHHHHHHÔHHHHÔHÔHHHHHHHHÔHHHHHHHHÔHHHHHHÔHHHHHHHHHÔHHHHHHHÔHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHÔÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔ`HHHHHHHHHHÔHÔHH`HHH`HHHHHÔHHHHHHHHHHHHHHÔHHHHHHÔHHHHHHHHHHHHÔHHHHHHÔHHHHHHHHHHHHHHÔHHHHHHHHHHHÔHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHÔHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHÔHHHHHHHHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHHHHHHHHHHÔHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHÔHHHHHHHHHHHHHHHHHHHHHÔHHÔHHHHÔÔHÔHHHHHHHÔHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHÔHÔHHHHHHHHHHHHHHHHHÔHHìHHÔHHHÔHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHÔHHÔHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHÔHHHÔHHHHHHHHHHHHHÔHHHHHHHÔHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHÔHHHHHHHHH`HHHHHHÔÔHHHHHHHHHHHÔHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHÔHÔÔHHHHHHHHHHHÔHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔ`HHHH`HH`HHHHÔHHÔHHHHÔHÔHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHH`HHHHHHHHHÔÔHHHHHHHHHHHHHHHHHHH`HHHHHHÔHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHÔHHHHÔHHÔHHHHHHHHHHHHHÔHÔHHHHHHHHHHHHHHHHHÔHHHHÔHHHHHHHHHHHHH`HHÔHHHHHHÔHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHÔHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHÔHHHHHHHÔHHHHHHHHHÔHHHHHHHHÔHHHHÔHHÔHHHHHHHHHÔHHHÔHHHHHHHHHHÔHHHHHÔHHHHHHHHHHHHÔHHHH2HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHŠHHHHHHHHHHHHHHHHÔHHHHHHHHHÔHHHHHHHÔHHHHHHHHHHHHÔHHHHHHHHHHHHHHHÔHHHHHHHHHÔHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHÔHÔHHHHHHHHHHHHHHHÔHHHHHHHHHHHHÔHHHHHÔHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHÔH`HHHHHHHHHHÔHHHHHHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHÔHHHHHÔHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHÔHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHÔHHHHÔHHHHHHHHHHHHHÔHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHÔHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHÔHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHÔHHH`HHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHÔHHHHHHÔHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔHHHHHHHHHHHÔHHHHHHHÔHHHHHHHHHHHHHHÔHHHHHHHHHÔHHHHHHHHHHHHHHÔHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHÔHHHHHHHHHHHHHHÔHHHHHHHHHÔHHHHÔHHHÔÔHHHHHHHHÔHHHHHÔHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHÔHHHHÔHHHHÔHHHHHHHHÔHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHÔHHHHHHHHHHHHÔHHÔÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHH`HHHHHHÔHHHHHHHHHÔHHHÔHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHÔÔHHHHHHHÔHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHÔHÔHÔHHHHHHHHHHHHHHHHŠHHHHHHHHH`HHHHH`HÔHHHHHHHHHHHÔHHHHHHHÔHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHÔHHÔHHHHHHHHHHHHHH`HHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHÔHHHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHHHHHHHHHHHHHHÔHÔHÔHHHHHHHHH`HHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHHHHHHHHHHHHHHHHHÔHHHHHHHHHÔHÔHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHÔHÔHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔHHHHHHHHHHÔHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHÔHHHHHÔHH`HHHÔHHHHHHHHHÔHÔHHHHHHHHHHHÔHHHHHHHÔHHHHHHÔHHHÔHHHHHHÔHHHHHHHHHHHHHÔÔHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHH`HHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔHHHHHHHHHHHHÔHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHÔHHHHHHHHHHÔHHÔHHHHHHHHHHHHHHHHHHHHHHHH`HHHHHHHÔHHHHHHHHHHÔHHHHÔHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHÔHHHHHHHÔHHHHHHHHÔHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔÔHHHHHHHHHHHHHHÔÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHÔHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHH`HHHHHHHHHHHHHÔÔHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHÔHHHHHHHHHÔHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHÔHHHÔHHHHHHHHHHÔHHHHHHHHHÔHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHÔHHHÔHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHH`HHHHHHHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHÔHÔHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHÔHÔHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔÔHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHHHHÔHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHìHHHHHHHHHHHHHHHHÔHHHHÔHHHHHÔHHHHHHHHÔÔHHHHHHHHHHHHHHHHHHÔHÔHÔHHHHHHHHHHHHHHHHÔHÔHHHHHHHHHHHHHHHÔHHHÔÔHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHÔHHHHHHHŠHHHHHÔHHHHHÔHHHÔHÔHHHHHHHHHHÔÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHHÔHHHHÔHHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHHHHHÔHHHHHHHH`HHHHHHÔHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHÔHHHHHHHHÔHÔHHÔHHHHÔHHHHHHÔHÔHHHÔHHHHHHÔHHHHHHHHHHHHHHHÔHÔHHHÔHHHHHHHHHHHHÔÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHÔHHHÔHHHÔHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHÔHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHHHHHHHHÔHHHHÔHHHÔHHHHHÔHHHÔHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHÔHHÔHHHHHHHHHÔHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHHHHHHHHHHHHHÔH`HHHHHHHHHHHÔHHHHHHÔHHHHHHHHHHHHHÔHHHHHÔHHHHHHHHHHHÔÔHHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHìHHHHHHÔHHHHÔHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHÔÔHHHHHHHHHHHHHHHHÔHHHHHHHÔHHHÔHHHHHHHÔHHHHHHHHHHHHHHHHHHÔÔÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHHHHHHHHHHHHHHHHHHHHHHH`HHÔHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHÔHHÔHHHHHHHHHHHHHHHHHÔHHHHHHHÔHHHHHHHHH`HÔHHHHHHHHHHHH`HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔHHHHHÔHHHHHHHÔHHHHHÔHHHÔHHHHHHHHHHHHHHHHHHHHÔHHHHÔHHHHHHHÔHHHHHHHÔÔHHHÔHHHHHHHHHHHHÔHHHHHHHHHHÔHHHHHHHHHHHHÔHHHHHHHHHHHÔHHHHH`HHHHHHHHHHHHÔHHHHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHÔHHHHHHÔHHHHHHHHHÔHHHHHHHHHHHHÔHHHHHHHHHHHH`HHHHHHHHHHHHHHHHHHHÔHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHÔHHHÔHHHHHÔHHHHHHHÔHHÔHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHÔHÔHHHÔHHHHÔHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHH`HHHHHHHHHHÔHHHHHHHHHHHHHHHHHHÔHÔHHHHHHHHÔHHHHHH`HHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHÔHHHHHHHHÔHHHHÔÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHÔHHHHÔHHHHHHHHHÔHHHHHHHÔHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHÔHHHHÔHÔHHHHHHÔÔHHHHÔHHHHHÔHÔHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔHHHHHHÔHHÔHHHHHHHHHÔÔHHHHHHHHÔHHHHHHHHÔHHHHHHxHÔHHHHHHHÔHHHHHHHHHHHÔHÔHHHHHHHHHHHHHHHHHHHHÔHÔHHHHHHHHHHHHÔHHÔHHHHHHHHHHHH`HHHHHHHHHHÔHHHHHHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔ`ÔHHHHHHHHHÔHÔHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH`HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHHHÔÔHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHÔHHHÔHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHÔHHHHHHHÔHÔHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHÔHÔHHHHHHHHHHHHHÔHH`ÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHÔHHHHHHHHHHHHHHHHHHHÔHHHHHHÔHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHÔÔHHHHHHHHHHHHHHHHÔHHHHHÔHHHHHHHHHHHÔHHHHHHHHÔHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHÔHHHHÔHHHHHHHHHHHHHHHHHHÔÔHHHHHÔHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHÔHHÔHHHHÔHHHHHHHÔHHHHHHHHÔHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHHÔÔHHHHHÔHHHHHìHHHÔHHHÔHHHHHHHHHÔHHHHHHHHHÔHHHHHHHHHHHHHHÔÔÔHHHHHHHHHHHHHÔÔHHHHHHHHHÔHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH`HHHÔHHHHHHÔHHHHHHHHHHHHÔHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔ`HHHHHHHHHHHHHHHÔHHHHìHHHHHHHHHHÔHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHÔHHÔÔHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHÔHHHHHHHHÔHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHÔHHHHHHHHHHHHHHHHHHHÔHHHHHHHHÔHHHHHÔHHHHHHHHHHHHÔHHHHHHHÔHHHHHHH`ÔHHHHHHHHHHHHHHHHHHHÔÔHHHHHHHHHHHHHHHHHHHHHÔHÔHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHÔHHHÔHHHHHHÔHHHHHHÔHHHHHHHÔHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHÔHHHHHÔHHHHHHHHHHHHHHHHHÔHHHHHHHHH`HHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHÔHHHHÔHHHHÔHHHHHHHHÔHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHÔHHHÔÔHHHÔHHHHHÔHHHHHHHHHHHHHHHHHHHHH`ÔHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHÔHHHHÔÔHHHHHHHHHHHÔHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH`HHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔÔHHHHHÔHHHHHHHHHHHHHHÔHHHHHHÔHHHHÔHHÔHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHÔHHHÔHHHHHHHHHÔHHHHÔHHHHHHHHHHHHHHHHHHHHHH`HHHHHHHHÔHHHHÔHHHHHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHÔHHÔHHHHHHHHHHHÔHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHÔHHHHÔHHHHHHHHHHHHHHHHHHHHHÔÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH`ÔHHHHHHHHHHHHÔHHHHHHHHHHHHHÔHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔHHHHÔHÔÔHHHHHŠHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔHHHÔHHÔHŠHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHÔHHHHHÔHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔÔHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHÔHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH`HHHHHHHHHHHHHHHHHHHHHHHHHHÔHHÔÔHHHHHHÔHHHÔHHHHHHHÔHHHHHHHHÔHHHHHHHHHHHHHHHHHHÔHHHHHÔHHHHHHÔHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHÔÔHHÔHÔHHHHHÔHÔHHH`HHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHÔHHÔHHHHHHHHHÔHHHHHHHHHHHHHHÔHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHÔHÔHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHÔHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHÔHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHÔHHHÔHHHHHHHHHHHHHHHHHHÔÔHHHHHHÔHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHÔHHHHHÔÔHHÔHHHHHHHÔHHHHHHHH`HHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHÔHHHHHHHHHHHÔHHHHHHHHHHHHÔHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHÔHHHHHHHHÔHHÔHHHHHHHHH`HHHHHHHHHHH`ÔHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHÔHHHHHHHHHHHHHHHŠHHHHÔHHHHHHHHHHHHHÔHHHHHHHHHÔHHÔHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔHHHHHÔHHHHHHHHHÔHHHHHHHHÔHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHÔHHHHHHHÔHHHHHHHHHHHÔHHÔÔÔHHHHHHHÔHHHHHHHHHHHHHHHHHHHÔHHÔÔÔHHHHÔHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHÔHHHHHHHHHÔHHHHHHHHHHHHHHÔHHHHHÔHHHHHHHÔHHHHHHHHHHHHHHHHHHHÔHHHHHHÔHHHHHHHHHÔHHHÔHHHHHHHÔHHHHHHHHHHHÔHHHHHHHHHHHHHÔHH`HÔÔHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHÔHHHÔHÔHHHÔHHHÔHÔHHHHHHHHHHHHHHHHHÔHHHHHHHÔHHHHHÔHHHHHHHHHÔHHHHHHHHHHHHHHÔHHHHÔHHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHÔHHHÔHHHHHHÔHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHÔHHHHHHHHHHHHHHH`HHHHHHÔHHHHHHHHHHÔHHHÔHHHHHHHHHHÔHHHHHHHHHHÔHHHHÔH`ÔHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHÔHHHHHHHHHHHHHHHÔHHHHHÔHHHHHHÔÔHHÔHHHHHÔHHÔHHHHHHHÔHHHHHHHHÔHHÔHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHÔHHHHHHHHÔHHHHHHHHHHHÔHHHHHHHHÔHHHHHHHHHHHÔHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHÔHHHHHHHHHHÔHHHHHHHÔHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHÔHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHÔHÔHHHHHHHHHHÔÔHHHHHHÔHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHHHÔHÔHHHHHÔHHHHHHHHHHÔHHÔHHHHHHHHHHHHHHHHÔHHHHHHHHHHHÔHÔHHHHHHHHHÔÔHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHHHHHÔHHHHHHHHHHÔÔHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHHHÔHHHHHHHHÔHHHHÔHHHHHHHHHÔHÔHHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHHHHHHÔÔHHHHHHHHHHÔHHHHHHHHHHÔHHHHHHÔHHHHÔHHHHHHHHÔHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHÔHÔHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHHHHHHHÔHHHÔHHHÔHHÔHHHHŠHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHÔHHHHHHHHHÔHHHHHHHHHÔHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHÔHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHÔHHHHHÔHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHÔHHHÔHÔHHHHHHHHHHHHHHHHHHHHHHÔÔHHHÔHHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHÔHHÔHÔHÔHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔH`HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHÔHHHHÔHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHÔHHHHHHÔÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHÔHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHÔÔHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔHÔHHHÔHHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHÔÔHHHHHÔHHHHHÔÔHHÔHHHHÔHHHHHHHÔÔHHHHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHìHHHHÔHHHHHHHHHÔHHHÔHHHHHHHHÔHHHHHHHHHHHHHHHHHÔHHHHHHHHÔÔHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHÔHHHHHHÔHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHÔHHHHHHHHHÔHHÔHHHHHHHHHHÔÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHÔHHHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHÔHÔÔHHHHHHHHHHÔHHHHHHHHÔHHHHH`HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHÔHHÔHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHÔHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHHHHHHHÔHHHHÔHHHHHHHHHHHHHHÔHHHHHÔHHHHHHHHHHHHHHHHHHHÔHHHHHHHH`HHHHHHHHÔÔHHHHHÔHÔHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHÔHHHHHHHHHHHHHHÔHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHÔHHHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHHHHHHHHÔHHHÔHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHH`HHHHHHHHHHHHÔÔHHŠHÔHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHHHHHH`HHHHHHHHHHÔHÔHHÔHHHHÔHHÔHHÔHHHHÔHHHHHHÔHHHHHHHHHHHHHHHHHHÔH`HHHHHHHHHHHHHHHHHHHHHÔHÔHHHHHHHHHHHÔÔHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHÔHÔHHÔHHHHHÔHHHÔHHHHHHÔHHHHHHHÔHHHHÔÔHHHHHHHHHHÔHHHHHHHÔHHHHHHHHÔHHÔHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHÔHHHHHHHHHHHHÔHÔÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHÔHHHHHHHÔHHHHÔHHHHHHHHHHHHHHHÔHHHHHÔHÔHHÔHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHÔHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHÔÔHHHHHHÔHHÔHÔHHHHHHHHHHHHHH`HHÔHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔHHHÔHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHÔHHÔHHHHHHHHÔHHHHÔHHHÔHÔÔÔHHHHHHHHHHÔHHHHÔÔHHHHHHH`HHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHÔHHHHHHHHHHHÔHÔHHHHÔÔHHHHHHHÔ`HHHHHHHÔHHÔHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHÔÔÔHHHHHHHHHHHHHHÔHHHHÔHHHHHHHHHHÔHHÔHHHHHÔHHHHHHHHHHHHÔHHHHHHHHHHHHH`HHHÔHHHÔHHÔHHHHÔHHHHÔÔÔ`HHHÔÔHHHÔÔHHÔÔHHHHHHHÔHÔHHHHHHHÔHHÔÔHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHHHÔHHHHHHHHHÔHHHÔHHHHHHHHHHHH`Ô`HHÔHHHHHHHHHHHHHHHHÔHHHHHHHHÔHHHHHÔHHÔHHHÔHHÔHHHÔ`HHHHHHÔHHHÔHHHÔ`HÔHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHÔHHHHHHHHHHHHHHHÔHHHHHHÔÔHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHÔHHÔHHHHÔÔHHHÔHHHÔHHÔHHHHHHÔHHHÔH`HHHHÔHHHHÔHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔHHHÔHHHHHHHHHHHHHHHHHHH`HHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHÔHHHHÔHÔHHÔHHHHHHHHHHHHHHÔHHHHÔHHHHHHÔHH`ÔHHHÔÔHHHÔHÔHHÔHHHHHHÔHHÔHHÔHÔHHHÔHÔHHHHÔHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHÔHHHHHHHHHHHÔHHHHHÔHHHHHHHHÔHHHHÔHHHHHÔÔÔHHÔHHHHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHÔHHHHHÔHÔHÔ`HHHÔHHHHHÔHÔÔHHHHHHÔHìHÔÔH`HÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHÔHHÔHHHHHHHHÔHHHHHŠHHHHHHHHÔHHHHHHHÔ`HHHHHHHHHHHHHŠHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHÔÔHÔ`HÔÔHHHÔHHHHHÔHÔHHHHHHHÔÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHÔHHHHHHHÔHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHÔHÔHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHHHHÔHHHHÔHHHHHH`HHHHHHHHHHHHHÔHHHHHÔHHHH`HÔHHÔHHÔ`HHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHÔÔHH`HHHHHHHHHÔHHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHÔ`ÔHHHŠHÔHHHHÔHÔHHHHHHH`Ô`HÔHÔHHÔHHHHÔHHHHÔHHHÔÔ`HHÔHHHÔHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHÔHHÔŠHÔHHHÔHH`ÔÔHÔÔH``HHHHHÔ`HHHHHHÔHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHHÔHHHHHHHHHHHHÔHHHHHŠHHHHÔHHHHHHHÔHHHÔÔÔHHHÔÔHHÔÔÔHHHHHHHHHHHHHÔÔHHÔHHHHHHÔHHHHÔÔŠ`HÔH`ÔÔÔHÔHHHìHÔÔHÔÔHÔHHHÔHHHH`HHHHHHHHHHHHHHHHHHHÔHHHHÔHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHÔHŠHHÔHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHH`HHHÔHÔHÔHHHÔÔHÔHHH`HHHHŠHHHHHHHÔHHHHÔHHHHHHHHHÔHHHÔHHHÔHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHÔÔHÔHHHHHHHHÔHHHHHHHHHHÔHHHÔHHHÔHHHHÔHHÔÔH`HÔHHÔH`ÔHHHHHÔHHHHHHHHHÔÔHHHHÔHHHHHHHHHHHHÔHHHHÔÔHHÔHHHHHHHÔHHHHHHHHHHHÔHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHH`HHHHHHHÔHHHHHHHHHÔÔHHHHÔHHHHHHHHHÔHÔHHHHÔHHÔHÔHÔHHHÔHH`ÔÔHHÔHHÔÔHHÔHHHÔHHÔHHÔHHHHHHHHÔÔHHHHH`HHÔHHHHHHHHHHHÔHHHHHHHŠHHHHHHHHHHHÔHÔHHHHHÔHHHHÔHHHHHHHHHHHHHHÔÔHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHÔHHHHHHHHHHHHHHHÔHHHHHHHÔÔHHHHHHHHHÔHHH2HHÔHHHÔÔHÔ`HHHHHÔHHHHHHHÔHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHÔHÔHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHÔHHHÔHHHìHÔHH`HHHÔHHHHHÔHHHHHHHÔHHHHÔÔHÔHHHHÔŠÔŠHHÔHHHŠÔÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHÔHHHHÔHHHHHÔHHHHHHÔHHHHHHHHHHHÔHHHHHHHHHHHHÔHHHHÔHHHHHHH`HÔHìÔHÔ`ÔHHHHHHHH`HÔHÔHHHHHHÔHÔ`HHÔHHHHHHÔÔÔÔHÔHHHHHHÔÔHHHHHHHHHHÔHHHHHHÔHÔHHÔHHHÔHHHHÔHHHHHHÔHHHHHHHHHHHHHHHŠHHHÔHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHÔÔHHHH`HHHHÔHHHHHÔHÔHŠHÔHÔÔHH`ÔHŠÔÔHHHHHHÔÔÔHHHHHÔHÔHHHHHHHHÔÔHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHÔHHHHHHHHHÔHHHHHHHHHHHHHHÔHHHHHÔHHHHHHHHHHH`HHÔHHÔÔHHÔHHÔHHHÔHHHHHÔ`HHHHHÔHÔHHHÔHHHÔÔÔÔHHHÔÔÔHHHHHHHHHHHHÔHHHHHHHHHHHHHHH`HHHHHHHHHHHHHHHHHHHHHHHHH`HHÔHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHÔHHHHHHHHÔHÔHÔHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHÔHHHHHH`HHÔ`HHHÔÔHHHHHH`ÔHÔHHÔHŠHHÔHHHHHHHHHÔHHHHHHHH`HHHHHÔHHÔHHHHHHHHHHHHHHHHHHHHHH`HHHHHHHÔHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHÔHÔHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔH`HHŠÔHHHHÔHHHHHHÔ``HÔÔHÔHHH`HHHHHŠ`ÔÔ`ìÔHHHÔHHHHHHHHHÔ`HHÔHHHHHHÔHHHÔÔÔÔÔÔHHHHÔHHHHHHHHHHHHHHHÔHHHHÔHHHHHHHHHHHHHHHHHHÔHHHHÔÔHHHHHHHÔÔHHHÔHHHHÔHÔHHÔHHÔHHHÔHHHHHHHHHHHHHHHHHHHHHHHÔHHÔHÔHHHHHHHHHHHÔHHHH`HH`Ô`HÔHÔŠH`HHHÔHHÔH`ÔHÔÔ`ÔHHHÔHHÔHHHÔÔ`ÔHHHHHHHHÔ`HHHHÔŠ`ÔHHÔHHHHHHHHHHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHÔÔHHHHHHHHHHHHHHÔHHHHHHHHHHÔHHHHHHÔHHHHHHÔÔHHHHHHHHHÔHHHHHHHHHÔHHHÔHÔHHHHHHHHHHHHHÔH`ìÔHHÔHHÔHÔHHH`H`HH`H`ÔHHHHHÔHHÔHHHÔHÔHHHHHHHHHHHHHHÔHHHHHHHÔHHHÔHHHÔHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHÔHHHHÔHHHHHÔHHHHHHHHHHÔHHHHÔHÔHHHHHHHHHHHHHHHHHHHHHHHHÔHÔHHHHHHÔHHHHHHHHÔÔH`HÔHÔÔHÔ`HHŠHHHHHH`HHHÔHHHHHÔHHHÔHÔHHÔ``HHHHÔHHÔHHHHHHHHHHHHÔHHHHHHHHHHÔHHHHHÔHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHÔHHHHHHHHÔHÔHHÔÔÔHHHHHHHHHHHHHHHHÔHHHHHHHHÔHHÔÔHHÔHHH`H`ÔHHÔHHHHÔHHHHHHHHHÔHHHHHHÔHÔHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHÔHHHHHÔÔHHHÔHHHHHHHHHHÔÔHHÔHH``ÔÔÔÔHHHHÔÔÔ`HÔÔHHHÔÔHHHHÔHÔ`HHÔHHHHHÔŠÔHÔ`HHÔHHHHHHÔHHHHHHHHHHHHÔÔHHHHÔHHHHHHHHHHÔHHHHÔHHHHÔHÔHHHHHHHHHHHHHHÔÔHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHÔHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHHHHÔHÔHHHHHÔ`HHÔHÔHÔÔHHHHìHHHÔÔHHHÔÔHHÔHHHÔHHHÔÔÔHHÔÔÔÔÔHÔHÔHHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHÔHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHÔHHHHHHH`ÔHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHÔHHHHHHHÔ`HHHÔHHÔHHHHŠHÔÔHHHHHHHÔHHHHHHHHHHŠŠÔÔHÔHHHHHHHHÔHH`HHHHÔHHHÔHHHHHHHHHÔHHHHHHHHHHHHHHHHHHÔHHHHHHHHÔHHHHHHHÔHHHÔHÔÔHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHÔHHHÔHHHH`HHHÔHHHHHHÔHÔHHHHÔHHHŠÔì`HÔÔHHHÔ`ÔHH`ÔH`ÔÔÔHÔÔÔŠHìÔHHHHHHHŠŠHHŠÔHHHHÔHHHÔÔHÔÔHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHHHÔŠ``ÔÔÔHHHHÔÔ`HHÔŠHÔÔÔHHHHÔHHHHHŠìÔÔŠHHHHHHÔHHHHHÔÔŠHHHŠHHHHHHHHHHHÔHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHÔHHHÔHHHHHHHÔHHHHHHHHHHHÔHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHHHHHHHÔÔHHHHÔHHHHHHHHHÔÔÔŠŠHŠÔÔHÔHHHÔHHHHHŠ2HH`ÔHHHHH`ÔÔHH`ÔìÔHHÔHHHÔÔÔÔH`HHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔÔHHHHHHHHHHHHHHHHÔHHÔHHHÔHHHHHHHHHHHHHHHHHHHÔH`HHÔHÔÔHHHHHHÔHHHHÔŠHHHHÔHŠŠÔ2ìÔH`HÔÔHÔÔHHÔHH`ŠÔHHÔHHÔÔHHÔÔHÔÔÔHHHÔHHHHHHÔŠŠÔHHHHÔHHÔHHHÔHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHÔHHHÔHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHŠHHHÔÔÔÔ`HÔHHÔHHHÔHHÔÔ`H`Ô``HŠÔŠHH`Ô`HÔ`HÔÔÔÔÔHHHÔH`HHÔHHÔ2ÔŠH```ÔHHHHHÔÔHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHÔHÔHÔHHHHHHHÔHHHHHHHHHHHHHHHHÔHHHHÔHHHHHHHHHHHHÔHHHHHHHHH`ÔÔŠ``HHHÔHHHHÔHH`ÔìÔ`JHÔHHÔŠ`ŠìÔÔ`ÔÔÔÔHHHÔÔHHHHŠ`ÔÔHH2ŠH`Ô`ÔÔHHHHHHHHÔHHHHHHHHHHHHHHHÔHHHHHHÔHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHÔHHHHHHHHHHHÔHHHHHHHHÔHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHÔÔHHHHHHHHHÔHÔŠÔ`ŠÔx`ÔÔHÔÔHÔÔŠHxŠHHHÔìHÔÔHìŠHHHŠHHÔÔÔH`HHHŠHHHÔHHHÔHÔHHÔHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHÔHHHHHHHHHHHHHÔHHHHÔHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHÔHHÔHHÔ`HHHÔHHŠ`HHHHHHÔ`ÔHÔHHÔHHHÔHH`Ô`ì``ÔÔHÔ`H```Ÿ2x`ÔÔ`ÔŠÔ`HHHÔ`HÔHHHH``ŠHH`HHHHÔ2ÔH`HÔHÔHHÔHHÔÔHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHH`HHHHÔHHHHHHHHHHHHÔHHHÔHÔÔHÔŠHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHÔÔHÔHHHHHÔHHHÔìÔìÔ`2ÔxŠŠÔHŠŠŠÔÔÔx```ÔÔÔìÔÔ`Ô`HHÔHHHH`ÔHìH``ÔÔHHHHH`ŠÔ2ìHÔHHHHHHHHHHHHHHHHHHHHÔÔHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔHHHHHÔHÔHHÔHHHHHHHHÔHHHÔHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHÔÔÔHÔHHÔÔHÔŠÔ`HHHHìHHÔ`ìì`2ÔŠHìŸŠÔH`ŠÔ`Ô``ìŸÔHÔÔŠHHÔÔHÔÔHHÔHHHÔÔŠ`ÔHHÔÔHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHÔHHHHHHHÔÔHÔÔHHHHHHHHHHHHHHHHHHHHHHÔÔ`ÔH`HÔHÔH`HHÔŠÔHHHÔÔì`Ô2ŸHÔÔ`ÔHÔ`HÔxÔÔÔ`ìŠHÔÔÔHHÔ`HÔ`HHÔHÔÔÔHHÔHHHHÔÔÔHÔHHÔHHHHHHHHHHHHHHHHHHHHHHÔÔHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHÔHHÔHHHHHHHHÔHHÔÔHÔHHHÔÔHHHHHHHHHHÔHHHHHHHHHHHHHHÔHÔ`HHH`HÔÔHÔÔHÔHÔHHHÔHHÔHÔHHÔÔ`Š2ŸHÔHHHÔ`Šì`Ô`ìxŠÔHÔÔŠŠHHHHÔÔŠ2ŠŠÔÔÔÔÔHHHÔ``HH`HHÔHHÔÔÔHHÔÔHHHÔHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHÔÔHHHHHHHHHHHHHHHHHÔHHHÔHHHHHHHH`ÔHHHHHHHHHHHHHHHHHÔHHHHHÔHÔÔÔHHHHHHHHHHHHHHÔHHHHHŠÔHÔÔÔHÔHHHÔHHÔHHHHHH``HHHÔ`ÔŠÔH`ìŠŠÔÔHÔHŠxìŠì`ÔHŠŠÔ`H`HHHHŠÔŸ2HìÔ`HHHHÔÔÔHH`H`HHHHÔ`ÔHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHÔÔHHHHHHHÔ`HÔHHÔH`ÔHÔHH`ÔHHHÔHHHÔHÔHHHHHÔÔŠŠÔHÔÔÔÔH`ÔHÔŸÔHŠ`ÔŠÔHHÔ`ŠÔÔ`x2ŠHHHH`Š`HHHHHHHÔHÔHHHÔÔHHHHHHH`HHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHÔÔHHŠHÔHHHHHHÔHHHHÔHHHHÔHHHHHHHHHHHHHHÔHHHHHHHHHÔHHHÔÔHH`HÔÔH`ÔÔHHH`ÔHÔHHÔ`ì`ÔÔHHŠÔÔHHHHHÔHHÔHÔH`ÔŠÔÔ`HHHÔÔ`HÔ``ÔHHHHHÔHHÔH`ŠHHÔÔHÔHÔHÔÔÔÔHÔHÔÔHHH`ÔHHÔHHHHHHHHHÔHHHHÔHHÔHHHHHHHHHHHHHHHHHHHHHHHHHÔH`HHHHHHHÔHHÔHHHHHH`ÔHHHHÔHHHHHHHHHHHHHHHHHÔHÔHHHHŠH`HÔHÔÔHÔ`ÔHÔHHHHÔHÔHHHH`H`ŠH`Ô``xHHH``Ô2HÔÔÔHÔ`HìŠHŠHÔHÔÔHHÔHHÔH`ŠÔHHHHHHHHHHHÔHHHHHÔHHHÔÔHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHÔHHHHÔHÔHHHHHHHÔHHHÔŠÔÔ`HHÔHÔHÔÔHHÔHHÔHHHHÔHHHHHHH`HŠxÔxì`HHŠHÔ```Š`ŠHHÔÔÔHHÔÔŠŸì2HÔ`ÔHÔHHHÔŠ``ÔÔHÔHHHHÔHHHHHHHHH`HHHHHHÔHHHHHHHHHHÔÔHHHHHHHHHHHHHÔHHHHHHÔÔHHHHHHHHHHÔHHHHHHHHHHHHH`HHHHÔHHÔHHHHHHHHHHHHHHHHHHHHHÔÔHHHHÔHHHHHÔ`ÔÔHHHÔHÔHHHHÔHHÔHÔHÔÔììÔÔÔÔÔ``ÔÔÔ`ÔÔÔH`ÔHHHÔÔ`Ô`ÔÔHHHHHÔ`2Š`HHHHHÔÔH`HÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHÔHHHHHHHHHÔHÔHHHHHHHHHHÔHHÔHHHHÔHHHHHHHÔHHHHÔÔÔÔHHÔHÔHHHÔH`ÔHHHHHHHÔHHHÔÔŠHHÔì2ÔŠÔŠ`Ô`HŠÔìŠ``Š`ÔÔHHH`2`HìŠHÔŠìÔHHÔHH`HÔ`2ÔHŠÔHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHHHHHHHHHHHHHHÔHHHHHHHÔHHHHHHHHHHHHHHÔHHHHÔHHHHHHÔÔHHHHHHÔHHHHÔHHHHHHÔHÔHÔHH`HHHH`ÔH`ŠHÔHHH`HHHHÔ``HHŠŸ```HHÔì2H`ìx22``HHH`ŠÔHHHHHH``Ô```HHHHÔÔHHHHHHHHÔHHHÔHHÔHHHÔÔHHÔHÔHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHÔÔHHHHHHHHHHHHHÔH`HHHHHHHŠHHHHHŠÔÔHÔHHÔHHÔÔŠÔ`ŠÔ`2`ì2ììÔÔŠÔÔìÔ`Ô``2ŠHÖxÔ2ÔHÔÔ``HÔ`HHHÔŠŠÔHÔÔHHHHÔHHHHHHÔHÔHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHÔHHHHHHHHHHÔHHHHÔHHHHHHHHHÔHHHHHH`HHÔHHHÔHHHHHHHHHHHHHHHHHÔHHHHHÔHHHHHHHHHÔHÔHHHHHHHHÔ`HÔHÔHHHHHHHÔÔ`ÔÔHH`ÔHŠŠHÔ`ÔìÔ`2ÔÔŠ``ÔHÔÔììÔx```Š``ŠŠ`ÔHìHÔÔÔÔÔHH`Ô`Ô`ÔÔHHHHHHHHÔHHHHHH`HÔÔHHHHHHHHÔHHHHHHHHÔHHHHHHHHHHHHHHHÔHHHHHHHHH`HHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔHÔ`HHHHÔÔÔHÔÔHŠ`HÔ`HHÔHHH`HHHÔHÔ`ÔÔìÔŠŠÔHÔxÔHHHÔ2``HHÔ`Ô`ŠHÔHÔHHHH``HŠxHÔÔÔHHHHÔHÔHÔÔHÔHÔHHÔ2HHHHHHHHÔHÔHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHÔHÔHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHŠHHHÔHHÔHHHHHHHHHÔHÔHHÔHHÔHHHHÔHÔÔHÔHŸHHÔÔÔÔÔHÔÔH``HÔHììÔÔ`H`ŠH`HÔÔHÔHÔÔÔH`ì`ÔHÔÔHÔH`ŠHHÔHx`ÔÔHHHÔ`ÔHH`HHH`HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHÔHHÔÔÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHÔHÔHÔHHÔÔHHHHHHÔHÔH``HHŠÔÔÔÔ`ÔÔ```ÔÔÔŠ`ì2Š`ÔÔÔHŠ`HHÔŠÔÔÔ`ìHÔH`HHHÔÔHHHÔHìÔ`ŠHHHHHHÔHHHÔÔÔŠÔÔHÔÔŠHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHH`HHHHHHHHHHHHHHHHHHHHHŠHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHÔHŠÔHÔHHHÔ`HHHHÔHH`ÔHHÔÔÔ`ÔÔÔÔHHHHÔHÔH`Š`2HÔÔŠÔ`Ô`Ô`HHŠŠŠŠÔHŠÔÔ`HÔHHHÔ`HÔ`HÔHŠ`ŠÔÔÔHHÔÔÔHHHÔHHÔÔÔH`HHÔHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHH`HHHHHHÔHHHHHHHHHHHHHHÔHHHHHÔHHHHÔHHHHHHHHHHÔHHHHHHHHHHÔŠHÔH`HHHHÔÔHHHŠÔ`H`HÔHH`ŠÔH2ìÔ`ŸÔŸÔÔHHHÔ`H`ÔÔÔHŠÔ`ÔHÔHHHHH`ìŸ`ÔHÔHHH```ì`ŠŠHH`ÔHHHHHHHÔÔÔHHìH`ÔÔ`HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHÔHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHHHÔHHHÔÔHHHÔÔŠHHHHHÔŠ2ÔHHÔHHHH`HH``ÔÔÔÔHŸì`ŠŠ``H`ÔÔ``H``ÔHHHHÔ`HÔÔÔHHÔ`ŠHxŠxŠ`HÔHÔHHHHHHHHÔÔ`HÔHÔÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHÔHHHHÔHHHHÔHÔHHHHHHHHHHHHHHHHHHHHHHHÔHHÔÔÔH`HHHHHHHÔÔHHÔHHÔÔÔ`Šx`ìŠHÔxÔŸHŠŠ`x`ÔŠÔHÔì`HHHŠŠHÔHHHHHÔH`HìÔÔÔHHHHÔŠ2Ô`ÔÔÔÔHÔHHÔHHHÔÔHH`HHHŠHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHÔÔHHHHHHÔHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHÔHHHÔÔHHHHHHHHÔHHÔÔÔHÔHÔì`ÔHHÔHÔ```ÔHHHHÔHHÔÔ``Š``H`H`ì`ŠHÔ2`ìx2ìÔHÔì`ŠJŠÔì2ì2ÔÔ`ÔÔÔHHHÔÔ`ìÔÔÔHHÔŠÔŠÔŠ2ì`ŠÔ`HHHHHÔÔHÔ`ŠÔÔHÔHÔÔÔHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHÔHHHHHHHÔHHÔHHHHHHHHHHHHHHHHHH`ÔHHÔHHÔHHHHHHHH`ÔHHÔHH`H`HÔ`ÔÔHÔHÔì``HÔÔŠŠ`H`ÔHHÔÔŠìŠ``H`ììÔÔ22ŠŠì``ŠŠHìÔHHH`Ô`2`Š``ÔHÔÔìì`2Ô`ìÔ`H`ÔHHHHH`HHHÔHŠÔHHHÔÔHHÔHHHHHHHHHHHHHHHHÔHHHÔÔÔHHHÔHÔHHHHHHÔHHHHHHHHHHHHHHHHHHHÔHHHHÔHHHÔHHHHHHHHHÔHHHHHHHÔHHHHHHÔÔHHHHÔHHHHHHHÔHÔHÔÔHHHÔHH`HÔHHHÔÔÔÔ`HÔÔ`ŠÔÔHŠÔŠÔHÔH2`x`Ô`ìHÔÔ`xÔ`Ô`ÔxxÔJ22ŸÔ22ÔxH`ìŠÔŠšŠŠHÔÔHÔÔ2`2HŠHÔHHÔH`2ÔxHÔHÔ``ÔÔÔHHHHÔH`ŠÔH``ŠÔÔHHHHHHHHHHHHHHHÔHHHHHHÔHHHHHHHÔHHÔHHHHHHHÔHHÔÔHHHHHHÔHÔHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHÔHHHHHHHHÔHHH`HÔHÔHHÔHHHHH2ÔHÔÔÔ2222`ŠÔ`ìÔÔÔÔ``ŠŠŠ2ŠÔÔŠìÔHÔHÔ2ÔŠŸ
+ŸÔŠHHÔÔHH`HHHHŠH`ÔHÔÔììÔŠÔÔHHHÔHHH`HÔŠÔHÔHŠH`HHÔH`HHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHŠHHÔÔHHHHHHHHHHÔHÔHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHÔHHÔHHHÔHHHÔHHHHHHHHHÔŠHHHH`xì`ŠÔŸÔHìÔH`H`ÔÔHŠ``Š2ÔìŠHŠH`ì2
+4Öx`xÔHŠÔ`ÔHÔHÔHxì`xHŠÔ``Ô`HÔÔHHHHHH`HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHHHHHHHHÔHÔH`HHÔHHHÔHHÔHHÔHHHHHHHÔHHHÔHHŠÔÔHHH2`ìŠŠ`ŠŠ`H`H`ŠŠÔÔÔ`Š`HÔ``ÔHH`ŠŠ2Šb
+z`HHHÔìÔH`ìÔÔHHHHŠ`ì`2HHHHHHHÔ`HHÔHÔH`HHHHHÔÔHHHHÔHHÔHHHHHHHHHHHHHHHHHHHHÔHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHÔHHHHH`ÔHÔHŠHHŠÔÔìÔH`ì`2xì`Ô`ŠH``Ô`ŠŠìÔììÔHÔH`Ô2ŠŸxÔHHHH`Hì`HÔHŠH`HH`xH`HÔÔÔHHHHŠHH`HHHHHÔHÔHHHÔÔH`HHÔHHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHH`HÔHHHHHHHÔHHHÔHÔŠÔHHHHHHHÔHHÔÔHìÔÔŠÔììŸ2`Š`ìÔHH`ÔÔH`Ô`HÔ`H2``x2HÔÔÔŸŠÔŠÔÔÔHŠÔÔ`HŠìŠ`ìHÔ`HÔ`HHÔ``HHHHHÔHHHH`ìHÔHHÔHHHHÔHHHHHÔHÔHHHHHHHHHHÔÔÔHHÔHÔHHHHHÔÔHHHHHHHHÔHHÔÔHHHHHHHHHHÔÔHHÔHHHHHHHHHHHHÔHHHHHHHHHHÔHHHÔHHÔH`HHHÔHHHHHHHHHÔŠHHHHHÔŠH2Ô`ÔH``ŠÔÔŠHÔHÔŠŠŠŸìÔHŠÔŠÔHÔHHŠ2ŸxìŠ`HHÔì2ì2ìxÔÔHHÔHHHÔÔŠŠìÔÔHHH`ÔHHHÔHÔÔÔ`ÔŠHHHÔÔH`ŠŠHÔÔÔHHÔHHHHHÔHHHHHHHHÔHHHHHHÔHHHHHHHHHHHHHHÔHÔHÔHHHHHHHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHHHHHHHHÔÔHHÔHHHHÔHHHHHÔHHHHHHÔÔHHÔHHH`HÔ`ÔHH`HÔHH`ÔHH`Š2HÔÔìHHHÔÔŠŠÔHÔÔÔÔŠÔì``HHxìÔH``ÔŠ2`Š`ÔÔÔHHH`Hì`ŠÔ```ÔHHÔH`ŠÔìH`HìÔÔHHHHHÔ`HÔÔHŠŠŠÔŠÔHHHÔÔHHHHHHHHHHHHHHHHHHHHÔHHÔHHHÔHHHHHHHHHÔHHHHHHHHHHHHHHHHÔHHHHÔÔHHHHHHHHHÔHHHÔHÔHHHHHHHHHHÔHHHHHHHHHHHÔH`ÔHÔHÔHÔHHHHHÔHHHHHÔÔÔÔHÔÔ`ìŠÔÔÔÔÔÔHHÔ2HÔHÔŸ2ŠÔìÔÔìŠÔ2ŠŸŠÔŠŠŸ
+J2ìHHxŠÔŠ`2ÔŠ``HHHHìH`ÖÔxìììÔÔÔHHHHHHÔHH`ÔÔHHÔŠHŠŠ`ÔxìHHHHHHHÔHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHHHHHÔHHHHÔHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHÔHHHHHÔÔÔÔÔÔHÔHÔÔÔHHHÔÔHŠÔÔ`ÔÔÔHxHììHÔ`ÔÔŠHÔŠHŠÔJŠÔÔÔ22`ìx`ŠŸìH`J2ŸJÔÔŠxÔìŸŠìx`ŠÔHH`Šì`ŠÔÔ`ŠHHH`ÔHHÔHHHHÔHÔHxHHHHHHHÔHHHÔHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHÔHÔHHHHÔÔŠHH`HÔÔÔHHÔÔHHH`ÔHHÔHÔìÔHÔÔŠxÔHHŠHŠ`ÔÔ`HÔHìŠÔŸ``JŠ`xŠ`x2ììŠ2x2x`ì`x`HHŠŠìŠìŸÔÔHH`ÔÔH`Ÿ`Ô``ÔÔÔÔHHHHHHHH`HHÔ`HÔ`HÔÔHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔHÔHHHHHHHHHHHHHHHHHHÔHÔHÔHHHHHHHHHHHHHHÔÔHHÔHHÔHHHHHHHÔHHHHHHHÔHHHHÔHÔHÔÔHÔHHHÔ`ÔÔ2ììxŠÔ`ÔÔÔHHÔÔŠŠHHÔHŠÔŠŸxŠ``Šì`Ÿxì``ŠÔŠHŠŠŠbìbÔŸìJ`ì`H`HÔ2`H`Ô`ÔHÔÔHìHŠ`ÔŠì`HÔÔÔÔHHHÔHHHÔHÔ`ÔHHH`ÔHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHÔHHHHHHHHH``HHHHÔHHHHHHHHHÔHÔÔHÔ``2`Ô`HÔHìHÔHHHHHHÔ2ìHÔÔ``ŠŸŠ`Šì`2ÔxììH2ŸJ``ŠHHHHìŠìŸšJìììÔ`HH2ÔÔ`2ŠÔÔÔHÔŠ`ÔÔÔÔHHÔHÔHHHHHxÔHHHÔÔHH`HHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHŠHHHÔHHHHÔHHÔHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔ``ÔHÔÔÔHHHHÔÔHHH`HŠÔì2ÔŠ`ìÔHHÔÔÔxŠHHÔ2Šì`ÔŠÔ`Š`HŠ2HÔšJšì`HH``x`xŸ
+ìŠx`HÔ`ŠÔŠŠÔHHHÔÔŠŠìŠ``2HHHHHHHÔHÔÔÔHHHÔÔHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHÔHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHÔHÔÔHÔHHHHHHHHHHHHHHHHHHHHHHÔHÔHHHHHHHHHHHHHHHHHHHHHÔHHHHHÔHHHHHÔÔHHŠHÔHÔHÔÔHHHHH`Ô2ÔìŠHÔHHHHÔÔÔÔÔìì`ìŠŠ`22Ÿ2ŠŠÖJŠìŸìŠ2`Ÿ`HHÔŸ`2x`Š22ÔŠ2ÔHÔŠ``Ô2Ôx`xŠ`Ô`Ô`Ô``ÔHHHHHÔHHHHHHHHHHÔHHHHHHHHÔHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHÔHHÔH`Ô`HÔHHHH`HHHHHÔHHÔÔÔŠHHìÔ``Ôì`H`ÔH``ÔŠ``ì2ì22x`Š22bxJbŠìŠJÖJìŠ`Š`x`x2ŠìŠÔHHÔ`ì`xìŠ2ÔHH`Ô`ÔŠì`x`ÔìÔHŠHÔHHHHHHHHHHHHH`HHHHHHHHHHHHHHHHHÔHHHHHHHHÔHHHHHHHHÔHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHÔHHHHHHÔHHHHHHHHHÔHHHHHHHHHHHHHHHÔHÔHHHHHHHHHÔHÔHHHÔÔÔÔHHHÔHHHÔH`H`Š`HŠ`HHŠH`ŠÔÔH`Ÿ2ìJ2`x`Ÿ2Šì`î
+zìŸ
+xbxìJìŠŠJJ`ììŠ`22JHÔìŠì`ÔŠ`HHìì```ìHŠÔHÔHÔHHHÔHHHHHÔHHHÔHHHHHHHHÔHHHHHHHHHHHHHÔH`HHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHÔHHHHHÔHHHHHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHÔHHHHHHHHHHH`ìÔÔHÔHÔHÔÔHHHHHHHÔŠH`HHÔÔHŠ`HHìHHÔH`ŠÔÔxÔÔx`ììŠ2ì`2ŠJìª
+ÀØbšš2xŸxŸ2`ŸÔŸìÔH`H2ÔÔŠÔÔŠÔìŠŠÔ``HHŠ`Ô`Ô`HHìÔHHHHHHHHÔHHÔHHHHHHHHHHHÔHHHHHHÔHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHÔHÔÔHHHHHHHHHHHHÔHHÔìÔÔÔHHHHHHHHHìÔÔHÔ`xÔÔŠ2`Š`ìHHH`HH`HÔ`ì`JÖÖŠŠ2ŠxìŸJxb
+
+J
+
+4Ö22Öx2Š2xJŸì2ì`ì`ŠHH2Ô2ì`ŠÔÔŠŠÔ`HHÔÔHÔ``Ô`ÔHHÔHÔHHHHHHHHHHHHÔHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHÔHHHHHHHÔHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHÔHHHHÔHHHHÔHŠHHHHìHHHHHHHHHHŠŠHHÔŠÔÔÔ``H``ŠÔŠHHŠìÔì`2xŸ2`ìxŸJÖìîÖ
+
+4
+
+z
+zîLîJÖxìxbxx`ÔHH`ÔŠŠ`2``Ôì`H`ÔÔÔ`ÔHH`HHHHHŠHÔHHHÔÔH`ÔŠÔHHHHÔHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHÔHHHHHÔÔÔHÔHHHHHHHHHÔHÔÔHÔHHHHHHHHHHHHÔxHHHÔHHÔHÔÔHHÔHÔÔìÔHHHHHHÔŠHŠHH`ÔHÔHŸ
+
+ÀJ`ìx
+JJŸbî
+À
+bîŸ
+îŸxJxŠîŸJìÔ`HÔH`Ÿì`xxx2ìÔŠì`ìHHHHHHÔH`ì`Ô`HHHHHŠ`ÔHÔHÔHHHHHHHH`ÔHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHHHÔHHHHHHHHHHHHHHHHHìHHÔÔHHHÔÔÔÔÔHHHHÔHHHHH`HÔHHÔHÔì`ÔxHHHÔìÔŠ`HÔ`ÔÔÔ`HÔHÔHŸ`ÔHì`ìJ2ìJ
+b
+ÀŸJ
+4
+4x
+hª
+42JJ
+zšŸ`J
+Öì2H`Ô`xxxb2Ö2`ÔHHŠŠHÔÔHHHÔÔH2ÔÔÔHHÔHHHH`HHHH`HHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHH`HHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHÔHHHHHHÔHHÔHHHHHHHÔH`ÔHHHHHHìHÔŠ2ìŠ`HHŠì2ŠH2`ÔŠHÔ`HHÔÔHÔHŠ`Ôì`Š2ìî
+zš
+4bb
+zJ
+bfP
+Üôª
+4šx`ì
+4Ö2`ÔÔHŠŠxJ2ì`ìÔŠŠŸ`ÔŠÔÔ`HŠHHHH`ÔH``ÔHÔHÔÔÔŠHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHÔHÔHHHHHHHHHHHHHHHHHHHHÔHHHÔHHÔHHHÔHHHHHHHHÔÔH`HÔÔHHHÔHHÔ2ÔÔ2ÔÔ`x2Ôì`ì`Š``ÔHHH`xHHÔ`Š```x2
+4šÖ
+zJÂ
+À8Úh~Ä¬®m®
+zš
+4ŠŠ`ì2x`ÔŠŠ`ìŠJŠJxxx``x2Ô`ìHÔHÔHHìÔHÔHÔHHÔHHHH`HHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔHHHHHHHH`HHHÔHHHÔÔHÔHHHHHHHHHÔHHHHHHHHHHÔHHHHHHÔHHHÔÔHÔìÔH`ÔììHÔÔxÔÔHHHH`ìÔHŠ`ìÔÔ``ìŸ2
+zL
+4b
+4
+JbdNÚöÈ+ÑA)°ÆjNLŸJŸì`ÔJHH`2ìŠ`b2`ìŠx``Š2ÔHHHÔÔÔì`2Ô`HHHÔH``2HHÔHHHHHHHHHHHHHHHHÔHHHHHHHHHHÔHHHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHÔHHHŠÔHHHHHHHHHHHHHHHÔHHHHHHHHHHHHÔHHHHHHHHHHHÔHHHÔHHHÔHHÔHÔÔH`xHÔ``ÔÔHHH`HÔÔH``ŠHÔÔÔxÔŠÔ2HÔÔHÔÔ`2Ôx222`ŠììŸ
+ðdbbLd6N"¢w¥À¡_¢1«ÄŠEôòNšììŠŠÔŸÔHÔŸ2ìxŸxJx`ŠJŸÔÔÔÔÔHHHÔ`ÔH``ì`HHHÔHHŠŠÔHHHHHHHHÔ`HHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHÔHHHHHHHHÔHHHHÔHHHÔHHHHHHÔHHHHHÔHÔHHHHHHHHHHHHHHHHHHHHHHHÔÔÔHHÔHHHH`ÔÔHHHHHHH`HÔÔìHÔHHÔ`2Ôìì`ŠŠHHH`Ô```ŠHìxxŸ`ŠììJìŠ2š6šÚÂ
+4LÄUo °°Ž>ŠE§
+¯Þ³òŠÔÔÔ2ÔŠŠxìÔ`ìŠìxŸ
+2JìxìÔ2ŠìHÔHìHìŸHÔHHHHHHHHÔHHHÔÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHÔHÔHHÔHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHH``ÔÔHHÔHHHÔŠHH`HÔÔÔì``ìÔÔÔH`ÔÔ`HÔ`Š`2`xxšîP
+À|ÄNUo¢wÎÆ,Úþ¹q¡£Ad|šŠ2ì2ŠŠì`Ô`ŸŸÖ
+zJ`ŠŠH`ŠŠÔ2ÔHHHHHŠ``xÔŸÔHHHÔ`ÔÔHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHìHHÔHHHHÔHHHHHÔHHÔHHHHHHHÔHÔHHHHHHHHHÔHHHHHHHH`ÔÔÔHÔÔÔHHHŠÔÔÔ`ÔÔHHÔŠH`ì`HÔHÔHÔÔÔŸŠÔÔŠÔHH`x2222ŸJÖŸb
+zN¬|ûs€bå3þs$áës)Wf
+2JŠ2xìŠìì`HŠŠxxxì2ŠŠ`Ô`Š2ŠÔÔHHHH2HHHHHHHHÔ2ÔÔHìHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHÔHHHHHHÔHHHHHHÔHHHHHH`HÔŠH`HHÔHÔH`HÔÔ`H`ŠHÔ`HÔH`HŠÔÔŠÔŠ`ŸÔÔÔxb
+z
+4îb
+4
+4ÖLÄ~š|§
+Ÿé
+ sÒ¢1ç"
+~dÖ
+ÀxxìxÔ2ì2ŠÖxx2JŠ2Ö`ŠŠŠì`ŠÔÔÔHHHHÔ``ÔHÔÔH`HHÔÔHHHÔHÔHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHHHHHHHHH`HHHHHHHHHHHHHHHHÔHHHHHHHHÔHHHHHHHHÔÔÔŠHÔHHÔHÔÔHHÔHHHÔŠHÔHHÔH``Š`ŠÔŠÔÔHŠÔÔHH`ÔHŸÔ`x22ŸJxŸ
+zªØ
+z
+4ìbÂÄá Ó¬Üª »Á¥ž¿»®8Æ¬Ö
+
+Jì2Ÿì2bxÖxŠbìx`ŠÔ`ÔÔHHÔìHÔÔÔHHÔHHHHHÔHHHHÔÔ`HÔHÔHHHHHÔHHÔHHÔHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHŠHHHHHHHÔÔHHHHHHHHHHHHHHÔHHHHHHHHÔHHHHHHHHHHHÔH`ÔHHHÔHÔHÔHHHŠHHHHÔ``Ô``ÔŠìŠ`ŠÔÔH`HHHH`Ô`H`Ô222``ŠìŠÔ
+î
+À
+4
+îª "o€šŠ±<³øœÅ3±ÈÞ
+šÖììŠìŸHHìììJ2xxxìxìÔÔŠÔ`ÔŠÔHHHHH`HÔHHHÔHHHHHHHHÔHHHHHÔHÔHHHHÔÔHHHHHHHÔÔHHÔHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHÔHÔHHÔÔHHH`HHHHHHÔHHHHHHHHHHHHHHHHHÔHHHHÔÔÔHHHŠHHHHHHÔÔHÔÔÔŠÔH`ÔHHHÔÔììH`ÔHÔHŠŠHH2HÔH2`Ô`ŠììÖJššš
+4bÖ
+òÜ"Æjý¥4£Õ¥z/ÍWØ
+b2Ö`x`x2``ÖxìÖŠ222ÔŸŸŠŠì2ŠÔHHÔìHÔHHHÔHH`HHH`ÔHHHH`HHHÔHHHHHHHÔÔHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHŠHHHHHHHHHÔHHHHHHÔHHHHHHÔHHHHHHÔHHHHHHÔHHHHHHH`HHHHHHHHHHÔHHHHHHHHHÔHHHHHHÔH`HÔŠì2ÔÔHHHHìÔŠŠŠx`J22J2Š2JŸÖxJ
+ÀLîØ6ðLùYm¬îšJ2ì``JJÔÔ2xxx
+`ŠŠHÔHHÔHxì`HHÔHHÔÔÔHHÔHHHÔHÔÔÔHÔHÔHHHÔÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHÔÔÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔHÔHHHHHHH`HHHHŠHHÔHÔHHHHHHHHÔÔHHHHÔììHHHH`ÔHHŸxŠÔŠŠ2xxŸ2
+ÀÖxLJî
+z
+ÀØPUÆ6Nðxììxì`HxììŠx`ŠÔ`ìÔ`Š`Š2`ÔHHÔÔHHÔHHÔÔHHHÔH`Ô`HÔHHHHÔHÔHÔHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHÔHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHÔHHÔÔÔHHHHHÔHHHHHÔHHÔÔHÔHÔ`HìÔìÔ``ìŠ`ÔH`ÔÔHHH`ÔÔÔ`ÔHŸŸ`JŸJÔŠ``ÖÖÂØxJJJ2Š2ŸÖî  
+bŸìŠ2x2b``ì`ÔÔ```Ô`Ô2ÔììxÔÔ``HHŠHHHHHHHHÔŠÔÔHÔHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔHHHÔÔHHHHHÔHHHHHHHHHHH`HHHHHHHHHHHHHHHÔHHHHHHHHHHHHÔHHÔHHHÔHHHHHHHÔHHHHHHHHHÔHHHÔHHÔHHHHÔÔÔH`ÔŠÔÔHŠHÔÔHHŠÔ`ìÔ2xŸ`ìÔ`xx`ŸbxxìbÖìÖbÖ
+4b
+zd
+4Ÿ
+4`bŸ
+
+4JJÔ`Ô`22ììx`ŠŠ`ŠÔ2ÔììÔŠÔH`2``HÔHHHH``ÔÔHH```HHHHÔHHHÔHÔHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHÔHHHHÔHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHÔHÔÔHHHÔHÔHHÔŠHÔHÔHÔHHìHHŠÔÔ`Šì`Ô2`ŠÔHÔŠì`ŸÔx`ìŠxì`ŠHìì2ŸJŸ`2ì2ìJîJÖ2
+zŸŸ
+JŸxì`Š``ì``ÔÔHÔŠ`ÔÔ`ìŠÔŠ`Ô`HÔHHÔHHHH`HHŠ`ŠŠÔHÔHÔHÔHHÔÔHHHÔHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHÔÔHHHHHHHHHHHHHHHHHHHHÔHHHHÔHHHHHÔHHHHHHHHÔHHHHHHHHHHHHHHHHHÔHHHHŠHÔHHÔÔHHHHHHÔÔ2ÔxŸÔ`ŠŸ`ìŸŠÔHŠìÔHÔÔÔŠÔ`Šx2xx2Ôx`x2Šxx2J2bŸ`ìŠ
+ŸJJÖxJxŠxÖŠ`Ô2Š2J`ŠŠŠ2`Ô`HHHHÔÔÔ2ÔÔHÔÔìxŠÔÔHHÔÔHHHHHÔ`ÔÔìÔÔÔÔHÔÔÔHHHHÔ`HHHHHHHHÔÔHHHHHHHHHHHHHHHÔHHHHHÔHHHHHHHÔHHHH`HHHHHHHHHHÔHHHHHHHHHHHHHHHHÔHHÔHÔHHHHHÔHHÔHÔHHÔHÔHHHHHHÔŠHHHHÔ`ŠHÔÔ`HÔÔÔHHHŠì2Š``ÔÔŠìÔÔHHÔÔ``ìHÔ`ìÔŸxŠ2ŠŠŸ22`îb2LJb
+Àì2ŸJ
+
+Ö2Šì2Ô``x2ŠŸHì```HHÔÔ2`HÔHÔÔHÔŠHŠÔÔHH`HHHÔŠ22ÔŸŸxÔ2`ÔHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔ`HÔHHHHHHHHHHHHHHHHHHHHHHHHHÔHÔHHHHHHHÔHÔHHHHHÔHHHHHHHHHHHHÔHHHHHHHÔHHHHHÔÔÔHÔ`Ô```ÔHìŠŠÔHÔÔHH`Šì`2`2ÔHHHHŠHH2Ô`Š`ì``xŸÔìÔÔx`ŸŸÔì2b2Ö2š
+zŸ`2xÔ22ŸÔŠ2``2`Ô2`Š`HHÔHÔÔÔŠHHHHÔ2Ô`HHHÔÔH`ÔìxxŠÔ`HÔÔHHHHHHÔHÔHHHHÔHHÔHHÔHHHHHHHHÔHHÔHHHHHHHHHHÔHHHÔHHHHHHHÔHHÔHHHHHHHHÔHHH`HHHHHHHÔHHÔHHHHHHHHHHHHHHHHHHHHÔHHHŠHHÔ`ÔHHÔ`HÔŠ`ÔÔ`HHÔHŠÔ`xÔì22ì2ÔÔHŠÔ``HHx2ìŠ`2xŸHÔÔìŠÔ`Ô`ìJxÔŸŸ`
+bbÖ2xŠŠÔxÔ``ìì`HŸìÔÔŸÔÔÔHH``HÔHÔHÔŠŠHŠHHHÔHHHHHÔHÔ2`Ô`ìHìŠÔHHHHHHHHÔHHÔ`HHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHÔHHHHHÔHHHHHHÔHHHHHHHHHHHHHHHHHŠHÔÔHHHÔÔÔÔÔHÔHHÔHŠŠŠŠŠHì``ìì`HHÔÔ```Ô`Ô2H```ŸÔì`Š`xŠ`HÔŸ`Ÿ2
+z
+zÖ2ÖšxìŠ`xŠŠ2xÔÔŸH``Š`2ÔÔÔHÔHHHHÔH`xÔŠH`HHHHHHHÔ``ì`ŠHHHHHÔÔHHHHHHHHHHHHÔHHHHHHHÔHHÔHHHHHHHHHHHHHHHHÔHÔHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHÔHHHHHHHHHHÔHHHHHHHHHÔÔHHÔHÔ`HÔHHHŠìHHÔH`HÔHÔìÔ`xììŸÔì``HHÔÔÔÔÔÔ`Hxx
+ŠxxŠÔxŠÔ`2
+ŠŸxŠ```Š````ÔŸ2ŠŠÔìH`ÔHÔHHHŠÔÔHÔÔHHHÔHHÔHÔHH`ŠÔHÔHHHHHÔHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHÔHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHÔHHHHHHHHHHHÔÔHHHHHHHHHHÔHHHHHHÔHÔÔŠHÔHHHÔŠHHHHÔHÔì2``ÔŠ`ÔŸ`2`HŠìÔÔHÔÔ`HŠ`ŠxJÖ2ìx`Šx``Š2bb
+ÀŠ`JJŸ`ì2``ÔŠŠÔÔì`ìŸŠÔHHHHÔHHH`ÔHHÔÔHHHHÔHHHHììÔìHŠ`HHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHÔHÔHHHHHHHHHHHHÔHHHHÔHHHHÔHHÔÔHÔH`ÔHÔ`HÔHŠÔÔHÔH`HŠ2Ô`ìÔ`Ô``ÔH``ŠÔ``HHÔHÔÔH``ÔHHÔŠ`ÔJ2`xìŠxìÔìÔ`x`JxŸŠ2ì2Ô`H`2HìÔ`x``ŠŠÔŠŸ`ŠHÔÔÔHÔŠHÔÔÔÔHHHHHÔHH`ÔÔÔHÔHHHÔHHHHHHHHÔHÔÔHHHHHHHHÔHHHHHHHÔHHÔHHH`HHHHHHHHHHHÔHHHHHHHHHHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHÔHHHHHÔHHHHHÔHHHHÔŠÔHHHHŠ`ŠÔH``ÔÔÔ`ÔH`Ô`ŸÔH`Š`ŠììHì22H``ÔìÔHì2ŠŸÖ`Š`ÔŠŠx`2ŠìììÔ`2ÔŠŠŸìì`ŠÔŠHHÔÔHÔÔÔÔÔ`ÔŠHHÔHHHHHHìŠ`HHÔHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHÔHHHHH`HHHHHHÔHHÔHHHHHHHÔHHHHHHHHHÔHHHHHÔHHHHÔHHHHHHHHÔHHHÔHHÔÔHHÔHÔHHÔHŠH2ŠŠHÔÔH`H`ŠHHÔxÔHÔHHÔHÔ`Š2ìŠÔÔ2ìŸ2ÔÔ
+ÔHÔ2`HÔìÔìJxŠH`HH`ÔHHHH`ÔÔÔHÔHÔHHHÔÔÔìH`ÔŠÔŠŠŠHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHÔÔHÔŠ`HHHHÔHHHHŠHŠHÔÔÔÔ``Ô`2HÔHÔH`H`ÔìH`ÔììÔÔÔŠ2ÔìHÔìì`xÔHx2xÔÖŠÔÔHHìÔ````ÔHÔŠŠ`HHHH``HÔHHHÔÔHHHHHH`Ô`Š2HHÔŠHHHHHHHÔHHHHHHHHHÔHHÔHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHH`HHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHÔHH`HÔÔHÔìHHHHÔHHHHÔŠÔÔÔŠŠ``HHÔ`ÔŠ`ÔHHxŠìÔÔÔHŠ``Š``ÔÔ``HÔÔìŠŠŠ22ŸŠÔHÔHŠìŠHÔHÔHHHÔÔH`ÔHÔH`ÔHHHHHHHHŠ`ÔŠ`Ô`ŠHÔHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH`HHHHHHHHHHHHHHHHÔÔHHHHHHHHHHHHHHHHÔHHHHHÔHHHHHHHHÔ``HÔHÔHHHHÔÔHÔHHHHÔHHÔÔŠ`2Š`Š`ÔìÔHÔÔH`ÔÔÔHÔ``ÔŠ`H2JŠ2xì``2ŠìÔŠHÔ2`ÔÔ2ìx22Š2HŠÔ`Ô`H`HHìÔŠÔÔHHHHHHHH`H`2HHHHHHÔHHHHHHHHHHHHÔHÔHHHHHÔHHHÔÔHHÔHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHÔHÔHÔHHHHHHHHHÔÔHHHHHÔÔHŠ`HHÔHHHÔHHÔHÔÔÔHHÔHÔÔ`ŠìÔŠxŠHH`HHŠ`ÔÔŠŠŠÔHÔ`ÔÔ`ŠHÔHH````ìJ2`ì2ìŠ`ÔH`ÔÔHHHHHHÔHHÔHÔHHHHHÔÔ2Ô`xìHHHHHHHHÔHHHHHHHHH`ÔHÔHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHÔÔHÔHÔHHHHHHHHHHHHÔHHHHHHHHHHÔÔHHHHHHÔHH`ÔHHÔÔHHHHHH`ÔHÔÔìHŠÔÔ`ìÔ`ÔÔHÔHHŠÔHHHÔìÔ2HHH``x`ŠÔì`2Š2ì```Š2ÔHHÔHÔHHÔHHÔÔHHHHHHÔŠŠHìHHHHHHÔHHHHÔHHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHHÔHHHHHHHÔHHHÔHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔHHHÔÔHHHHÔHHH`HÔÔHHHÔHHÔÔ`ÔÔìŠ`H````HHÔHÔŠÔ`ÔHÔHHHÔŸÔ`xì`HÔ`ÔÔHŠ2ŠŠ`ÔÔJìÔ2ÔÔÔ`Š``Ô2ì```ÔHHÔÔHHHÔ`HHŠHHHHHHHHHÔHHŠÔìHHHÔHHÔHHÔÔHHHHÔHHHHHHHHHÔHHHHHHHHHHHHHÔHHHÔHHHÔHHÔHHHHH`HHHHHHHHHHHHHHHÔHHHÔHHHÔHHHHHHHHÔHÔHHÔHHHHHHÔH`ÔÔHHÔÔÔÔHHHHÔŠÔÔÔÔHìÔ`ŠÔH2ŠŠH`ÔÔ`Ô`ÔHH`H`ÔHHHÔÔ````ì``ÔHÔ`Šì`2xÔ`Š``ì`ìÔ`HÔHHHHŠÔÔŠHHHHHHHHHHÔH`ÔŠÔ`HHHÔHÔHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHÔHHHHHHHHHHHHHHHHHHÔHHHHHHHÔHHHHHHÔHÔŠÔŠÔÔŠHHÔHÔHÔHÔHHÔÔÔÔŠÔHÔ`ÔìHHÔÔÔHHHÔHÔÔÔÔHÔ`H``HÔÔÔÔŠxHÔì````ÔÔÔŠH`H`ÔÔŠ`ÔÔÔÔÔ`HHHHÔHÔHHÔHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHÔÔHHHHÔHHHHHHHHÔHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHÔH`HHHHHHHHHHHÔHHÔHHÔHHHHÔHÔÔHÔÔHHÔHÔHÔìÔÔ``Ô`ÔH`Ô`HHHH`HHHHHÔÔ`ì`ì2ÔÔÔÔìŸJŸì`ŠŠ`ÔÔÔ`HŸH2`HHHHHHHHHì`HH`HHHHÔHHHÔÔHÔHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHÔHHHHHHHHHHHHHHHHHÔHHHHHHHHHÔHHÔHHHHHÔHHHHHHÔHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHÔHHHÔHHÔHÔHÔÔHÔÔìÔÔHHHŠ`HÔHÔÔHHŠŠŠÔ2H`ÔÔÔÔHÔHHHÔHHH```ÔìÔìŠ22ÔÔ2`2HÔÔÔÔÔ`ÔÔHHHHŠ``ìÔÔHHÔìHÔHHÔHHHHHHHH`HHHÔHHHÔHHÔHHHÔHÔHHHHHHHHHHHHHHHÔHHHHHHÔÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHÔÔHHHHHHHHHHHHHHÔHHHHH`HHHHHHHÔHÔHÔÔHHHÔÔÔŠÔ`ŠHH`ÔÔÔŠ````HÔH`ÔHHŠÔ`HÔÔHÔ`HH`HxHÔHHÔÔŠ2``2Ô`ÔÔÔxìŠHÔÔÔÔHx2Ô``ìHHHÔHHHHHHÔH`ÔHHH``ììHHHHHHHHHHHHHHHHHÔHHHHHH`HHHHHÔHHHHHHHHHHHHHHÔHHHH`ÔHHHÔÔHHHHHHHHHHHHÔHÔHÔHHHHHHHHHHHHÔHHHHHHHÔÔÔHHHHHHHÔÔHHHHHÔHHHŠHŠHHÔŠŠHHHÔHŠ`ÔÔÔÔHHHÔHÔÔÔHÔHHÔŠH`ÔÔHHH`ÔÔÔ2Š2HxìŠì``ÔHÔHŠ`Š```2`ÔÔHHÔÔHÔHHÔÔHHHHÔHÔÔ`HÔHHHÔHHHHÔHHHHHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHH`HHÔH`H`HÔHÔHÔÔHH`ÔŠ`ÔHì``ŠHŠxÔ`ÔŠHÔÔÔŠŠHHÔŠHHÔÔ`Š`Ôx2ÔHHHHxìì`Hì2`ÔŠHÔÔÔŠHŠHHÔHHÔHHHHHHHH``HÔHHHÔÔHHHÔHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHÔHHHHHHHHHÔHHHHHHHHHHHH`HHÔHHHHHHHHHHHHHHHHHHHHHHÔ`HÔHÔHH`HHH`HHHÔÔHHìHÔÔ`Ô`ìHŠŠŠÔ`ŠHŠHHHì``Š`ÔÔ2xìŠÔÔ2``ì```ÔÔÔŠ`ŠHÔH`2ÔxŸŠÔHÔHHHHÔHHHHHHHÔHHHHŠ````ŠÔHHHHHHHHHHÔHHHHHHHHHHÔHHHHÔHHHHHHHÔHHHHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHHÔHHHHHHHÔHÔHHHHHHHHHÔHHHHHÔHHHHHÔÔHHìHHÔHÔHÔHHHHÔŠÔŠÔHHHÔ`ŠÔ``ììHHHHÔÔÔ`HH22`ìÔ``ÔHŸx`HÔ`ÔìÔŠŠ`ŠHHÔÔÔHÔÔHŠìì2ÔÔÔÔHÔÔHHHÔÔHHHHHHÔH`H`ŠÔ`HHÔHHÔHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHH`HHHÔHHHHHHHHHÔÔŠHìxÔHHHHHÔH`HHHHHÔì`HHÔÔÔHÔÔÔxìŠìŠŠ``HHÔŸxÔŠ2ì`2xÔìŠ`ÔÔ``ì`ÔŠHŠHHÔHHŠìÔŠÔ````Ô`HÔHÔÔHHHHHÔHÔHHHHÔH`ÔHHHÔHHÔHHHÔHHHHHHÔHHHÔHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHÔÔÔHHHHHHHHHHÔHHHHHHHHÔHÔH2HHÔÔÔ`ÔÔHHHÔHHHHHHÔHH`HŠ`Ô2HìÔÔ`H`ÔHÔHHÔŠ``ŸxxŠŠìJxŠH`ÔŠHÔ`Ô`HììÔHÔHÔHHÔHÔÔ`x`ÔŠì`HHHHHHHŠHHHHHHHÔH`HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHÔHŠHHHHÔHHHHHHHHHÔHHHHHHHHHHHÔHHÔÔÔ`Ô``HÔÔHHHÔHHHHHHHÔHHÔHHH`HHŠìÖŠŠHŠìÔŠHÔ```ŸŠ``ì2ÔÔÔ`ÔŠH2Ô`Ô`ÔÔ`ÔHÔH`H`ŠŸìŠ`ÔHHHHHHÔHÔHHHHHHÔHHHìŠHHÔHHÔHHHÔHHHHHHHHÔHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHÔHHÔHHHH`ÔHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔHHHHHHHÔHHHHHHHHHHÔÔÔÔHÔHÔH`HHHHHÔÔHHÔHHÔHHHŠŸx2xÔŠxŠ`HHÔìÔHÔH```H`ŠH`ŠŠŠ``ÔHHÔŠŠÔH``ŸììŠÔÔHHÔHHHÔHHHHÔHHÔÔHHÔÔHÔHHHHÔHHHHHHHHHHHHÔHHHHÔHHHHHHHHHHHÔHHHH`HHHHHHHHHHHHHHÔHHÔHHHHŠHH`HHÔHHHHHHHHHHHHHHHÔHHHHHHÔÔHHHHHHHHHHHHHÔHHÔŠÔ`HHHÔŠHHHÔHHHH`HÔ`ÔììŠ`2ÔÔŠì`ÔÔHÔHÔ`ŠÔìx``ÔH`ÔHÔŠ`H`HHÔ2ÔHHÔÔ`ŠÔ`ÔxŠìÔŠ```ÔHHHH`HÔHH`HÔHHHHHHHÔHHHHHHHHHHÔÔHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHÔHHHHÔÔHHHHH`HHHHÔHHHÔHHHÔHÔHHHHHHHHHHHHHHHÔHHHHHÔH``ÔHHHHHHHÔHHÔHÔÔ`HŠŸìŠŠìxŠHÔÔÔÔH`ÔÔÔŠÔŠ2HŠ`Š`HHHÔHÔ`HÔÔHHÔHHÔÔììÔ`ÔÔÔ2
+Ôì`ìŠŸHHÔÔHHHHHÔHÔÔHHÔHHÔHHHHHHHHÔHHHHHÔHÔHHHÔHHHHHHHHHHHHHÔÔHHHHHHHHHHHHHHHHŠHHÔHHHHHHHHHHHHHHHHHHHÔHHHÔHHHHÔHHHÔHHHHHHHHHHÔHHHHHHÔHHHHÔHHÔÔHHHHÔHHHÔHHHÔ``ÔÔŠÔ2H`Ô`ÔŠHÔŠÔìHÔÔÔ`ÔÔHHÔ`ÔÔÔH`Ô`H`xìÔHŠŠŠ`Š`ÔHÔHHHH`HÔÔHŠHÔHHHH2ÔHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHÔHHHHHHH2HHHHHHHŠHHHHHHHHHHHHHHHÔHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHÔÔÔÔHHHHHHHHHHHHÔÔH`H```2``HìHÔ`J`ŠÔHÔHÔÔ`ÔŠ`H`HÔŠHHHHÔÔÔ`HÔÔx`ìxÔH`Ô2`ŠìÔ`HHHHHHHÔHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHÔHHHHÔHHHHÔÔHHHHHHHŠHHHHÔHÔÔÔHìÔÔÔHHÔHHH`HHÔHÔH`ÔÔ`ì`ŠÔHÔ`ÔÔH`ÔìŠ`ŠÔ`ŠÔHÔÔHHHŠÔìHHxHÔ2ìÔìì``HHÔÔHÔHÔHHHŠHHÔÔÔHHHHHÔ`HHHHHHHHÔHHHHHHÔHÔHHHHHHHHHHHHHHHHHÔHHŠHÔÔHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHH`HHHHHHHHHÔHHHHHHHHHìÔHHHÔŠÔHHŠHHHHÔÔÔHH`HHì`ìŠ`ÔìÔŠHHHÔÔHÔÔÔHH`HH`HÔH`HÔÔÔH`ÔHHŠÔ```H2HÔìÔì`Ôì`ìŠÔHÔHHHHHHHÔHH`HHHÔHÔHHHHHHHHHHHÔÔHHHHHHHHÔÔHHHHHHÔHHHHHÔHHHHHHÔHHHHHHHÔHHHHHHHHÔHHÔHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔÔ`HHHHHHÔÔHHHH``ÔHHÔÔHÔ``HHHHHHHÔìÔ`ÔHÔÔŠÔ`Šx`2ÔÔÔÔ`HH`H`xŠÔÔìì`HHÔÔHHHHHHHHHÔÔHHHHÔHHHHHHHÔÔÔHH`HÔHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHÔHÔHHHHHHHHHHHHHHHHHÔÔHHHHÔHHHHHHÔHÔHHHHÔHŠ`ÔŠHHHHÔÔ2H`2ŠŠŠÔHÔ``ÔÔ`Ô`ÔÔÔ2ÔÔìÔŠHŠHŠHÔHÔÔHHHHHHHHHÔÔHHHHHHÔHHH`HHHÔHHHHHHHHHHHÔHHHHHHÔHHHHHHHHHHHHHÔHHHHÔHHHHHÔHHHHHHHHHHHHÔÔHHHHÔHÔHHHÔHHHHHHHHÔHHHHHHHHHHHHHHHÔ`HHÔHHÔÔHHŠHŠÔHÔÔŠHÔÔHÔÔH2`Ôì``2``HHHHÔÔŠŠÔŠÔÔÔ`ŸìŠŠŸÔÔ`ÔŠ```ÔÔHHHHÔÔHHÔHÔHHHÔHÔHHÔÔHHHÔHHHHHHHHÔHÔ`HHHÔHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHÔÔHHHHÔH2HHHHÔHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔH`ÔHH`ÔÔHHHÔHHÔÔÔH`ÔÔÔìHHÔ`ŠìŠŠŠÔ2ŠŠHìÔHÔHH`HŠÔÔ``Ÿ2`Šì2Š`ÔHHÔìÔHHHÔHHÔHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHÔHHHHHHHHHHHÔHHHHHHÔHÔHHHHHHHHHHHHHHH`ÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHÔ`H`ÔHHHHHÔHHÔHHÔÔHHHHÔHHHÔHHHHHHHÔHHŠ`Š`Š2ŠŠHÔŠÔ`H22J`Ô`HÔH`HHHHHHHHHHÔHHHHHÔHÔHHHHHHHHHHÔHÔHHHÔHHHHHHHHHHHHHHHHHHHHHHÔHHHHÔHH`HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHÔHHHHHÔHHHHHÔHHHHÔHHHÔÔHHHÔHHÔHÔHHHÔHHHHì`HÔHHHHHÔHHÔH`ÔÔìÔHŠ`HxÔ`ÔHÔÔÔìŠŸ2ìÔx`Ô`ÔÔÔÔHÔÔHHHHHHHÔHÔ`HÔHÔHHÔÔHHHHHHHHHHHHHHHHÔHHHHHHHÔHHHHHHHÔHHHHHHHÔHHHHHÔHHHHHHHÔHHHHÔHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔÔÔHHHHHHHHHÔHÔ`2ÔHHHÔHHHHHHHÔìHÔÔHHHHÔHHHHHH`ÔÔŠÔìÔ`ìŠÔŠH`HHHHÔŸ2HÔÔÔHÔÔ`Š22HHHHHHHHHHHHHHÔHHHHÔHHHŠHHHHHHÔHHHHHHHHHÔHHHHHHHÔHHHHHHHHHHHÔHHHHHHHHHHHÔHHHHHHÔHHÔHHHHHHÔHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHÔHHHHHHÔ`ÔHÔHÔHHHÔHHHÔHHHHHHHHHÔÔ`ŠìÔHHìH`ÔÔ``ÔŠŠŸ`Ô`HHHHHHìHÔHHHHÔHHHÔHHÔH`ÔHHHHHHHHÔHHHHHHHHHÔHHHHHHHHÔHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHÔHHHHHHHÔHHHHHHHHHHHHHHHHHHÔHÔHHHHHHÔHHHHHHHHÔHÔHŠHHHHHHHHÔHHÔHÔHŠÔŠÔHHÔÔH`HÔ`H2Š`xH`HHHHHHHHÔHHHHHHHÔÔÔÔÔÔÔHÔHHÔHHHHHHÔHHÔHHHHHHHÔHHHHHHHHHHHHHHHÔHHHHHHHÔHHÔHHHHHHHHHHHHHHHÔHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHH`ÔÔHHHÔÔHHHÔÔÔ`ÔÔHHHHHÔHHÔHH`HÔŠ`ÔÔHHHŠÔHHÔŠìÔH``HÔÔHHHÔHHHÔÔŠŠHHHHHHHHHÔÔHÔHHHHHHHHHHHHHHHHHHHHHHHHHH`HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHÔHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHÔÔÔÔ`HHŠÔH`ÔHÔÔHHÔHHHÔHÔÔHÔHHÔÔJìÔHHÔHÔìÔHHÔ`ÔÔìÔÔHHHHHHHHHÔÔÔHHHHHHHHHHÔHHHHÔHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHÔHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHŠÔÔÔ`HHHHHÔH`HHHHHHHÔHH`ÔŠÔÔ`HÔ`HHÔÔ`HÔ`HHHÔÔÔÔÔHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHÔHHHHHH`HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHÔHHHHHÔHHHHHHHHHHHÔHHHHHHHHHHHHHHÔHHÔ`ŠHHÔHHÔ2HHÔHHHÔÔHH2H`ŠHÔ`ÔÔHH`HH`ÔÔHŠÔHHHHÔHHÔHHHHHHHHÔHHÔHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔŠHHHHHHHHHHÔHHHHHHÔHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHÔÔHHÔ`ÔŠHŠÔHŠHHÔHÔÔHìHHHHÔHH`HHHHÔÔÔHHÔHÔÔÔHHÔHÔÔHÔH`ÔH`HÔHHHHHÔHHHHÔHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHŸHHHHÔHHHHHHHHHHÔHHHHHHÔHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHÔHÔHHHHŠHÔHÔŠ`ÔÔHHHÔÔHHHÔHHÔÔHHHÔHÔHÔHHHÔHHHHHÔHÔHHHHHHHHHH`HHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHŸHHHHHHHÔHHHHHÔHHÔHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHìHÔÔÔÔHHHHH`HHHHHHHHHHHHHÔHHÔÔHHHÔHHHÔHHHHHÔHHHHHHHHHHHÔHÔHHHHHHHHHHHHHHHÔHHHHHHHH`HHHHHHHHHHÔÔHHHHHHÔHHHHHÔÔHHHHÔHHHÔHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHÔHHHHHÔHÔHHHHÔÔŠHÔÔ``HHÔHHHÔÔÔH`HìH`ÔHHÔHÔHÔHÔHÔHHHH`HŠH`HHÔHHHÔHÔHHHÔHHÔHHHHÔŠHHÔHÔÔHHÔHHHHHHHHHÔHÔHHHHÔHHHHHÔHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHxHHHHHHHHHHÔHÔHHHHHHHHHHHHHÔHHHHÔHHHHHHHHHHHHHHHHHHÔHHH`HŠHHHHHH`ÔìHHHHÔHHHHHHÔHÔÔÔÔÔÔHÔHHHÔÔÔÔHHÔHHHHHHHHHÔHÔÔHHHHÔÔHHHÔ`ÔÔHHHHHÔÔHHHHHÔHÔHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHÔHHHH`HHHHHHHHÔHHÔHHHHÔHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHÔHHHHHHHHÔHHÔHHHHHÔHHHÔÔÔHÔHÔHHHÔ`H`HÔHÔHHÔHHÔHÔHHÔHÔHHHHHHHÔHHÔHÔHÔHHÔHHHHHHHÔ`ÔHHÔHHHHHHHÔHHHHHHHÔ`HHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHÔÔHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHÔÔHÔHHHÔHÔHHHHHHHHHHHHHHHHHHHHÔ`HHÔ`ÔH`ÔŠÔÔÔHHHHHÔÔÔHHHHHHHHHÔŠÔHHHHHÔHÔHHHHHHHHHHHHHHÔHÔHHHHHÔÔHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHÔHHHHHHHHHHH2HHHÔHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHH`HH`HHÔHHHHÔHH``HHHHÔŠHÔHHHHÔHÔHÔHHHHÔÔHH`ÔÔHHHÔHH``ÔHÔÔHÔHÔ2HÔHÔÔÔHHHHÔHHHHÔHHHHHHÔHHHHHÔHHHHHHHHHHHHHHHHHHHHHÔHHHHÔHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHHÔHHHHHÔHHHHHHHHHHHÔHHHHHHHHHHÔÔÔÔÔÔHHÔHHŠÔÔ`HHÔHHHHÔÔHHÔHHHHHHHŠHÔÔHÔHHÔÔÔHÔHHHÔHHHHHHHÔHÔHÔÔHHHHHÔHHHHHHÔHHÔHHHHHHHHHHHHHHHHHHHHHHHÔHÔHHHÔHHHHHHHHHHHHHHÔHHHHH`HHHHHHHÔHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHÔHHHHÔHÔHÔÔÔHÔHHHHHHÔH`ÔHHHHH2ÔÔÔHŠHHÔ`ÔHHHÔÔìHìHÔHHÔHHHHHHÔHHHHÔHÔHHHHH`HHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHH`ÔHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHÔ`HHHHHHHHHHHHHHHHHHHHÔHHHÔHHHÔŠHHHHÔHHHHHÔÔHÔ``HHH`HHÔHÔHÔHÔ`HŠHÔÔÔHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHÔÔÔHHHHHHHÔHÔHHHHHHHHHHHÔHÔHHHHHH`HHHHHHHHHHHHHHHHHÔHÔHHHÔHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHÔHÔHHH`HHÔHHÔHHÔÔHÔÔÔÔ``HHHHÔHHHHHHHÔHÔHHŠHÔÔHHHHÔHHìHÔÔ`ÔÔHÔŠÔHHHÔHHHHÔHHHHÔHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHH`HHHHHHHHHHHHHHÔHHHHÔHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHÔHHHHÔHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHÔÔÔÔHHHHHHHHHHÔHHHÔHH`HHHHÔŠÔÔHHHHHHHHHHÔH`2HìHÔHHHÔÔHHHÔÔÔHHÔÔÔHHHHHHHHÔHÔHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHÔHHHHÔHHHHHHHHHHHHHÔHHHHHHHHÔHHHHHHÔHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHÔHHÔHHÔHHH`ìÔHHÔHHHHHHHHHÔÔHHHHHHHÔìH2ÔHŠHHÔHHìHHÔHHHHÔHÔÔÔHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHÔHHHHHHHÔHHHHHHHHHHHÔHÔHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHÔHHHHHHHHHHHÔHHHHHHHHHHHHHHHHÔHHÔHHÔÔÔÔHÔHHHHHHÔHHHHHHHÔHÔHHì`HìHHÔHHÔHÔHÔH`HÔHHÔHHÔHHÔHHHHHHHHHÔÔHHHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHÔHÔÔHHHHHHHHHHHHHHHHHHHHHÔÔHHHHHÔHHHÔHÔHHHHÔHHHHHHÔHÔHHHHÔÔHHHHHÔHHÔ2ÔHH``Š`ÔŠHHÔHHHÔHHHHÔHHHHH`HHÔHHHHHHHHHHHÔHÔHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHÔHÔHHHHHÔÔHHHH`ÔHHHHÔHHHHŠÔÔÔ`HHHÔH`ÔHH`ÔHÔHÔHÔÔHÔHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHH`HHHHHHHHHHÔHHHHHHHHHHHHHHÔHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔÔHÔHHHHHHHHHÔHHHÔHHHHHHHÔHHŠÔH``HHHHHÔHÔÔHHÔÔÔHHÔÔHHHHHHHHHHHÔÔHHHHÔHHHHHHHHHHHHÔHÔHÔHHHHHHHHHHHHÔHÔHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHÔHHHHÔHHHHHHHHHHHHÔHHHH`HHHHHHÔHHHÔHŠÔHHÔ````H2HÔHHHH`Ô``ÔHHÔÔÔHHHHÔHHÔHÔHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHÔHHHHHHÔHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHÔÔÔHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHHHìÔÔHŠHHÔHHHHHHHHHHÔÔÔÔHHHHHHHHHHHHHHHHÔHHHÔÔHHHH`HHHHÔHHHHHHHÔHHHHHHHHHHHHÔÔHHHHÔHHHHHÔHHHHHHHHŠHHHHHHHHHHHHHÔHHHHHHHHHHHÔHHHHHHHHÔHHHHŠHHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHÔHHHHHHÔH`ÔHÔÔHÔ`ÔHHHHÔHHHHHÔHÔHHHHHHHHHÔÔHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHÔHÔHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHÔHHHHHHHÔÔHHHHÔHHHHHHHHHHHHHHHHHHHHHÔHHHHHHH`ÔHHHHHHHHHÔHHŠÔ`HHHHHÔHÔÔHH`HHHHHHÔÔHHHHHHHHÔHHHHHÔÔHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHÔHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHÔHHHHHHHHHHHHHÔHÔHHHHHHHHHHHHHHHHHHHHHHÔHHÔHHHHHHHHÔÔÔH`H`ÔHH`ÔHHÔÔHHHHÔÔÔHHHÔHHÔÔHHHHÔHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHÔHHÔHHÔHHHHÔÔHHÔHHHHHHÔHHHÔHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHÔÔHHHÔHìHHÔHHHHHÔHHHÔÔÔHHÔHHÔHHÔHHHHHHHHHHHÔHHŠHHHHÔ`HHÔÔHÔHHHHÔHHHÔHHHHHHHHHHHHHHHHHHÔHHHHÔÔHÔÔHHHHHHHHHHHHHÔHHHHHHHHÔHHHHHHÔHHHHHHÔHHHHHHHÔHHÔHHÔHHHHÔÔHHHHHÔHHHHHHHHHHHÔHÔHHHHHHHHHHHÔHHHHHHHHHHHHHHHÔHHÔHHHÔÔÔHHÔÔHHHHÔHÔÔHHHHHHÔÔHHÔÔHHÔHHHÔÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHÔH`HHHHHHÔHHÔHHHÔ`ÔHHÔHHHHHÔHÔHHHHHÔHHHHHHHÔHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHÔHHHÔHHHHÔHHHHHHÔHHHHHHHHHÔHÔHHHHÔHHHHHHHÔHHHHÔHHHHHHHHHHHHHHHHHHHÔHHÔÔHHHHHHHHHHHHH`ÔÔÔHÔHHHHHHHHÔHHHHHHÔHHHHÔHHÔHHHH`ÔHHHHHÔHHHHHHÔHHHHÔHHÔHHÔHHHHHHÔHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHÔHÔHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔHHÔHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHÔHHHHHHÔHÔÔÔHÔHHHHHHÔHHHHHÔHHHHHHHÔHHÔHHHHHÔHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHÔHÔHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHÔHHHHÔHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHÔÔHHHHHHHHHHÔHHHÔÔHHÔH``ÔHÔHÔHHHHHHHHHHHHHHÔHHHHÔHHHHHHHHHHHHHHHHHHHÔÔHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHÔHÔHHHHHHHÔHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔHHHHÔHHHHHHHHHHHÔHHÔHÔÔHHÔ`HÔHHHÔHHHHHHHÔHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHÔHHHHHHHHHHH`HHHHHHHHHHHHHHHHHHHHHÔHÔHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHÔHÔÔHH`HHÔÔHÔÔHHHHHÔHÔHÔHÔÔHÔHHÔHHHHHÔHÔHHHHHHHHHHÔHÔÔHHHHHHHHHHHHHHHHHÔHHHHÔÔHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHÔÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHHHHHHÔHÔHHHÔHHHHHHHÔHHHHHHÔÔHÔÔÔHHHÔÔHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHÔHHHHHH2HHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHH`HÔHHHHHHHHHHHHHHÔHHHHHHHÔHHHHHHHHHHHHÔHÔHHHHÔÔHHHÔH`ÔHHŠHHHHHÔHHÔHHHHHHÔHHHHHHHHHÔHHHHHÔHHHHHHHHHHHHÔHHHHÔHHHÔHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHÔHHHHHHHHHÔHÔHHHHHH`HHHHHHHÔHHHHHHHHHHHHÔHHHHHHHHHHHHHÔHÔHHHHHHHHHÔÔHHHHÔHHHHHHHHHÔÔHHHHHÔHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH`HHHHHHHHHHHHHHÔ`HHÔHHHHHHHHHHHHHHHÔHHHÔHHHHHHHHÔHHHHHHHHHÔHHHHHHÔHHÔHHÔHHÔHHHHHHHHHHHHHHHHÔÔHH`ÔHHHHÔ`HÔHÔHÔHHHHÔHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHHHxÔHHHHHHHHHÔHHHÔHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHÔHH`HÔHxHH`H`ÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHÔHHHHHHHHHHìHHHHHHHHHHHHHHHHHHHHHHHHH`HÔHHHHHÔHHHHHÔHHHÔHHHHHÔHHHHHHHHHÔHHHHHHÔHHHÔHHHHHHHHHHHHHHHÔHÔHHHHHÔHHHHHHHÔHHÔHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHŠÔHHHHHHHHHHHHHHHHÔHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHÔHÔHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHH`ìHHHHHHHHHH`HHHHÔHHHHŠHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHÔHHHHHÔHHHHHHHHHÔHÔHHHHHHHHÔHHHHÔHHHHHHÔHHHHÔHHHHHHHHÔÔHHHHÔHHHÔHHHHHÔHHHHH`HHH`ÔHÔHHÔHHHÔHHÔHHHHHHHìHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHHHHHÔHHHHHHHHHHHHHHHHHÔHHHHÔHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHÔHHÔHH`HHHHHHHÔÔH`HHHHHHHÔHÔHÔÔÔHHHHÔHHHHHHHHHHHHHÔÔHHHHHHHÔHHHHHHHHHHHHHHÔÔHHHHHHHHÔHHHHHHHHHHHHHHÔÔHHHHHHHHÔHHÔHH`ÔHHHHHHHHHHHHHHHHÔHHHHHHÔHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHÔHÔHHHHHHÔHHHHHHHHÔHHÔHHHHHHHHHHHHHHHHHÔHHHÔHHÔHHHHHHHÔHHHHHHHHHHHHHHHÔHÔHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHÔHHÔHÔHHÔHHHHHHHHHHHHHHHHHÔHHHHHHHHHHÔHHÔHHHHHHHÔÔHHHHHHHHHHHÔHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHÔHHÔHìHHHHHHHÔHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHÔHÔHHHHHHHHHHHHHÔHHHHHHHÔHHHHHHHHHHHHHHHHHÔHHÔHHÔHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHÔÔHHÔÔHHHHHHHHHÔHHHHHHHHÔHHHHÔHHHHHHHÔHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHHÔHHHHÔHHHHHHHHHHÔHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHŠHHHHHHHÔÔHHHHHHHHHHHÔHHHHÔHHHÔHHH`HHHHHHHHHHHHHHHHHHHHHH`ÔHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHÔHÔHHHHHHHHHÔHHHHHHÔHHHHHHHHHHHHÔHHHHHHHÔHHHŠHHHHHŠHHHHHHÔHHÔHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHÔHHHHHHHHHHHHHHHHÔHÔHHÔHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH`HHHHHHHHÔHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHÔHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHÔHHHÔHÔHHÔHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHÔHHHHHHHÔŠHHHHHHHHHÔHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHÔHHHHÔHHÔÔÔHHHHHHÔHHHHHHHHHHHHÔHHHHHHÔHHHHHHHHHHHHÔHHHHHHHHHHHHÔHHHÔHHHHHHHHHHHÔHHHHHHHHHHÔHHHHHÔH`HHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHHHÔHHHHHHHÔHHHHHHÔHHHHHHHHHHHHHHHHÔHÔHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHÔHHHHHHÔHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHHHÔHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHÔHHHHÔHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHÔHHHHH`HHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHHHHHÔHHHHÔHHHHHHÔHHHHHHHHHHHHÔHHHHHHHHHÔHHHHHHHHHHHHHHHHÔHHHHÔÔHHHHHHHHHHHHHHHÔHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHÔHHÔÔHHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔHÔHÔHHÔHHÔÔHHHHÔHHHHHHHHHHHHHHHHHHHÔŠHHHHHÔHHHHHÔHHHHHHHHHHHÔHÔHHHHHHHHHHÔHHHHHHHHHÔHHHHHHHHHHHHHHHHHHH`HHHHHHHHHHHHHHHHHHHHHHHHÔÔHHHHHHHHHHHHHHHHHHHHHHHHÔHHÔHHHHHHÔHHÔHHHHHHHHHHHŠÔHHHHHHHHHHHÔHHHHHHHHHHHHHHHHÔHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHÔHHHÔHHHHHHHHÔHÔHHHH`HHHHHÔHHHHHHÔHÔHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHÔÔHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHHHÔHÔH`ÔÔHHÔHHHHHHHHHHHHHHHHHHHHHHHÔHHHHÔÔHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHÔHHHHHÔHHHHHHÔÔHHHHHÔHHÔHÔHHHHHHHHHHHHHHHHHÔÔHHHHHHHHHHHHHHHHHHHHHHHHÔHHÔHHHHHHÔÔHHHHHHHHHHHHHHHÔHHHHHHHHHHHHÔHHHHHHHHHÔHHÔHHHHHHHHHHHHHHÔHHHHHÔHHHHHHHHHHHÔHHHHHÔHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHÔHHHHHHHHHÔHHHÔHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHÔÔÔHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHÔHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHHHHHHHHÔÔHHHÔHHHÔHHHHHHHHHHHHHHHHHHHHÔÔHHHHHHHHHÔHHHHHHÔHHHHÔHHHHHHHHHHHHHHHÔÔHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHÔÔHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH`HHHHÔHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔHÔHHHHHHHHHÔHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHÔHHHHÔHÔHHÔHHHHHHHHHHHHHHHHHÔHHHÔÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHÔHHÔÔHHHHHHHHHÔHÔHHÔHHHHHHHHHHHHHÔHHHHHHÔHHHHHHHHHHHHHHHHHHHH`HHHHHHÔHHHHHHHHHHHHHHHHÔHHHHHHHÔHHHHHHHÔÔHHHHHHÔHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHÔHHÔHHHHHHHHHHHHHHHÔHHHHÔHHHHÔHHHHHÔÔHHHHÔHHÔHHHÔHHHHHHHHHHHHHHHHHHHHH`HHHHÔHHHHHÔHHHÔHHHHHHHÔHHHHHHÔHHHHHHÔHHHHHHHÔHHHHHHÔHHHHHÔHHHÔHHHHHHHHÔHÔHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHÔÔHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔÔÔHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHH`ÔHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHÔHHHÔHÔHHHHHHHHHHHHHHHHHHÔHHHHHHÔHHHHHHHHHÔHÔHÔHHHHHHHHÔHHHHHHÔHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHÔ`HHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHÔHÔHHHHÔHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHÔHHHHHÔHHHHHÔHHHHHHHHHÔHHHHHÔHŠHHHHHHHÔHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHÔHHHHH`HHHHHHHÔHHHHHHHHÔHHHHÔHHHHHHH`HHHHHHHHHHHÔHHHHHHHHHHHHÔHHHÔHHHHHHHHHHÔHHHHHHHHHHHHHHHHHÔHHHHHHÔÔHÔHHHHHHHHHHHHHHHHHHHHHHÔÔHHHHÔÔHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔHÔHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHÔHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHÔHHHHHHHHHHHHHHHHHÔHHHHHHHÔHHŠÔHHHHÔHHÔHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHÔÔHHHHHHHHHHHHHH`HHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHÔHHHHHHHHÔÔHHHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHHHHHHÔHHHHHHHHHHÔHHHHHHHHHHHHÔHHHHHHHHHÔHHHHHHÔÔHHHHHHHHHHHHHHHÔHHHHHHH`HHHHHÔHHHHHHHHHHÔHHHHHHHHHHÔHÔÔHHHHHHHHHHÔHHHHHHÔHHHHHHHHHHÔHÔHHHHHHHHÔHHHHHHHHHHHHHHHHHÔHHHHÔHHHÔÔÔHHHHHHHHÔHHHHHHÔHHHÔHÔÔHÔHHÔHHHHHHHÔHHHHHHHHÔHHHHHÔHHHHHÔHHHHHHHHHHHHHHHHHHÔHHHHÔHHHHHHHHHHHÔHHHHHHHHHÔHHHHHHHHÔHHÔHHHHÔHHHHHHHHHHHÔHHHHHHH`HHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHÔHHHHHÔHHHHHHÔHHHHHHŠHHHHHHÔHHHHÔHHHHHHHHHHHHHHHHHHHHHHÔHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHÔHHHHHHHHHÔHHHHHHHHHHHHHHHHHÔHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHÔHHHHÔHHHHHHHHHHHHHHHHHÔHHHHHHHHÔÔHHÔHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔHHHHHHHHHHÔHHHHÔHHHHÔHHHHHHÔHHHHÔHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHÔHHHHHHHHHHHÔHHHHHHHHÔHHÔHHHHÔHHHHHHÔHHHHHÔHHÔÔHHHHHHHHÔHHHHÔHHHHHHHHÔHHHHÔHHHHÔÔHÔHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHÔHHHHHHÔHHÔHHHHHHHHHHÔHHHHHHHHÔHHÔÔHHÔHHHHHHÔHHÔHHHHHHHHHHHHHÔHÔHHÔHHÔHHHHHHHÔHHHHHHHHÔÔHHHHHHHHHÔHÔHHÔHHHHHHHHHÔHHHÔÔHHHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHÔHHHHÔHHHHHHHHÔHHÔHHHHHHHHHHÔÔÔHHÔHHÔHHHHHHHHHHHHHHHÔHÔHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHÔHHHÔHÔHÔHHHHHHHHHHHHHHHÔHHHHHHÔHHHHH`HHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHÔHHHÔHHHÔÔHÔÔHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHÔHHÔHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHÔHHHHHÔHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHÔHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHÔHHHÔHHHHHÔHHHHHH`ÔŠÔHÔÔHHHHHÔÔHHHHHHHHHHHHHHHHHHHÔÔHÔHHHHHHÔÔHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHHHHHHHHÔHHHHHHHHHHHHHHÔÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHH`HHHHHHÔHHHHHHÔHHHHHHHHÔHÔ`HHHHHÔHÔHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHHHHHHHHÔHHHHHÔHHHHÔHÔHHHHHHHŠHHÔHHHHH`HHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHÔHHHHHHHHÔHHHHHHHHHHHHHHÔHHHHHHHHÔHHHHHHHÔHHHHHHHHHHHÔHÔHHHHHHHHÔHHHHHHHHHHÔHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHÔHÔHHHHHHHHHHHHHHHHHHÔHHHHHH`HHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHHHHHHHHÔHÔÔH`HHHHHHHHHHHHHÔHHHHHHHHHÔHHHHHÔÔHHHHHHHHHHHHHHHHHÔHHHHHHHÔHHHHHÔHHHHHHHHÔHHÔÔHHHHHHHHHHHHHHHÔHHHHHHHHHHHÔHHHHHÔHHHÔHHHHHHHHHÔÔHHHHHHÔHHHHHÔHHHÔHHHHHHÔHHHHHHHHHHHHHHHHHHHH`HHHHHHHHHÔHÔHHHHHÔHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHÔÔHÔHHHHHHHHHHHHHHHHHHÔÔHHHHHHHHHHHHHHHHÔHHÔHHHHHHÔHHHHHHÔHHHHHHHHHHHHHHH`HHHHHHHHHHHHHHHHHHÔÔHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHHHHHHHHHHHÔHHHHÔHHHHHHHHHHHHÔHHHHHHHHÔÔHHHHHHÔHHHÔÔHHÔÔHHHHHHHHHHHHHHHHHHÔÔHHHÔHHHHHHHÔHHHÔHHHHHHHHÔHHHÔHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHÔHÔHHHHHHHHHHHHHHHHHHÔHHHHHÔHHHHHÔHHHHHHHHHHÔHHHHHHHÔHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHHHHHHÔHHHHHHHHHÔHHHHHHÔÔHHÔHHÔHHHHHHHHHHHHHHHHHHÔHHHÔHHHHÔHHÔHHHHHHHHHHHÔHHHHHHHHHHÔHHHHHHHÔHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHHHHHHHHŠHHHHHHHHHHHHHHHÔHHHHHHHHHÔHHHHHHÔHHHHHH`HHHHHHHHHHÔHHHHHHHHÔHHHHHHHHHÔHHHHHHH`HHHHHHHÔHHHHHHHHHHHHHHHÔHHHHHHHHÔHHHHHHHHÔHHHHHHHHHHÔÔHHHHHHHHHHHÔHHHHHHHHÔÔHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHHHHHHHHHHHHHHHHHHHHHHHÔÔHHHHHHHHHÔHHHHHHHHHHHHHHHHHÔHHHHHÔHHHHHHHHHHHHHHÔÔHHHHHHHHHHÔHHHHHHHHHHÔHHHHHHHHÔHÔHHHHÔHHHÔHHHHHHHHHHHHÔHHHHHHHHÔHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHHHHHHHÔHÔHHHHHHHHHHHHHHHHHHHHÔHÔHHHÔHHHHHHHHHHHHHHHHHÔHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHÔHHÔHHHÔÔHHHÔHHHHHHHHHHHÔHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHÔHHHHHHHÔHHHHHHHHHHÔHHHÔHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHÔHHÔH`HÔHHHHHHÔHHHHHHHÔÔHHHHHHHHHHHÔHÔHHHHHHHHHHHHHÔHHHHHHHÔÔHHHHHHHHHHHHHÔHÔHHHHÔHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHÔHHÔHHHÔHÔHHHHHHHÔHHHHHHHHHHHHHHHHÔHÔHHHHHÔHHHHHHHHHHÔHHHHHHÔHHHÔHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔÔHHHHHHHHHHHHHHÔHHHHHÔHHHHHHHÔHHHHHHHHÔHHHHHHHÔÔÔHHHHÔHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHÔÔHHHHHHÔHHHHHHHÔHHHHHHHHHÔHHHHHHHHHŠHHHHHÔÔHHHHHHHHHHÔHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHÔHHHHHH`HHHHHHHHHHHHHHHHHHHHHHHHHÔÔHÔHHHHHHHHHHHHHHHHHHHHHÔHÔHHHHHÔHHHHHHHHÔHHHHHÔHHHHHHÔÔHÔHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHHÔHHHHHÔHHHHÔHHHHHHHHHHHHHHHHHHHHHHÔH`HHÔÔHHHHHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔHHHHHHHHHHÔHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHÔHHHÔHHHHHHHHHHHHHHHÔHHHÔHHHHÔHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHÔHHHHHHHÔHH`HHHÔHHHHHHHHHHHHHHHÔÔÔHHHHHHHHHÔHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHÔHHHHHHÔHHHÔHHHHHHHHÔÔHHHHHHHHHHÔHHHHHHHHHHHHHHHHHÔÔHHHHHHHHHÔHHHHHHHHHÔHHHHHÔHHHHHHÔHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHŠHHHHHHHHHHHH`HHHHHHÔHHHŠÔHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHÔHHÔHHHHÔHHHHHHHHHHHHHHHHHHHÔHHHHHH`HHHÔÔHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHÔHHHHHHHHÔHHHHHHHHHHHHHHHHHHHH`HHHÔHHHHHHHHÔHHHHHHÔHHÔHHÔHÔHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔHÔHHHHHÔHHHHHHHÔHHHHÔHHHHHHHHHHHHHHHHHŠHHHHÔHHHHHHHHÔHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHÔHHHÔHHHHHHHHHHHHHÔHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHÔÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHÔHHHHHHHHHHHHHHÔHHHHHHHHÔÔHHHHHHHÔHHHHHHHHHHHHÔHHHHÔHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHÔHHHHHHHHÔÔHHHHHHHHHHHÔHHHHHHÔHÔHÔHHHHHHHÔHHHHHHHÔHH`ÔÔHHHHHHHHHHHHHHHHHHHHHHHHHHŠÔHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHHÔHÔHHHHHHHHHHHHÔHHÔHHHHHHHÔHHHHHHHHÔHHHÔHHHHHHHÔHÔHHHÔÔHHHHÔÔHHHÔHHHÔHHHHHHHHHHHHHHÔHHHHHHHHHHHHÔHHHHHHHÔHHÔÔHÔHHHHHHÔHHHÔHHHHÔHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHH`HHHHÔHHHHHÔHHÔHHHHHHHHHHHÔÔHHHHHHHHÔHHHHÔÔHHHHHHHÔÔHHHHHHHHHHHÔHÔH`HHHHHHÔH`HHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHÔHHÔHHHHÔHHHÔHHHÔHHHHHHHHÔHHHHÔHHHHHHHHHHHHHHHH`ÔHHHHHHHHHHHÔHHHHHHHHÔHHHÔHHHHHHHHÔÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHHHHHHHHHHÔHHÔHHHHHHHÔHHÔÔHHHHHHHHHHHHÔHHÔHHHHHHHŠHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHÔHHHHHÔHHÔHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHÔHÔHHHHHH`HHHHHHHHÔHHHHHÔÔHHHHHHHHHÔHHHHHHHÔHHHÔHHHHHHÔHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHÔHHHHHHHÔHÔHHHHHHHHHHHHHHHHHHHHÔÔHHHHHHHHHHHH``HHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔ`HHHÔHHHHHHHHHHHHHHHÔ`HHHHHÔÔHHÔHÔHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHÔHHÔHHHHHHHÔHHHHHHHHHHHHHHHHHÔHHHÔHHHHHHHÔHHHHHHHHHHHHHHHHHÔHHÔHÔHHHHHHHHHHÔHHHHÔÔHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHÔHHHHHHHHHHÔÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHÔHHHHHÔHÔHHHHHHÔHHHHÔHHHHHHHHHHHHHHHHHHÔHHHHHHHHÔHHHHHHHHHHHHÔHHÔHHHHHHHHHÔHHHÔHHÔHHHHHHHÔHHHHHHHHÔHHÔHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHÔHHHHÔHHHHHHHHHHHHÔHHHHHHHHHHHÔHÔHHHHHHHHHHHÔHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHÔHÔHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHÔÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHÔHÔHHHÔHHHHHHÔHHHHHHHHHHHHHHHHHHHHÔÔHHHHHHHÔHHHHHHÔHHHHHHHHHHHHHHHÔHHHHHHHHHHHÔHHHHHHHÔHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHÔHHHHÔHHHHHHHHÔÔHHHHHHÔHÔÔHÔHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHÔHHHHHHÔHHHHÔHHHHHHHHHHHHHHÔHHHHHHHHHHHHHÔHHHHHHÔHÔHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHÔHHHHHHHHHHHÔHHHHHHHHÔÔHHHHHHHHHHHHÔÔHHHHHÔHHÔHHHHHHHHHHÔHHHHHHHHHHHÔHHHHHHHHHHHHHÔÔHHHHHHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHÔHÔHHHÔHHHHHHHHHHÔHHHHHHHHHHHHHHHHÔHHHHÔHHHHHHHHHHH`HHHHHHHH`HHÔHHHÔHÔHHHÔHHÔHHHHHHHHHHHHHHHHHÔHHHÔHHHÔHHHHHHHHHHHHHHHHHHHHHHÔHHÔHHHHHÔHHHHHHHHHHHHHÔHHHHH`HHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔHHHHHHHÔÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHÔÔHHÔHHHHHHHÔHHHHHHHÔHHHHHHHÔHHÔÔHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHH`HHÔHHHHHÔHÔHHHHHHHHHHHHHÔHHHHHHHÔHHHÔHHHHHÔHHHHHHHHHHHHÔHHHHHHHHHHHHÔÔHHHHHHÔHHHHHHÔHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHÔHHHÔHÔHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHÔHHHHÔHHHHHHHHHHHHHHHÔHHHHHÔHHHHHHHHHHHHHHHÔHHHHHHHHHHHHÔHHHHÔÔHHHHHÔHHHHHÔHHHHHÔHHHHHHHHÔHHHÔHHHHHHHÔHHHHHHHHÔHHHÔHHHHHHÔHHHHHHHHHHHHÔÔHÔHHHHHHHHHHHÔHHHHHHHHHHHÔHHHHHHHHHHHHHHHHÔHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHÔHHHHHHHÔÔHHHHHHHHHHHÔHHHHHÔHHHHHHHHHHÔHHHHHHHHHHÔHÔHHHÔÔHHHHHÔHHHHHHHHHHHHHHHHHHHHH`ŠÔHHÔHHHHHHÔHHHHHHHHHHHH`HÔHHHHHHHÔHÔHHHHHHHHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHÔHÔHHHHHHHHHHHHHÔHHHHHHÔHHHHHHHHHÔÔHHHHHHHHHHHHÔHH`HHHHHHHHHHHHHÔHHHÔHHHHÔHHHHHHHHHHHÔHHHHHÔHHHHHÔHHHHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHÔHHHÔHÔHHHHÔHHHHHHHHHÔHHÔÔHHHHHHHHÔÔHHHHHHH`HHHHHHHHHHHHHHHHHHHHHHHHÔHHÔHHHH`HHHHHHHHHÔHHHHHHHHHHHHHÔHHHHÔÔÔHHHHHHHHHHHHHHHHHHH`HHHHHHHHHHHHÔHHHHHHÔHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHÔHÔHHHHHÔHHHHHHHHHHÔÔHHHHHHHHHHHHHHÔH`HHHHÔHHHHÔHHHÔHHHHHHHHHHHHHHHHHHHHÔHHHHHÔHHHHHÔHHHHÔHHHHHHHHHHÔÔHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHH`HHHHHHHHHHHHHHÔHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔÔHHHHHHHHHHHHHHÔHHHHÔHHÔHHHÔHÔHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHÔÔHHHHHHHHHHHHHHHHHHÔHHHHHHHHHÔÔHÔHHHÔHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHÔHHHHÔHHHHÔHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHÔHHHHÔHÔHHHHHHHHHHHHHHHÔHHHHHHHHÔHHHHÔHHHHHHHHÔHHHÔHHHHHHHHHHHHHHHHHHHÔHHÔH`HHHHHHHÔÔÔHHHHÔHHHHHHÔ`HÔHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHÔÔHHHÔHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHÔHÔHHHHHHHÔHHHHÔHHHÔHHHÔHHHHHHÔHHHHHHHHHHHHHHHHHHHHÔHHHHÔHHHHHHHHHHHÔHHHHÔHHHHHHÔHÔHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHH`HHHHHHHHÔHHÔHHHÔHHHHHHHHHHHHHH`HHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHÔHHHHHHHÔHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHÔHHHHHHÔHHHHHHHÔHHHHHHHHHHHHHHÔHHHHÔHHHHHÔHHHÔHHHHHHHHHHHHHHHHÔHHHH`HHHHHHHHHHÔHÔÔHHHHHHHHHHÔHHHHHHHHHHHHHHHÔHHHHHÔHHHHHHHHHHHHHHHHHHHÔHHHÔHHÔHHHHHHHHHHHHHHHHHHHHHÔHHHHHÔHÔHHÔHHHHHHHHHHHHHHHHHHHHHHÔHHÔHHÔHHHHHHHHHHHHHHHHÔHHHHÔHHHHHÔHH`H`HHHÔHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHH`HHHHHHHHHHHÔÔHHHHHHHHHHHHHHHHHHHHHHÔHHHHÔHÔHHÔHHHHHÔÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHÔHÔÔÔHHHHÔ`HHÔHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHÔHHHHHHHHHHHHHHHHÔHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHH`HÔHÔ`HÔHHHÔHHHHHHHHHÔÔHHÔHHHHHHHHHJHHHHHHÔHHHHHHÔHHHHHHHHÔHHHHHHHHHHHÔHHÔHHÔHHHHHHHHÔH`HHHHHHHHHÔHHHHHHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHÔHHHÔÔÔHHÔHHHHHHHHHHHHHHHHHÔHHHHHHHÔHÔHHHHHHHHHHÔHHHHHHHHHHHHÔHHHHÔÔHÔHHHÔHHHHHHHHHHHHHÔHHHÔHHHHHHHH`HHÔ`HHÔHÔHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔHHHHÔÔHHHHHHHHÔHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHxHHHÔHHHHÔHHHHHÔHHHHÔHHHHHHÔHHHÔHHHHHÔHHHHHHHHHHHÔŠHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHÔHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHÔHHHHHHÔHHÔŸHHHHHHÔHHÔHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHÔHHHHÔHHHHHHÔHHHHÔHHH`HHHHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHHHHHHHHHHÔHHH`HÔHHHÔÔHHHHHHHHHHHHÔHHHHHHHHÔHÔHÔHHHHHHHHHHHHHHÔHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHÔHHÔHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHÔHHHHÔHHHHHHHHHHHHHHÔHHHHHHHHHHÔHHÔHHHHÔHHHHHHHHHHHÔHHHHHHHHHHHHH`HÔHHHHHÔHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHÔÔHHHHHÔÔHHHHHHHH`HHHHHHHHHHHHHHHÔHÔHHHHHHHÔHHHHHHHHHHHHHHÔHHHÔÔHHHHHHÔHHHÔHHHHHHÔHHHHHHHHHÔHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHÔHHHHHHÔHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHÔHHHHÔHHÔHHHHHHHHHHHHHÔHHHHHHHÔHHHÔHHHHHÔHHHÔHHHÔHÔHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHÔHHHHHHHHÔHÔHHHHHÔHHHÔHHHHHHHHH`HHHHÔHÔHÔÔHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHÔHHHHHHHHHHHHHHÔHÔÔHHHÔHHHHHHHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHÔHHHHHHHHÔHHHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHHHHÔHHHHHHÔ`HHHHÔHHHHHHHHHHÔÔHHHHHHÔHHHÔHÔHHHHHHHHHHÔÔHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHÔHHHHHHHÔHHHÔHHHHHHHHHHHHHHHHHHÔHHÔHHHÔHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔHHHHÔHHHHHHÔHHÔHHHHÔHHHÔHHHHHHHÔHHÔHHHHHHHHHÔHHHHHHHHHHHHHHHÔHHÔHHHHHHÔHHHHHHHHÔHHÔHHHHHHHHÔHHHHHÔHHHHHHHHHHHHHÔÔHHHHHHÔHHHHHHÔHÔHÔHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHÔHÔHHHHHÔHHHHHHHHHHHH`ÔÔ`ÔHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHÔHHHHHHHÔHHHHHHHHÔHHHHHHHHHHHH`HHÔHÔHHHHÔHHHHHHHHHHHHHHHHHHHHHÔHHHHHÔÔHHHHHHHHÔHHHHÔHÔÔHHHHHHHHHHHHHHÔÔHHHHHÔHHHHHÔHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHÔÔHHH``ÔHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHÔHHHHHHHHHHHÔHHHHÔÔHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHÔHHHHHHÔHHHHH`HHÔHÔHHHHHHHHHHÔHHHHHHHHHÔÔHHÔHÔHHHHHHHHHÔÔHHHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHÔHHHHÔHHHHHÔHHH`HHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHÔHHHHHÔÔHHHHHHÔÔHHHHHHÔHHHHHÔHHHHHHÔHHÔHÔHHHHHHÔHHHHHHHHHHHHHHHHHHHHÔHHÔHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHÔHHHHHHHHHÔHHHHHHHHHHHHÔHHH2HHHHHHHHHHHÔHHHHHHÔHHÔHHHHHHHÔHHHHHHHHHÔÔHÔHHHHHHHHHŠHHHÔHHHHHHHHHÔHHHÔHHHHHHHHHHHHHHHÔHHHHHHHHHHÔHHHHÔHHHHHHHHHHHHHHHHHHHHÔHHHÔHHHHHHHHHÔHHHHÔHHHHHHHHHHHHHHHÔHHHHHHHHHHHÔHHHH`ÔHHHHHHHHHHHH`HHH`H`HHHÔHHÔHHHHHHHHHHÔHHHHHHÔÔHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHHHHÔÔHŠHHHHHHHHHÔHHHHHHHHHHHHHHHHHÔHÔHHHHHHHHHHHHHHH`HÔHHHHÔHHHÔHHHHHHHÔHHHHHHHHHÔHHHÔHHHHHHHHHHHHHHHHÔHHHHHHHHHÔHHHHHÔHÔHHHHHHHHHÔHHHHHHHHHÔHHÔHÔHHÔHÔHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHHHHHHÔÔHÔHHHHHHHH`HHHHHHHHÔÔHHHHHHHHHHHHÔHÔHHHHHHHHÔÔHHHHHHHHHHHHHHHHHÔHHHHHÔHÔHHHÔHHHHHHHHHHHHHHHHHHHHÔHHHHHHHÔHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHÔHHHHHÔHÔHHHHHHHHHHHHH`HHHHHHHHHHHHH`HHHHHÔHHHHH`HHHÔÔÔHHHHHHHHHHÔHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHHHHÔHHHHHHHHHHÔHHHHHHHH`ÔHHÔHHHHHHHHHHHHHHÔHHHHÔHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHÔHHHHHHÔ`ÔHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHÔHHHHHÔHHHHHHÔ`HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHÔHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHH`HHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHÔHHHÔHHHHHHHÔHHHHHHHÔHHHÔHHHHHHHHHHHHHHHHHHÔHHHHHHHHHÔHHHHHHH`HHHHHHHÔH`HHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHÔHHHHÔHHHHHÔHHHHHHHHHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH`HHHÔHHHHHHÔHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHÔÔHHHHHÔHHÔHHHÔHHHHHHHÔHHH`HHHHHHHHHHHHHHHHHÔHHHHÔHHHHHHÔHHHHHHHHÔÔHHÔHHÔHHHHÔHHHHHÔHHHHHHHHHHHHHH`HHHHHHHÔÔÔHHHÔÔÔHHHHHHHÔHHHHHHHHHHHHHÔHHH`HHHHHHÔHìHHÔHHÔHHìHHHHHHHHHHÔÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHÔÔHHHHHHHÔHHÔHHHHHHHHHHHHHHÔHHHHHHHHHÔHHHHHÔHHHHHHHÔÔHHHHHHHÔHHHHHHHHÔHÔÔHHH`HHHHHHHHHHÔHHÔHHHHHHHHHHHHHÔÔHHHHHÔHHHHHHHHHHHÔHHÔHHHHHÔHHìHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHÔHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHÔÔHHHHHHH`HHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHH`HHÔHHHHH`HHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHÔHHHÔHHHHHHHHHHÔÔHHHHHHHHHHHHHHHÔÔHHHÔHHHHHHHÔHÔHHHÔHHÔHHHHHHHHHHHHHHHÔHHHHÔHHHHHŠHHHHHHHHHHHHHHHHHHÔHÔHHHHHHHHHÔHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHÔHHHHÔHHHHHHHHHÔHHHHHHHHHHÔHÔHÔHHHHHHHHHHÔHÔHHÔHHHHHÔHHÔHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔH`HÔHHHHHHHHHHHHHHHHHHHHHHHÔHHÔHHHHHHHÔHH`HHHHHHHHHHHHHHHHHHHHHÔHÔHHHHHHHHHHHHHÔHHHHHHHHÔÔHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHÔHHHHHHHHÔÔÔHHHHÔHHHHH`HHHÔHHHHHHìHÔHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHÔHHHÔHÔÔHHHHHHHHHHHHHÔHHHHHHÔHHHHHHHHHHHHÔHHÔHHHÔHÔHHHHHHHÔHHHHHHHÔHHHHÔHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHŠHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHÔHHHÔÔHHŠHHHHHÔHHÔHHHHHÔHHÔHHHHÔÔHHHHHHHHHÔÔHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔHHHÔHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHÔHHHHHÔHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHÔHHHHHHHHÔHÔHHHH`HHHÔHHHHHÔÔHHHHHHHHHHHHHHHHHHÔHHHHHÔHHÔHHÔHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔHHHHHHHÔHHHHHHHHHÔHHHHHHHHHHHHHHHHHÔHHHHHHHHÔÔHHHHHÔHHHHHHHHHHHHÔHHHÔHHHHHHH`ÔHHHHHHÔHHHHÔHHHHHHHHHHHHHHHHHHÔHHHHÔHÔHHHÔÔHHHHHHHHHHÔÔHHHÔHHHHHHHHHHHHHHHŠHHHHHHHÔHHHHHHHHHHÔHHHHHHHHHHHHHHÔHHHHHHÔÔHHHHHÔHHHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHHHÔHHHHÔHHHÔHHHHHHHHHHHHHHHHHÔHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHÔHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔHHHHHHÔHHHHÔHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHÔÔHHHHHHHHHHÔHHHHHHHHHHHÔHHHÔHHHHHÔHHHHHHÔHÔHHHÔHHHHHÔHÔÔHHHHHÔHHHÔHHHHHHHHÔHHHHHHHHHHHHÔHHHÔHÔHHHHHHHHHHHÔHHHHHÔHHHHHHHHHHHHHHHHHHHÔHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHHÔHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHÔHHHHHÔHHHHÔHHÔHHHHHHHHHHHHÔHÔHHHHHHHHHHHHHHHHÔHHHHHHHHHÔHHHÔHHHHHHÔHHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHHÔÔHHHHHHHHHHHHHHHHHHHHHÔÔHHHHHHHHHHHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔÔHHHHHÔHHHHÔHHÔHHHÔHHHHHHHHHÔHHHHHHHHÔHHHH`HHHHHHÔHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHÔHÔHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHÔHHHHHHHHHHHÔHÔHHHHÔHHHÔHHÔHHHHHHHHHHHÔHÔÔHHHHHHHÔHÔHHHHÔHHHHHHHHHHHHHHHHHHHÔ`HHHHHÔHÔHHÔHHÔHHHHHHHHHHHHHHH`HHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHÔHHHHHÔHHHÔHHHHHHHŠHHÔÔHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHÔHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHÔHHHHHHHHHHÔHHHHHHHÔHHÔHHHHHHHHHHHHÔÔHHÔHHHHHHHHHHÔHHHHÔHHHHHHHHHHHHHHÔHHHHÔHHHÔHHHÔHHÔHHHHHHHHHÔÔHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHÔHHHÔHHHÔHÔHHÔHHHHÔHHHHHHHHHHHÔÔHHHHHHHHHHHHHH`HHHHÔHÔHÔÔHHHHHHHHHHHHŠHHHHHHÔHHHHHHHHHHHHHHHHHHÔÔHHHHÔÔHHHÔHHHHHHHHHHHHHHHHHHHHÔÔHHHHHHHHHHHHHHHHHHHÔÔHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHÔHHHHÔHHHHHHHHHHHHHHHHHHHHÔHHÔHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHHÔHHHÔHHHÔHHHHÔHHHHHHHÔHHHHÔHHHHHHHHHHÔHHHHHHHHHHHHHHÔÔHHHÔHHHÔÔÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHÔÔHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHÔHHHHHHHHHHHH`HHHHHHHHÔHÔHHHHHHÔÔHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHÔHÔHÔHÔHHÔHHHHÔHHHHHHHHHHHHHHHHÔÔHHHHHHHHHÔHHHHHHH`HHHHHÔÔHHHHHÔÔHHHHHHHHHHHHHHHHHÔHHHHHHÔHÔHHHHÔHHHHHHHHHHHHHHHHHHÔHÔHHHÔHHHHHÔHHHHHHHHHÔHHHÔHHHHHHHHHHHÔHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔHHHHHHHÔHHÔHHHÔÔHHHHHHHHHHHHÔHHÔHHHHHHHHHHHHHHHÔHHHHHHÔHHÔHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHÔHHHHHHÔHHHHHHHHHHÔHHHHHHHÔÔHHHHHHHHHHHHHHHHH`HHÔHHHHÔÔHHHÔHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHÔHHHÔHHHHÔHHHHHHHHHHHHHHHHHHHÔHHÔHH`HÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHÔHHHHHHHÔHHÔHHHHHÔHHHHHHHÔHÔHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHÔHHÔHHHHÔÔHHHHÔHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHÔHHHHHHHHHÔÔÔHHÔHÔHHHHHHÔHHHHHHHHHÔHHHHHHHHHHHÔHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHÔHHHHHHÔHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHÔÔHHHHHHHHHHHHHHHHHHHHÔHHHHÔH`ÔHHHÔHHHHÔHHÔHHHHÔÔÔHHHÔHHHHHHHHHHHHHHHHHHHÔHHÔHHÔHHÔHHHHHHÔHHHHHHHHÔHHHHHHHHHHHHHHHHÔÔHHHHHHH`HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHÔHHHHHHHHHHHHHHHHHHHHHHÔHHÔÔHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHÔHHÔHHHH`ÔHHH`HHHHÔHHÔHHHHHHHHÔHÔHHHHHHHHHHHHHHHHÔHHHHHHHHHHÔHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHH`HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHÔHHHHHHHHHÔHHÔHHHHÔHHHHHHHHHHHHHÔHÔHHHHHHHHHHHHHHHŠHHHHHHHHHHHHHHHÔHHHHHHHHHHHHH`HHHHÔHHHHHHÔHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHHHÔHHHHHHHHÔHHHHHHHÔHHHHHHHHH`HHHHHÔHHHHHHHHÔHHHHÔHÔHHHHHHHHHHHHHHHHHHÔHHHHHÔHHHHHÔHHHHHHHÔHÔHHHHHHHHHHHHHHHHHHÔHHÔHHHÔHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔHHÔHHÔHHHHHHHHÔHHHHHHHHHHHHHÔHHHHHHHHHHHHÔ`HHHHHHHHHHHHHHHHHHHHHHHHÔHHH`HÔHHHÔHHHHHHHHÔH`HHHHHHHHÔHÔÔHHHÔHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHHHHHHH`HÔHHHHHHÔHHHHHHÔHHHHHHÔHHHHHHÔHHHHHHHHHHHÔHHHHHHHHHHHHHHÔHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHHÔHHHHHHHÔHHHHHHHÔHHHHHHHHHHHH`HHHHHHHHHÔHÔHHHÔHHHHÔÔHHHHÔHHHHHHHHHHHHHHHHÔHHHHHHH`HHÔHHHHHHHHÔHHHHÔHHHÔHHÔHHHHHÔHHÔHHHHHHHHHHÔHÔHÔÔHHHHHHHHHHHHHHÔHHHHHHÔHHHHHHHHHHHHHHHHHHHHHHÔÔHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHÔHHHHHHÔHHHHÔHÔÔHHÔHH`HÔHHÔÔHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHH`HHHHHÔHHHHHHHHHHÔHÔHHHHHHHHHHHHHHHHHHHÔHHHHHHÔHHHHHÔHHHHHHHHHÔHHHÔHHHHHHHHHÔHHHHHHHHHHHHÔHHHHHHHHHHHHHHHHHHHHÔHÔHHHHHH`HHHHHHHHHHHHHHHHHHHHHHHHH`HHHÔÔHHHHHHHHHÔHHÔHŠH`HHHHHÔHHÔHHHHÔHÔH`HHHHHHÔHÔHHHÔHHHÔHŠHHÔHHHHHÔHÔHÔHH`HHHÔHHHHHHHÔHHHÔHHÔHHÔHHHHHÔ`HHHHÔH`ÔHÔÔHHHHHÔHHHHHHHÔHÔHHHH`HHHHÔHHHHHÔHHHÔHHHHHÔÔHHHHHÔHHHÔHHÔHHHHHHHHHHHHHHÔHÔHHHHHHHHHHHHÔHHHHHHÔHHHHHHHHHHHH`HHHìHHHHHÔÔHÔÔÔHHHHÔÔÔHHŠHHHÔ2`ŠHH`ÔHHH`HHH`ÔHHÔHÔÔHÔÔÔ`ÔHHÔÔÔÔHÔ`HHHÔHHHÔÔHHÔHìHHÔÔHHŠ`HHHÔÔHH`HHHHÔ`HÔŠÔ`Š`ŠHHHÔÔHHHHHHHH2ÔŠÔHHÔÔÔÔHHHHHHÔHHHÔÔ`ÔHH`ÔHHHHHÔH`ÔÔìHHHHHHÔH``HHHÔHHÔ`ÔHÔHHÔHHÔHHÔÔHHHH`HÔÔÔHHHHÔHHHHHHHH`HHŠHHHHHHHHÔÔÔÔÔHHHHHHHÔÔÔHHÔHHÔH`HHHHÔHHÔÔHHÔ`ÔXTENSION= 'TABLE   '           / FITS STANDARD                                  BITPIX  =                    8 /  8-bits per 'pixels'                           NAXIS   =                    2 /  Simple 2-D matrix                             NAXIS1  =                  335 /  No of characters per row                      NAXIS2  =                    1 /  The number of rows                            PCOUNT  =                    0 /  No 'random' parameters                        GCOUNT  =                    1 /  Only one group                                TFIELDS =                   20 /  Number of fields per row                      EXTNAME = 'x0cj010ct_cvt.d0h.tab' / Name of table                               TTYPE1  = 'CRVAL1  '           /                                                TBCOL1  =                    1 /                                                TFORM1  = 'D25.16  '           / %25.16g                                        TUNIT1  = '        '           /                                                TTYPE2  = 'CRVAL2  '           /                                                TBCOL2  =                   27 /                                                TFORM2  = 'D25.16  '           / %25.16g                                        TUNIT2  = '        '           /                                                TTYPE3  = 'CRVAL3  '           /                                                TBCOL3  =                   53 /                                                TFORM3  = 'D25.16  '           / %25.16g                                        TUNIT3  = '        '           /                                                TTYPE4  = 'CRPIX1  '           /                                                TBCOL4  =                   79 /                                                TFORM4  = 'E15.7   '           / %15.7g                                         TUNIT4  = '        '           /                                                TTYPE5  = 'CRPIX2  '           /                                                TBCOL5  =                   95 /                                                TFORM5  = 'E15.7   '           / %15.7g                                         TUNIT5  = '        '           /                                                TTYPE6  = 'CD1_1   '           /                                                TBCOL6  =                  111 /                                                TFORM6  = 'E15.7   '           / %15.7g                                         TUNIT6  = '        '           /                                                TTYPE7  = 'CD1_2   '           /                                                TBCOL7  =                  127 /                                                TFORM7  = 'E15.7   '           / %15.7g                                         TUNIT7  = '        '           /                                                TTYPE8  = 'CD2_1   '           /                                                TBCOL8  =                  143 /                                                TFORM8  = 'E15.7   '           / %15.7g                                         TUNIT8  = '        '           /                                                TTYPE9  = 'CD2_2   '           /                                                TBCOL9  =                  159 /                                                TFORM9  = 'E15.7   '           / %15.7g                                         TUNIT9  = '        '           /                                                TTYPE10 = 'DATAMIN '           /                                                TBCOL10 =                  175 /                                                TFORM10 = 'E15.7   '           / %15.7g                                         TUNIT10 = '        '           /                                                TTYPE11 = 'DATAMAX '           /                                                TBCOL11 =                  191 /                                                TFORM11 = 'E15.7   '           / %15.7g                                         TUNIT11 = '        '           /                                                TTYPE12 = 'MIR_REVR'           /                                                TBCOL12 =                  207 /                                                TFORM12 = 'I11     '           / %11d                                           TUNIT12 = '        '           /                                                TTYPE13 = 'ORIENTAT'           /                                                TBCOL13 =                  219 /                                                TFORM13 = 'E15.7   '           / %15.7g                                         TUNIT13 = '        '           /                                                TTYPE14 = 'FILLCNT '           /                                                TBCOL14 =                  235 /                                                TFORM14 = 'I11     '           / %11d                                           TUNIT14 = '        '           /                                                TTYPE15 = 'ERRCNT  '           /                                                TBCOL15 =                  247 /                                                TFORM15 = 'I11     '           / %11d                                           TUNIT15 = '        '           /                                                TTYPE16 = 'FPKTTIME'           /                                                TBCOL16 =                  259 /                                                TFORM16 = 'A24     '           / %-24s                                          TUNIT16 = 'CH*24   '           /                                                TTYPE17 = 'LPKTTIME'           /                                                TBCOL17 =                  284 /                                                TFORM17 = 'A24     '           / %-24s                                          TUNIT17 = 'CH*24   '           /                                                TTYPE18 = 'CTYPE1  '           /                                                TBCOL18 =                  309 /                                                TFORM18 = 'A8      '           / %-8s                                           TUNIT18 = 'CH*8    '           /                                                TTYPE19 = 'CTYPE2  '           /                                                TBCOL19 =                  318 /                                                TFORM19 = 'A8      '           / %-8s                                           TUNIT19 = 'CH*8    '           /                                                TTYPE20 = 'CTYPE3  '           /                                                TBCOL20 =                  327 /                                                TFORM20 = 'A8      '           / %-8s                                           TUNIT20 = 'CH*8    '           /                                                CRVAL1  = ' right ascension of reference pixel' /                               CRVAL2  = ' declination of reference pixel' /                                   CRVAL3  = ' first packet time' /                                                CRPIX1  = ' x-coordinate of reference pixel' /                                  CRPIX2  = ' y-coordinate of reference pixel' /                                  CD1_1   = ' partial of the right ascension w.r.t. x' /                          CD1_2   = ' partial of the right ascension w.r.t. y' /                          CD2_1   = ' partial of the declination w.r.t. x' /                              CD2_2   = ' partial of the declination w.r.t. y' /                              DATAMIN = ' the minimum value of the data' /                                    DATAMAX = ' the maximum value of the data' /                                    MIR_REVR= ' is the image mirror reversed' /                                     ORIENTAT= ' the orientation of the image in degrees' /                          FILLCNT = ' number of segments containing fill' /                               ERRCNT  = ' number of segments containing errors' /                             FPKTTIME= ' the time of the first packet' /                                     LPKTTIME= ' the time of the last packet' /                                      CTYPE1  = ' the coordinate type for first axis' /                               CTYPE2  = ' the coordinate type for the second axis' /                          CTYPE3  = ' the coordinate type for the third axis' /                           END                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      12.6869651851956       -52.10126619890351        87038170.45117187           257.           257.    2.383380E-6    5.689839E-6   -5.385026E-6    2.518288E-6             0.           936.          0       66.12611          0          028-AUG-1990 21:27:29.8125-APR-1990 17:30:15.61RA---TANDEC--TANTIME                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
Index: /BAORadio/libindi/libindi/indiapi.h
===================================================================
--- /BAORadio/libindi/libindi/indiapi.h	(revision 503)
+++ /BAORadio/libindi/libindi/indiapi.h	(revision 504)
@@ -75,5 +75,5 @@
 
 /* INDI Library version */
-#define INDI_LIBV	0.7
+#define INDI_LIBV	0.8
 
 /*******************************************************************************
Index: /BAORadio/libindi/libindi/indidriver.c
===================================================================
--- /BAORadio/libindi/libindi/indidriver.c	(revision 503)
+++ /BAORadio/libindi/libindi/indidriver.c	(revision 504)
@@ -323,4 +323,5 @@
 void IUFillBLOB(IBLOB *bp, const char *name, const char * label, const char *format)
 {
+    memset(bp, 0, sizeof(IBLOB));
     strncpy(bp->name, name, MAXINDINAME);
     strncpy(bp->label, label, MAXINDILABEL);
@@ -341,5 +342,4 @@
   strncpy(svp->label, label, MAXINDILABEL);
   strncpy(svp->group, group, MAXINDIGROUP);
-  strcpy(svp->timestamp, "");
   
   svp->p	= p;
@@ -399,4 +399,5 @@
 void IUFillBLOBVector(IBLOBVectorProperty *bvp, IBLOB *bp, int nbp, const char * dev, const char *name, const char *label, const char* group, IPerm p, double timeout, IPState s)
 {
+    memset(bvp, 0, sizeof(IBLOBVectorProperty));
     strncpy(bvp->device, dev, MAXINDIDEVICE);
     strncpy(bvp->name, name, MAXINDINAME);
@@ -405,10 +406,9 @@
     strcpy(bvp->timestamp, "");
 
-  bvp->p	= p;
-  bvp->timeout	= timeout;
-  bvp->s	= s;
-  bvp->bp	= bp;
-  bvp->nbp	= nbp;
-
+    bvp->p	= p;
+    bvp->timeout	= timeout;
+    bvp->s	= s;
+    bvp->bp	= bp;
+    bvp->nbp	= nbp;
 }
 
Index: /BAORadio/libindi/libindi/indiserver.c
===================================================================
--- /BAORadio/libindi/libindi/indiserver.c	(revision 503)
+++ /BAORadio/libindi/libindi/indiserver.c	(revision 504)
@@ -84,11 +84,14 @@
     char dev[MAXINDIDEVICE];
     char name[MAXINDINAME];
+    BLOBHandling blob;			/* when to snoop BLOBs */
 } Property;
 
-/* record of each snooped property */
+
+/* record of each snooped property
 typedef struct {
     Property prop;
-    BLOBHandling blob;			/* when to snoop BLOBs */
-} Snoopee;
+    BLOBHandling blob;
+} Property;
+*/
 
 struct
@@ -119,5 +122,5 @@
     char dev[MAXINDIDEVICE];		/* device served by this driver */
     int active;				/* 1 when this record is in use */
-    Snoopee *sprops;			/* malloced array of props we snoop */
+    Property *sprops;			/* malloced array of props we snoop */
     int nsprops;			/* n entries in sprops[] */
     int pid;				/* process id or REMOTEDVR if remote */
@@ -163,6 +166,6 @@
     Msg *mp, XMLEle *root);
 static void addSDevice (DvrInfo *dp, const char *dev, const char *name);
-static Snoopee *findSDevice (DvrInfo *dp, const char *dev, const char *name);
-static void addClDevice (ClInfo *cp, const char *dev, const char *name);
+static Property *findSDevice (DvrInfo *dp, const char *dev, const char *name);
+static void addClDevice (ClInfo *cp, const char *dev, const char *name, int isblob);
 static int findClDevice (ClInfo *cp, const char *dev, const char *name);
 static int readFromDriver (DvrInfo *dp);
@@ -175,5 +178,6 @@
 static int sendClientMsg (ClInfo *cp);
 static int sendDriverMsg (DvrInfo *cp);
-static void crackBLOB (char *enableBLOB, BLOBHandling *bp);
+static void crackBLOB (const char *enableBLOB, BLOBHandling *bp);
+static void crackBLOBHandling(const char *dev, const char *name, const char *enableBLOB, ClInfo *cp);
 static void traceMsg (XMLEle *root);
 static char *indi_tstamp (char *s);
@@ -433,5 +437,5 @@
 	dp->lp = newLilXML();
         dp->msgq = newFQ(1);
-	dp->sprops = (Snoopee*) malloc (1);	/* seed for realloc */
+        dp->sprops = (Property*) malloc (1);	/* seed for realloc */
 	dp->nsprops = 0;
 	dp->nsent = 0;
@@ -484,5 +488,5 @@
 	dp->lp = newLilXML();
 	dp->msgq = newFQ(1);
-	dp->sprops = (Snoopee*) malloc (1);	/* seed for realloc */
+        dp->sprops = (Property*) malloc (1);	/* seed for realloc */
 	dp->nsprops = 0;
 	dp->nsent = 0;
@@ -737,5 +741,5 @@
     static char *envDev=NULL, *envConfig=NULL;
     const char *delm = " ";
-    char *token, *cp;
+    char *token, *cp, *tp;
     DvrInfo *dp = NULL;
     int startCmd=0;
@@ -748,5 +752,6 @@
     while ( fgets (line, MAXRBUF, fifo.fs) != NULL)
     {
-        //fprintf(stderr, "FIFO: %s\n", line);
+        fprintf(stderr, "FIFO: %s\n", line);
+
         tDev[0] = '\0', tDriver[0] = '\0', tConfig[0] = '\0', envDev[0] = '\0', envConfig[0] = '\0';
         cp = strdup(line);
@@ -756,4 +761,6 @@
         if (!strcmp(token, "start") || !strcmp(token, "stop"))
         {
+            //fprintf(stderr, "TOKEN: %s\n", token);
+
                 if (!strcmp(token, "start"))
                     startCmd = 1;
@@ -765,4 +772,6 @@
 
                strncpy(tDriver, token, MAXRBUF);
+               if (tp = strchr(tDriver, '\n'))
+                   *tp = '\0';
 
                if (verbose)
@@ -785,7 +794,8 @@
                      strcat(tDev, " ");
                      strncat(tDev, token, MAXRBUF);
-                     if (strstr(token, "\"") || strstr(token, "'"))
+                     if ( (tp=strchr(tDev, '\"')) || (tp=strchr(tDev, '\'')))
                      {
-                         tDev[strlen(tDev)-1] = '\0';
+                         //tDev[strlen(tDev)-1] = '\0';
+                         *tp='\0';
                          break;
                      }
@@ -793,5 +803,9 @@
                  }
                  else
+                {
                      strncpy(tDev, token, MAXRBUF);
+                     if (tp = strchr(tDev, '\n'))
+                         *tp = '\0';
+                 }
 
                   /* Find config, if there is any */
@@ -808,13 +822,18 @@
                           strncat(tConfig, token, MAXRBUF);
 
-                          if (strstr(token, "\"") || strstr(token, "'"))
+                          if ( (tp=strchr(tConfig, '\"')) || (tp=strchr(tConfig, '\'')))
                           {
-                                 tConfig[strlen(tConfig)-1] = '\0';
-                                 break;
+                                 //tConfig[strlen(tConfig)-1] = '\0';
+                              *tp = '\0';
+                              break;
                           }
                        }
                       }
                        else
+                      {
                            strncpy(tConfig, token, MAXRBUF);
+                           if (tp = strchr(tConfig, '\n'))
+                               *tp = '\0';
+                       }
                   }
               }
@@ -824,5 +843,8 @@
                {
                  snprintf(envDev, MAXRBUF, "INDIDEV=%s", tDev);
-                 //fprintf(stderr, "With name: %s\n", envDev);
+
+                 if (verbose)
+                    fprintf(stderr, "With name: %s\n", envDev);
+
                  putenv(envDev);
 
@@ -834,5 +856,8 @@
                {
                    snprintf(envConfig, MAXRBUF, "INDICONFIG=%s", tConfig);
-                   //fprintf(stderr, "With config: %s\n", envConfig);
+
+                   if (verbose)
+                    fprintf(stderr, "With config: %s\n", envConfig);
+
                    putenv(envConfig);
                }
@@ -978,5 +1003,5 @@
 		 */
 		if (dev[0])
-		    addClDevice (cp, dev, name);
+                    addClDevice (cp, dev, name, isblob);
 		else if (!strcmp (roottag, "getProperties") && !cp->nprops)
 		    cp->allprops = 1;
@@ -984,5 +1009,6 @@
 		/* snag enableBLOB -- send to remote drivers too */
 		if (!strcmp (roottag, "enableBLOB"))
-		    crackBLOB (pcdataXMLEle(root), &cp->blob);
+                   // crackBLOB (pcdataXMLEle(root), &cp->blob);
+                     crackBLOBHandling (dev, name, pcdataXMLEle(root), cp);
 
 		/* build a new message -- set content iff anyone cares */
@@ -1073,5 +1099,5 @@
 		/* that's all if driver is just registering a BLOB mode */
 		if (!strcmp (roottag, "enableBLOB")) {
-		    Snoopee *sp = findSDevice (dp, dev, name);
+                    Property *sp = findSDevice (dp, dev, name);
 		    if (sp)
 			crackBLOB (pcdataXMLEle (root), &sp->blob);
@@ -1094,5 +1120,5 @@
 
 		/* send to interested clients */
-		if (q2Clients (NULL, isblob, dev, name, mp, root) < 0)
+                if (q2Clients (NULL, isblob, dev, name, mp, root) < 0)
 		    shutany++;
 
@@ -1244,4 +1270,6 @@
 	for (dp = dvrinfo; dp < &dvrinfo[ndvrinfo]; dp++) {
 	    int isremote = (dp->pid == REMOTEDVR);
+            if (dp->active == 0)
+                continue;
 	    if (dev[0] && dp->dev[0] && strcmp (dev, dp->dev))
 		continue;	/* driver known to not support this dev */
@@ -1271,5 +1299,5 @@
 
 	for (dp = dvrinfo; dp < &dvrinfo[ndvrinfo]; dp++) {
-	    Snoopee *sp = findSDevice (dp, dev, name);
+            Property *sp = findSDevice (dp, dev, name);
 
 	    /* nothing for dp if not snooping for dev/name or wrong BLOB mode */
@@ -1297,5 +1325,5 @@
 addSDevice (DvrInfo *dp, const char *dev, const char *name)
 {
-	Snoopee *sp;
+        Property *sp;
 	char *ip;
 
@@ -1306,13 +1334,13 @@
 
 	/* add dev to sdevs list */
-	dp->sprops = (Snoopee*) realloc (dp->sprops,
-					    (dp->nsprops+1)*sizeof(Snoopee));
+        dp->sprops = (Property*) realloc (dp->sprops,
+                                            (dp->nsprops+1)*sizeof(Property));
 	sp = &dp->sprops[dp->nsprops++];
 
-	ip = sp->prop.dev;
+        ip = sp->dev;
 	strncpy (ip, dev, MAXINDIDEVICE-1);
 	ip[MAXINDIDEVICE-1] = '\0';
 
-	ip = sp->prop.name;
+        ip = sp->name;
 	strncpy (ip, name, MAXINDINAME-1);
 	ip[MAXINDINAME-1] = '\0';
@@ -1325,7 +1353,7 @@
 }
 
-/* return Snoopee if dp is snooping dev/name, else NULL.
- */
-static Snoopee *
+/* return Property if dp is snooping dev/name, else NULL.
+ */
+static Property *
 findSDevice (DvrInfo *dp, const char *dev, const char *name)
 {
@@ -1333,8 +1361,7 @@
 
 	for (i = 0; i < dp->nsprops; i++) {
-	    Snoopee *sp = &dp->sprops[i];
-	    Property *pp = &sp->prop;
-	    if (!strcmp (pp->dev, dev) &&
-		    (!pp->name[0] || !strcmp(pp->name, name)))
+            Property *sp = &dp->sprops[i];
+            if (!strcmp (sp->dev, dev) &&
+                    (!sp->name[0] || !strcmp(sp->name, name)))
 		return (sp);
 	}
@@ -1342,4 +1369,5 @@
 	return (NULL);
 }
+
 
 /* put Msg mp on queue of each client interested in dev/name, except notme.
@@ -1352,5 +1380,5 @@
 	int shutany = 0;
 	ClInfo *cp;
-	int ql;
+        int ql,i=0;
 
 	/* queue message to each interested client */
@@ -1359,8 +1387,33 @@
 	    if (!cp->active || cp == notme)
 		continue;
-	    if (findClDevice (cp, dev, name) < 0)
+            if (findClDevice (cp, dev, name) < 0)
 		continue;
-	    if ((isblob && cp->blob==B_NEVER) || (!isblob && cp->blob==B_ONLY))
-		continue;
+
+            //if ((isblob && cp->blob==B_NEVER) || (!isblob && cp->blob==B_ONLY))
+            if (!isblob && cp->blob==B_ONLY)
+                continue;
+
+            if (isblob)
+            {
+                if (cp->nprops > 0)
+                {
+                Property *pp = NULL;
+                int blob_found=0;
+                for (i = 0; i < cp->nprops; i++)
+                {
+                    pp = &cp->props[i];
+                    if (!strcmp (pp->dev, dev) && (!strcmp(pp->name, name)))
+                    {
+                        blob_found = 1;
+                        break;
+                    }
+                }
+
+                if ( (blob_found && pp->blob == B_NEVER) || (blob_found==0 && cp->blob == B_NEVER) )
+                    continue;
+               }
+               else if (cp->blob == B_NEVER)
+                   continue;
+           }
 
 	    /* shut down this client if its q is already too large */
@@ -1568,10 +1621,10 @@
 	int i;
 
-	if (cp->allprops || !dev[0])
+        if (cp->allprops || !dev[0])
 	    return (0);
-	for (i = 0; i < cp->nprops; i++) {
-	    Property *pp = &cp->props[i];
-	    if (!strcmp (pp->dev, dev) &&
-                                    (!pp->name[0] || !strcmp(pp->name, name)))
+        for (i = 0; i < cp->nprops; i++)
+        {
+            Property *pp = &cp->props[i];
+            if (!strcmp (pp->dev, dev) && (!pp->name[0] || !strcmp(pp->name, name)))
 		return (0);
 	}
@@ -1582,19 +1635,29 @@
  */
 static void
-addClDevice (ClInfo *cp, const char *dev, const char *name)
+addClDevice (ClInfo *cp, const char *dev, const char *name, int isblob)
 {
 	Property *pp;
 	char *ip;
-
+        int i=0;
+
+        if (isblob)
+        {
+            for (i = 0; i < cp->nprops; i++)
+            {
+                Property *pp = &cp->props[i];
+                if (!strcmp (pp->dev, dev) && (!pp->name[0] || !strcmp(pp->name, name)))
+                    return;
+            }
+        }
 	/* no dups */
-	if (!findClDevice (cp, dev, name))
+        else if (!findClDevice (cp, dev, name))
 	    return;
 
 	/* add */
 	cp->props = (Property *) realloc (cp->props,
-					    (cp->nprops+1)*sizeof(Property));
+                                            (cp->nprops+1)*sizeof(Property));
 	pp = &cp->props[cp->nprops++];
 
-	ip = pp->dev;
+        /*ip = pp->dev;
 	strncpy (ip, dev, MAXINDIDEVICE-1);
 	ip[MAXINDIDEVICE-1] = '\0';
@@ -1602,5 +1665,9 @@
 	ip = pp->name;
 	strncpy (ip, name, MAXINDINAME-1);
-	ip[MAXINDINAME-1] = '\0';
+        ip[MAXINDINAME-1] = '\0';*/
+
+        strncpy (pp->dev, dev, MAXINDIDEVICE);
+        strncpy (pp->name, name, MAXINDINAME);
+        pp->blob = B_NEVER;
 }
 
@@ -1632,5 +1699,5 @@
  */
 static void
-crackBLOB (char *enableBLOB, BLOBHandling *bp)
+crackBLOB (const char *enableBLOB, BLOBHandling *bp)
 {
 	if (!strcmp (enableBLOB, "Also"))
@@ -1640,4 +1707,31 @@
 	else if (!strcmp (enableBLOB, "Never"))
 	    *bp = B_NEVER;
+}
+
+/* Update the client property BLOB handling policy */
+static void crackBLOBHandling(const char *dev, const char *name, const char *enableBLOB, ClInfo *cp)
+{
+    int i=0;
+
+    /* If we have EnableBLOB with property name, we add it to Client device list */
+    if (name[0])
+        addClDevice (cp, dev, name, 1);
+    else
+    /* Otherwise, we set the whole client blob handling to what's passed (enableBLOB) */
+        crackBLOB(enableBLOB, &cp->blob);
+
+    /* If whole client blob handling policy was updated, we need to pass that also to all children
+       and if the request was for a specific property, then we apply the policy to it */
+    for (i = 0; i < cp->nprops; i++)
+    {
+        Property *pp = &cp->props[i];
+        if (!name[0])           
+            crackBLOB(enableBLOB, &pp->blob);
+        else if (!strcmp (pp->dev, dev) && (!strcmp(pp->name, name)))
+        {
+            crackBLOB(enableBLOB, &pp->blob);
+            return;
+        }
+    }
 }
 
Index: /BAORadio/libindi/libindi/libs/indibase/baseclient.cpp
===================================================================
--- /BAORadio/libindi/libindi/libs/indibase/baseclient.cpp	(revision 503)
+++ /BAORadio/libindi/libindi/libs/indibase/baseclient.cpp	(revision 504)
@@ -20,4 +20,6 @@
     cServer = "localhost";
     cPort   = 7624;
+    svrwfp = NULL;    
+    sConnected = false;
 
 }
@@ -26,7 +28,5 @@
 INDI::BaseClient::~BaseClient()
 {
-
-    disconnect();
-
+    close(sockfd);
 }
 
@@ -43,5 +43,5 @@
 }
 
-bool INDI::BaseClient::connect()
+bool INDI::BaseClient::connectServer()
 {
     struct sockaddr_in serv_addr;
@@ -76,5 +76,4 @@
     /* prepare for line-oriented i/o with client */
     svrwfp = fdopen (sockfd, "w");
-    svrrfp = fdopen (sockfd, "r");
 
     int result = pthread_create( &listen_thread, NULL, &INDI::BaseClient::listenHelper, this);
@@ -86,30 +85,82 @@
     }
 
+    serverConnected();
+    sConnected = true;
+
     return true;
 }
 
-void INDI::BaseClient::disconnect()
-{
-    char errmsg[MAXRBUF];
-    removeDevice(NULL, errmsg);
-    if (lillp)
-        delLilXML(lillp);
-    lillp = NULL;
-    pthread_cancel(listen_thread);
-    close(sockfd);
-    if (svrwfp)
+bool INDI::BaseClient::disconnectServer()
+{
+    if (sConnected == false)
+        return true;
+
+    if (svrwfp != NULL)
         fclose(svrwfp);
-    svrwfp = NULL;
-    if (svrrfp)
-        fclose(svrrfp);
-    svrrfp = NULL;
-}
-
-INDI::BaseDriver * INDI::BaseClient::getDevice(const char * deviceName)
-{
-    vector<INDI::BaseDriver *>::const_iterator devi;
+   svrwfp = NULL;
+
+   close(sockfd);
+
+    serverDisconnected();
+
+    sConnected = false;
+
+    return true;
+}
+
+
+void INDI::BaseClient::setDriverConnection(bool status, const char *deviceName)
+{
+    INDI::BaseDriver *drv = getDriver(deviceName);
+    ISwitchVectorProperty *drv_connection = NULL;
+
+    if (drv == NULL)
+    {
+        IDLog("INDI::BaseClient: Error. Unable to find driver %s\n", deviceName);
+        return;
+    }
+
+    drv_connection = drv->getSwitch("CONNECTION");
+
+    if (drv_connection == NULL)
+        return;
+
+    // If we need to connect
+    if (status)
+    {
+        // If there is no need to do anything, i.e. already connected.
+        if (drv_connection->sp[0].s == ISS_ON)
+            return;
+
+        IUResetSwitch(drv_connection);
+        drv_connection->s = IPS_BUSY;
+        drv_connection->sp[0].s = ISS_ON;
+        drv_connection->sp[1].s = ISS_OFF;
+
+        sendNewSwitch(drv_connection, &(drv_connection->sp[0]));
+    }
+    else
+    {
+        // If there is no need to do anything, i.e. already disconnected.
+        if (drv_connection->sp[1].s == ISS_ON)
+            return;
+
+        IUResetSwitch(drv_connection);
+        drv_connection->s = IPS_BUSY;
+        drv_connection->sp[0].s = ISS_OFF;
+        drv_connection->sp[1].s = ISS_ON;
+
+        sendNewSwitch(drv_connection, &(drv_connection->sp[1]));
+
+    }
+}
+
+
+INDI::BaseDriver * INDI::BaseClient::getDriver(const char * deviceName)
+{
+    vector<devicePtr>::const_iterator devi;
     for ( devi = cDevices.begin(); devi != cDevices.end(); devi++)
         if (!strcmp(deviceName, (*devi)->deviceName()))
-            return (*devi);
+            return (*devi).get();
 
     return NULL;
@@ -141,15 +192,12 @@
 
     /* read from server, exit if find all requested properties */
-    while (1)
-    {
-        n = fread(buffer, 1, MAXINDIBUF, svrrfp);
+    while (sConnected)
+    {
+        n = read(sockfd, buffer, MAXINDIBUF);
 
         if (n ==0)
         {
-            if (ferror(svrrfp))
-                perror ("read");
-            else
-                fprintf (stderr,"INDI server %s/%d disconnected\n", cServer.c_str(), cPort);
-
+            perror ("read");
+            fprintf (stderr,"INDI server %s/%d disconnected\n", cServer.c_str(), cPort);
             serverDisconnected();
             return;
@@ -180,4 +228,5 @@
         }
     }
+
 }
 
@@ -242,12 +291,12 @@
 int INDI::BaseClient::removeDevice( const char * devName, char * errmsg )
 {
-    std::vector<INDI::BaseDriver *>::iterator devicei = cDevices.begin();
+    std::vector<devicePtr>::iterator devicei = cDevices.begin();
 
     while (devicei != cDevices.end())
     {
-      if (devName == NULL || !strcmp(devName, (*devicei)->deviceName()))
+      if (strcmp(devName, (*devicei)->deviceName()))
       {
           cDevices.erase(devicei);
-          delete (*devicei);
+          //delete (*devicei);
           return 0;
       }
@@ -263,10 +312,10 @@
 {
 
-    std::vector<INDI::BaseDriver *>::const_iterator devicei;
+    std::vector<devicePtr>::const_iterator devicei;
 
     for (devicei = cDevices.begin(); devicei != cDevices.end(); devicei++)
     {
         if (!strcmp(devName, (*devicei)->deviceName()))
-         return (*devicei);
+         return (*devicei).get();
 
     }
@@ -279,5 +328,5 @@
 INDI::BaseDriver * INDI::BaseClient::addDevice (XMLEle *dep, char * errmsg)
 {
-    INDI::BaseDriver *dp;
+    devicePtr dp(new INDI::BaseDriver());
     XMLAtt *ap;
     char * device_name;
@@ -293,5 +342,4 @@
     device_name = valuXMLAtt(ap);
 
-    dp = new INDI::BaseDriver();
     dp->setMediator(this);
     dp->setDeviceName(device_name);
@@ -299,8 +347,8 @@
     cDevices.push_back(dp);
 
-    newDevice();
+    newDevice(device_name);
 
     /* ok */
-    return dp;
+    return dp.get();
 }
 
@@ -467,16 +515,13 @@
 void INDI::BaseClient::setBLOBMode(BLOBHandling blobH, const char *dev, const char *prop)
 {
-    char blobOpenTag[64];
-
-    if (dev)
-    {
-        if (prop)
-            snprintf(blobOpenTag, 64, "<enableBLOB device='%s' name='%s'>", dev, prop);
-        else
-            snprintf(blobOpenTag, 64, "<enableBLOB device='%s'>", dev);
-    }
-    else
-        snprintf(blobOpenTag, 64, "<enableBLOB>", dev, prop);
-
+    char blobOpenTag[MAXRBUF];
+
+    if (!dev[0])
+        return;
+
+   if (prop != NULL)
+           snprintf(blobOpenTag, MAXRBUF, "<enableBLOB device='%s' name='%s'>", dev, prop);
+   else
+          snprintf(blobOpenTag, MAXRBUF, "<enableBLOB device='%s'>", dev);
 
     switch (blobH)
Index: /BAORadio/libindi/libindi/libs/indibase/baseclient.h
===================================================================
--- /BAORadio/libindi/libindi/libs/indibase/baseclient.h	(revision 503)
+++ /BAORadio/libindi/libindi/libs/indibase/baseclient.h	(revision 504)
@@ -4,4 +4,5 @@
 #include <vector>
 #include <map>
+#include <boost/shared_ptr.hpp>
 #include <string>
 
@@ -32,7 +33,8 @@
 public:
     enum { INDI_DEVICE_NOT_FOUND=-1, INDI_PROPERTY_INVALID=-2, INDI_PROPERTY_DUPLICATED = -3, INDI_DISPATCH_ERROR=-4 };
+    typedef boost::shared_ptr<INDI::BaseDriver> devicePtr;
 
     BaseClient();
-    virtual ~BaseClient();
+    ~BaseClient();
 
     /** \brief Set the server host name and port
@@ -57,21 +59,28 @@
         \note This function blocks until connection is either successull or unsuccessful.
     */
-    bool connect();
+    bool connectServer();
 
     /** \brief Disconnect from INDI server.
 
         Disconnects from INDI servers. Any devices previously created will be deleted and memory cleared.
+        \return True if disconnection is successful, false otherwise.
     */
-    void disconnect();
+    bool disconnectServer();
 
+    /** \brief Connect/Disconnect to INDI driver
+        \param status If true, the client will attempt to turn on CONNECTION property within the driver (i.e. turn on the device).
+         Otherwise, CONNECTION will be turned off.
+        \param deviceName Name of the device to connect to.
+    */
+    void setDriverConnection(bool status, const char *deviceName);
 
     /** \param deviceName Name of device to search for in the list of devices owned by INDI server,
          \returns If \e deviceName exists, it returns an instance of the device. Otherwise, it returns NULL.
     */
-    INDI::BaseDriver * getDevice(const char * deviceName);
+    INDI::BaseDriver * getDriver(const char * deviceName);
 
     /** \returns Returns a vector of all devices created in the client.
     */
-    const vector<INDI::BaseDriver *> & getDevices() const { return cDevices; }
+    const vector<devicePtr> & getDrivers() const { return cDevices; }
 
     /** \brief Set Binary Large Object policy mode
@@ -86,11 +95,11 @@
       If \e dev and \e prop are supplied, then the BLOB handling policy is set for this particular device and property.
       if \e prop is NULL, then the BLOB policy applies to the whole device.
-      if \e dev is NULL, then the BLOB policy applies to all devices owned by INDI server.
+
 
       \param blobH BLOB handling policy
-      \param dev name of device
-      \param prop name of property
+      \param dev name of device, required.
+      \param prop name of property, optional.
     */
-    void setBLOBMode(BLOBHandling blobH, const char *dev = NULL, const char *prop = NULL);
+    void setBLOBMode(BLOBHandling blobH, const char *dev, const char *prop = NULL);
 
     // Update
@@ -143,9 +152,10 @@
     pthread_t listen_thread;
 
-    vector<INDI::BaseDriver *> cDevices;
+    vector<devicePtr> cDevices;
     vector<string> cDeviceNames;
 
     string cServer;
     unsigned int cPort;
+    bool sConnected;
 
     // Parse & FILE buffers for IO
@@ -153,5 +163,4 @@
     LilXML *lillp;			/* XML parser context */
     FILE *svrwfp;			/* FILE * to talk to server */
-    FILE *svrrfp;			/* FILE * to read from server */
 
 };
Index: /BAORadio/libindi/libindi/libs/indibase/basedriver.cpp
===================================================================
--- /BAORadio/libindi/libindi/libs/indibase/basedriver.cpp	(revision 503)
+++ /BAORadio/libindi/libindi/libs/indibase/basedriver.cpp	(revision 504)
@@ -13,4 +13,10 @@
     mediator = NULL;
     lp = newLilXML();
+
+    if (getenv("INDIDEV") != NULL)
+    {
+        strncpy(deviceID, getenv("INDIDEV"), MAXINDINAME);
+        putenv("INDIDEV=");
+    }
 }
 
@@ -18,90 +24,55 @@
 INDI::BaseDriver::~BaseDriver()
 {
-    std::vector<INumberVectorProperty *>::const_iterator numi;
-    std::vector<ISwitchVectorProperty *>::const_iterator switchi;
-    std::vector<ITextVectorProperty *>::const_iterator texti;
-    std::vector<ILightVectorProperty *>::const_iterator lighti;
-    std::vector<IBLOBVectorProperty *>::const_iterator blobi;
-
     delLilXML (lp);
-    pAll.clear();
-
-    for ( numi = pNumbers.begin(); numi != pNumbers.end(); numi++)
-        delete (*numi);
-
-   for ( switchi = pSwitches.begin(); switchi != pSwitches.end(); switchi++)
-        delete (*switchi);
-
-   for ( texti = pTexts.begin(); texti != pTexts.end(); texti++)
-        delete (*texti);
-
-   for ( lighti = pLights.begin(); lighti != pLights.end(); lighti++)
-        delete (*lighti);
-
-   for ( blobi = pBlobs.begin(); blobi != pBlobs.end(); blobi++)
-        delete (*blobi);
 }
 
 INumberVectorProperty * INDI::BaseDriver::getNumber(const char *name)
 {
-    std::vector<INumberVectorProperty *>::const_iterator numi;
-
-    for ( numi = pNumbers.begin(); numi != pNumbers.end(); numi++)
-        if (!strcmp(name, (*numi)->name))
-            return *numi;
-
-    return NULL;
-
+    INumberVectorProperty * nvp = NULL;
+
+    nvp = static_cast<INumberVectorProperty *> (getProperty(name, INDI_NUMBER));
+
+    return nvp;
 }
 
 ITextVectorProperty * INDI::BaseDriver::getText(const char *name)
 {
-    std::vector<ITextVectorProperty *>::const_iterator texti;
-
-    for ( texti = pTexts.begin(); texti != pTexts.end(); texti++)
-        if (!strcmp(name, (*texti)->name))
-            return *texti;
-
-    return NULL;
+    ITextVectorProperty * tvp = NULL;
+
+    tvp = static_cast<ITextVectorProperty *> (getProperty(name, INDI_TEXT));
+
+    return tvp;
 }
 
 ISwitchVectorProperty * INDI::BaseDriver::getSwitch(const char *name)
 {
-    std::vector<ISwitchVectorProperty *>::const_iterator switchi;
-
-    for ( switchi = pSwitches.begin(); switchi != pSwitches.end(); switchi++)
-        if (!strcmp(name, (*switchi)->name))
-            return *switchi;
-
-    return NULL;
-
+    ISwitchVectorProperty * svp = NULL;
+
+    svp = static_cast<ISwitchVectorProperty *> (getProperty(name, INDI_SWITCH));
+
+    return svp;
 }
 
 ILightVectorProperty * INDI::BaseDriver::getLight(const char *name)
 {
-    std::vector<ILightVectorProperty *>::const_iterator lighti;
-
-    for ( lighti = pLights.begin(); lighti != pLights.end(); lighti++)
-        if (!strcmp(name, (*lighti)->name))
-            return *lighti;
-
-    return NULL;
-
+    ILightVectorProperty * lvp = NULL;
+
+    lvp = static_cast<ILightVectorProperty *> (getProperty(name, INDI_LIGHT));
+
+    return lvp;
 }
 
 IBLOBVectorProperty * INDI::BaseDriver::getBLOB(const char *name)
-{
-    std::vector<IBLOBVectorProperty *>::const_iterator blobi;
-
-    for ( blobi = pBlobs.begin(); blobi != pBlobs.end(); blobi++)
-        if (!strcmp(name, (*blobi)->name))
-            return *blobi;
-
-    return NULL;
-}
-
-void * INDI::BaseDriver::getProperty(const char *name, INDI_TYPE & type)
-{
-    std::vector<pOrder>::const_iterator orderi;
+{       
+  IBLOBVectorProperty * bvp = NULL;
+
+  bvp = static_cast<IBLOBVectorProperty *> (getProperty(name, INDI_BLOB));
+
+  return bvp;
+}
+
+void * INDI::BaseDriver::getProperty(const char *name, INDI_TYPE type)
+{
+    std::map< boost::shared_ptr<void>, INDI_TYPE>::iterator orderi;
 
     INumberVectorProperty *nvp;
@@ -110,52 +81,39 @@
     ILightVectorProperty *lvp;
     IBLOBVectorProperty *bvp;
-    int i=0;
-
-    for (i=0, orderi = pAll.begin(); orderi != pAll.end(); orderi++, i++)
-    {
-        switch ( (*orderi).type)
+
+    for (orderi = pAll.begin(); orderi != pAll.end(); orderi++)
+    {
+        if (type != INDI_UNKNOWN &&  orderi->second != type)
+            continue;
+
+        switch (orderi->second)
         {
         case INDI_NUMBER:
-            nvp = static_cast<INumberVectorProperty *>((*orderi).p);
+            nvp = static_cast<INumberVectorProperty *>((orderi->first).get());
             if (!strcmp(name, nvp->name))
-            {
-                type = INDI_NUMBER;
-                return (*orderi).p;
-            }
-
+                return (orderi->first).get();
              break;
         case INDI_TEXT:
-             tvp = static_cast<ITextVectorProperty *>((*orderi).p);
+             tvp = static_cast<ITextVectorProperty *>((orderi->first).get());
              if (!strcmp(name, tvp->name))
-             {
-                 type = INDI_TEXT;
-                 return (*orderi).p;
-             }
+                return (orderi->first).get();
              break;
         case INDI_SWITCH:
-             svp = static_cast<ISwitchVectorProperty *>((*orderi).p);
+             svp = static_cast<ISwitchVectorProperty *>((orderi->first).get());
              if (!strcmp(name, svp->name))
-             {
-                 type = INDI_SWITCH;
-                 return (*orderi).p;
-             }
+                 return (orderi->first).get();
              break;
         case INDI_LIGHT:
-             lvp = static_cast<ILightVectorProperty *>((*orderi).p);
+             lvp = static_cast<ILightVectorProperty *>((orderi->first).get());
              if (!strcmp(name, lvp->name))
-             {
-                 type = INDI_LIGHT;
-                 return (*orderi).p;
-             }
+                 return (orderi->first).get();
              break;
         case INDI_BLOB:
-             bvp = static_cast<IBLOBVectorProperty *>((*orderi).p);
+             bvp = static_cast<IBLOBVectorProperty *>((orderi->first).get());
              if (!strcmp(name, bvp->name))
-             {
-                 type = INDI_BLOB;
-                 return (*orderi).p;
-             }
+                 return (orderi->first).get();
              break;
         }
+
     }
 
@@ -165,5 +123,5 @@
 int INDI::BaseDriver::removeProperty(const char *name)
 {
-    std::vector<pOrder>::iterator orderi;
+    std::map< boost::shared_ptr<void>, INDI_TYPE>::iterator orderi;
 
     INumberVectorProperty *nvp;
@@ -175,48 +133,43 @@
     for (orderi = pAll.begin(); orderi != pAll.end(); orderi++)
     {
-        switch ( (*orderi).type)
+        switch (orderi->second)
         {
         case INDI_NUMBER:
-            nvp = static_cast<INumberVectorProperty *>((*orderi).p);
+            nvp = static_cast<INumberVectorProperty *>((orderi->first).get());
             if (!strcmp(name, nvp->name))
             {
                  pAll.erase(orderi);
-                 delete (nvp);
                  return 0;
              }
              break;
         case INDI_TEXT:
-             tvp = static_cast<ITextVectorProperty *>((*orderi).p);
+             tvp = static_cast<ITextVectorProperty *>((orderi->first).get());
              if (!strcmp(name, tvp->name))
              {
                   pAll.erase(orderi);
-                  delete (tvp);
                   return 0;
               }
              break;
         case INDI_SWITCH:
-             svp = static_cast<ISwitchVectorProperty *>((*orderi).p);
+             svp = static_cast<ISwitchVectorProperty *>((orderi->first).get());
              if (!strcmp(name, svp->name))
              {
                   pAll.erase(orderi);
-                  delete (svp);
                   return 0;
               }
              break;
         case INDI_LIGHT:
-             lvp = static_cast<ILightVectorProperty *>((*orderi).p);
+             lvp = static_cast<ILightVectorProperty *>((orderi->first).get());
              if (!strcmp(name, lvp->name))
              {
                   pAll.erase(orderi);
-                  delete (lvp);
                   return 0;
               }
              break;
         case INDI_BLOB:
-             bvp = static_cast<IBLOBVectorProperty *>((*orderi).p);
+             bvp = static_cast<IBLOBVectorProperty *>((orderi->first).get());
              if (!strcmp(name, bvp->name))
              {
                   pAll.erase(orderi);
-                  delete (bvp);
                   return 0;
               }
@@ -255,8 +208,5 @@
             buildProp(root, errmsg);
 
-
-
     /**************************************************************************/
-
 }
 
@@ -268,5 +218,5 @@
     XMLEle *ep = NULL;
     char *rtag, *rname, *rdev;
-    INDI_TYPE type;
+    //INDI_TYPE type;
     double timeout=0;
 
@@ -277,5 +227,5 @@
         return -1;
 
-    if (!deviceID[0])
+   /* if (!deviceID[0])
     {
         if (getenv("INDIDEV"))
@@ -283,12 +233,16 @@
         else
             strncpy(deviceID, rdev, MAXINDINAME);
-    }
-
-    if (getProperty(rname, type) != NULL)
+    }*/
+
+    if (!deviceID[0])
+        strncpy(deviceID, rdev, MAXINDINAME);
+
+    //if (getProperty(rname, type) != NULL)
+    if (getProperty(rname) != NULL)
         return INDI::BaseClient::INDI_PROPERTY_DUPLICATED;
 
-    if (crackIPerm(findXMLAttValu(root, "perm"), &perm) < 0)
-    {
-        IDLog("Error extracting %s permission (%s)", rname, findXMLAttValu(root, "perm"));
+    if (strcmp (rtag, "defLightVector") && crackIPerm(findXMLAttValu(root, "perm"), &perm) < 0)
+    {
+        IDLog("Error extracting %s permission (%s)\n", rname, findXMLAttValu(root, "perm"));
         return -1;
     }
@@ -298,5 +252,5 @@
     if (crackIPState (findXMLAttValu(root, "state"), &state) < 0)
     {
-        IDLog("Error extracting %s state (%s)", rname, findXMLAttValu(root, "state"));
+        IDLog("Error extracting %s state (%s)\n", rname, findXMLAttValu(root, "state"));
         return -1;
     }
@@ -305,5 +259,7 @@
     {
 
-        INumberVectorProperty *nvp = new INumberVectorProperty;
+        numberPtr nvp(new INumberVectorProperty);
+        //INumberVectorProperty *nvp = new INumberVectorProperty;
+        //INumberVectorProperty *nvp = (INumberVectorProperty *) malloc(sizeof(INumberVectorProperty));
         INumber *np = NULL;
         int n=0;
@@ -325,5 +281,5 @@
             np = (INumber *) realloc(np, (n+1) * sizeof(INumber));
 
-            np[n].nvp = nvp;
+            np[n].nvp = nvp.get();
 
             XMLAtt *na = findXMLAtt (ep, "name");
@@ -364,8 +320,12 @@
         nvp->nnp = n;
         nvp->np  = np;
-        pNumbers.push_back(nvp);
-        pOrder o = { INDI_NUMBER, nvp };
-        pAll.push_back(o);
-        IDLog("Adding number property %s to list.\n", nvp->name);
+        //orderPtr o(new pOrder);
+        //o->p = &nvp;
+        //o->type = INDI_NUMBER;
+        //pAll.push_back(o);
+        pAll[nvp] = INDI_NUMBER;
+        //IDLog("Adding number property %s to list.\n", nvp->name);
+        if (mediator)
+            mediator->newProperty(nvp->device, nvp->name);
     }
     else
@@ -374,5 +334,7 @@
   else if (!strcmp (rtag, "defSwitchVector"))
         {
-            ISwitchVectorProperty *svp = new ISwitchVectorProperty;
+            switchPtr svp(new ISwitchVectorProperty);
+            //ISwitchVectorProperty *svp = new ISwitchVectorProperty;
+            //ISwitchVectorProperty *svp = (ISwitchVectorProperty *) malloc(sizeof(ISwitchVectorProperty));
             ISwitch *sp = NULL;
             int n=0;
@@ -398,5 +360,5 @@
                 sp = (ISwitch *) realloc(sp, (n+1) * sizeof(ISwitch));
 
-                sp[n].svp = svp;
+                sp[n].svp = svp.get();
 
                 XMLAtt *na = findXMLAtt (ep, "name");
@@ -418,8 +380,12 @@
             svp->nsp = n;
             svp->sp  = sp;
-            pSwitches.push_back(svp);
-            pOrder o = { INDI_SWITCH, svp };
-            pAll.push_back(o);
-            IDLog("Adding Switch property %s to list.\n", svp->name);
+            //orderPtr o(new pOrder);
+            //o->p = &svp;
+            //o->type = INDI_SWITCH;
+            //pAll.push_back(o);
+            pAll[svp] = INDI_SWITCH;
+            //IDLog("Adding Switch property %s to list.\n", svp->name);
+            if (mediator)
+                mediator->newProperty(svp->device, svp->name);
         }
         else
@@ -430,5 +396,7 @@
     {
 
-        ITextVectorProperty *tvp = new ITextVectorProperty;
+        //ITextVectorProperty *tvp = new ITextVectorProperty;
+        //ITextVectorProperty *tvp = (ITextVectorProperty *) malloc(sizeof(ITextVectorProperty));
+        textPtr tvp(new ITextVectorProperty);
         IText *tp = NULL;
         int n=0;
@@ -450,5 +418,5 @@
             tp = (IText *) realloc(tp, (n+1) * sizeof(IText));
 
-            tp[n].tvp = tvp;
+            tp[n].tvp = tvp.get();
 
             XMLAtt *na = findXMLAtt (ep, "name");
@@ -471,8 +439,12 @@
         tvp->ntp = n;
         tvp->tp  = tp;
-        pTexts.push_back(tvp);
-        pOrder o = { INDI_TEXT, tvp };
-        pAll.push_back(o);
-        IDLog("Adding Text property %s to list.\n", tvp->name);
+        //orderPtr o(new pOrder);
+        //o->p = &tvp;
+        //o->type = INDI_TEXT;
+        //pAll.push_back(o);
+        pAll[tvp] = INDI_TEXT;
+        //IDLog("Adding Text property %s to list.\n", tvp->name);
+        if (mediator)
+            mediator->newProperty(tvp->device, tvp->name);
     }
     else
@@ -482,5 +454,7 @@
     {
 
-        ILightVectorProperty *lvp = new ILightVectorProperty;
+        //ILightVectorProperty *lvp = new ILightVectorProperty;
+        //ILightVectorProperty *lvp = (ILightVectorProperty *) malloc(sizeof(ILightVectorProperty));
+        lightPtr lvp(new ILightVectorProperty);
         ILight *lp = NULL;
         int n=0;
@@ -500,5 +474,5 @@
             lp = (ILight *) realloc(lp, (n+1) * sizeof(ILight));
 
-            lp[n].lvp = lvp;
+            lp[n].lvp = lvp.get();
 
             XMLAtt *na = findXMLAtt (ep, "name");
@@ -521,8 +495,12 @@
         lvp->nlp = n;
         lvp->lp  = lp;
-        pLights.push_back(lvp);
-        pOrder o = { INDI_LIGHT, lvp };
-        pAll.push_back(o);
-        IDLog("Adding Light property %s to list.\n", lvp->name);
+        //orderPtr o(new pOrder);
+        //o->p = &lvp;
+        //o->type = INDI_LIGHT;
+        //pAll.push_back(o);
+        pAll[lvp] = INDI_LIGHT;
+        //IDLog("Adding Light property %s to list.\n", lvp->name);
+        if (mediator)
+            mediator->newProperty(lvp->device, lvp->name);
     }
     else
@@ -532,5 +510,7 @@
     {
 
-        IBLOBVectorProperty *bvp = new IBLOBVectorProperty;
+        //IBLOBVectorProperty *bvp = new IBLOBVectorProperty;
+        //IBLOBVectorProperty *bvp = (IBLOBVectorProperty *) malloc(sizeof(IBLOBVectorProperty));
+        blobPtr bvp(new IBLOBVectorProperty);
         IBLOB *bp = NULL;
         int n=0;
@@ -550,5 +530,5 @@
             bp = (IBLOB *) realloc(bp, (n+1) * sizeof(IBLOB));
 
-            bp[n].bvp = bvp;
+            bp[n].bvp = bvp.get();
 
             XMLAtt *na = findXMLAtt (ep, "name");
@@ -580,8 +560,12 @@
         bvp->nbp = n;
         bvp->bp  = bp;
-        pBlobs.push_back(bvp);
-        pOrder o = { INDI_BLOB, bvp };
-        pAll.push_back(o);
-        IDLog("Adding BLOB property %s to list.\n", bvp->name);
+        //orderPtr o(new pOrder);
+        //o->p = &bvp;
+        //o->type = INDI_BLOB;
+        //pAll.push_back(o);
+        pAll[bvp] = INDI_BLOB;
+        //IDLog("Adding BLOB property %s to list.\n", bvp->name);
+        if (mediator)
+            mediator->newProperty(bvp->device, bvp->name);
     }
     else
@@ -609,33 +593,4 @@
         return false;
 
-}
-
-void INDI::BaseDriver::setConnected(bool status)
-{
-    ISwitch *sp = NULL;
-    ISwitchVectorProperty *svp = getSwitch("CONNECTION");
-    if (!svp)
-        return;
-
-    IUResetSwitch(svp);
-
-    // Connect
-    if (status)
-    {
-        sp = IUFindSwitch(svp, "CONNECT");
-        if (!sp)
-            return;
-        sp->s = ISS_ON;
-    }
-    // Disconnect
-    else
-    {
-        sp = IUFindSwitch(svp, "DISCONNECT");
-        if (!sp)
-            return;
-        sp->s = ISS_ON;
-    }
-
-    svp->s = IPS_OK;
 }
 
@@ -958,2 +913,64 @@
 }
 
+void INDI::BaseDriver::registerProperty(void *p, INDI_TYPE type)
+{
+
+
+    if (type == INDI_NUMBER)
+    {
+        INumberVectorProperty *nvp = static_cast<INumberVectorProperty *> (p);
+        if (getProperty(nvp->name, INDI_NUMBER) != NULL)
+            return;
+
+        numberPtr ovp(nvp);
+
+        pAll[ovp] = INDI_NUMBER;
+    }
+    else if (type == INDI_TEXT)
+    {
+       ITextVectorProperty *tvp = static_cast<ITextVectorProperty *> (p);
+       if (getProperty(tvp->name, INDI_TEXT) != NULL)
+           return;
+
+       textPtr ovp(tvp);
+       //o->p = &ovp;
+
+       pAll[ovp] = INDI_TEXT;
+   }
+    else if (type == INDI_SWITCH)
+    {
+       ISwitchVectorProperty *svp = static_cast<ISwitchVectorProperty *> (p);
+       if (getProperty(svp->name, INDI_SWITCH) != NULL)
+           return;
+
+       switchPtr ovp(svp);
+       //o->p = &ovp;
+
+       IDLog("Registering switch %s\n", svp->name);
+
+       pAll[ovp] = INDI_SWITCH;
+    }
+    else if (type == INDI_LIGHT)
+    {
+       ILightVectorProperty *lvp = static_cast<ILightVectorProperty *> (p);
+       if (getProperty(lvp->name, INDI_LIGHT) != NULL)
+           return;
+
+       lightPtr ovp(lvp);
+       //o->p = &ovp;
+       pAll[ovp] = INDI_LIGHT;
+   }
+    else if (type == INDI_BLOB)
+    {
+       IBLOBVectorProperty *bvp = static_cast<IBLOBVectorProperty *> (p);
+       if (getProperty(bvp->name, INDI_BLOB) != NULL)
+           return;
+
+       blobPtr ovp(bvp);
+       //o->p = &ovp;
+
+       pAll[ovp] = INDI_BLOB;
+    }
+
+}
+
Index: /BAORadio/libindi/libindi/libs/indibase/basedriver.h
===================================================================
--- /BAORadio/libindi/libindi/libs/indibase/basedriver.h	(revision 503)
+++ /BAORadio/libindi/libindi/libs/indibase/basedriver.h	(revision 504)
@@ -2,5 +2,5 @@
 #define INDIBASEDRIVER_H
 
-#include <vector>
+#include <boost/shared_ptr.hpp>
 #include <map>
 #include <string>
@@ -26,5 +26,5 @@
 public:
     BaseDriver();
-    virtual ~BaseDriver();
+    ~BaseDriver();
 
     /*! INDI error codes. */
@@ -38,5 +38,5 @@
 
     /*! INDI property type */
-    enum INDI_TYPE
+    typedef enum
     {
         INDI_NUMBER, /*!< INumberVectorProperty. */
@@ -44,6 +44,7 @@
         INDI_TEXT,   /*!< ITextVectorProperty. */
         INDI_LIGHT,  /*!< ILightVectorProperty. */
-        INDI_BLOB    /*!< IBLOBVectorProperty. */
-    };
+        INDI_BLOB,    /*!< IBLOBVectorProperty. */
+        INDI_UNKNOWN
+    } INDI_TYPE;
 
     /** \return Return vector number property given its name */
@@ -57,4 +58,6 @@
     /** \return Return vector BLOB property given its name */
     IBLOBVectorProperty * getBLOB(const char *name);
+
+    void registerProperty(void *p, INDI_TYPE type);
 
     /** \brief Remove a property
@@ -74,5 +77,5 @@
 
     */
-    void * getProperty(const char *name, INDI_TYPE & type);
+    void * getProperty(const char *name, INDI_TYPE type = INDI_UNKNOWN);
 
     /** \brief Build driver properties from a skeleton file.
@@ -90,9 +93,5 @@
     /** \return True if the device is connected (CONNECT=ON), False otherwise */
     bool isConnected();
-    /** \brief Connect or Disconnect a device.
-      \param status If true, the driver will attempt to connect to the device (CONNECT=ON). If false, it will attempt
-to disconnect the device.
-    */
-    virtual void setConnected(bool status);
+
 
     /** \brief Set the device name
@@ -100,4 +99,5 @@
       */
     void setDeviceName(const char *dev);
+
     /** \return Returns the device name */
     const char *deviceName();
@@ -107,11 +107,14 @@
     */
     void addMessage(const char *msg);
-    //** \returns Returns the contents of the driver's message queue. *;
+
+    /** \return Returns the contents of the driver's message queue. */
     const char *message() { return messageQueue.c_str(); }
 
     /** \brief Set the driver's mediator to receive notification of news devices and updated property values. */
     void setMediator(INDI::BaseMediator *med) { mediator = med; }
+
     /** \returns Get the meditator assigned to this driver */
     INDI::BaseMediator * getMediator() { return mediator; }
+
 
 protected:
@@ -120,5 +123,4 @@
       \param root XML element to parse and build.
       \param errmsg buffer to store error message in parsing fails.
-
       \return 0 if parsing is successful, -1 otherwise and errmsg is set */
     int buildProp(XMLEle *root, char *errmsg);
@@ -133,21 +135,15 @@
     char deviceID[MAXINDINAME];
 
+    typedef boost::shared_ptr<INumberVectorProperty> numberPtr;
+    typedef boost::shared_ptr<ITextVectorProperty> textPtr;
+    typedef boost::shared_ptr<ISwitchVectorProperty> switchPtr;
+    typedef boost::shared_ptr<ILightVectorProperty> lightPtr;
+    typedef boost::shared_ptr<IBLOBVectorProperty> blobPtr;
+
 private:
 
-    typedef struct
-    {
-        INDI_TYPE type;
-        void *p;
-    } pOrder;
-
-    std::vector<INumberVectorProperty *> pNumbers;
-    std::vector<ITextVectorProperty *> pTexts;
-    std::vector<ISwitchVectorProperty *> pSwitches;
-    std::vector<ILightVectorProperty *> pLights;
-    std::vector<IBLOBVectorProperty *> pBlobs;
+    std::map< boost::shared_ptr<void>, INDI_TYPE> pAll;
 
     LilXML *lp;
-
-    std::vector<pOrder> pAll;
 
     std::string messageQueue;
Index: /BAORadio/libindi/libindi/libs/indibase/defaultdriver.cpp
===================================================================
--- /BAORadio/libindi/libindi/libs/indibase/defaultdriver.cpp	(revision 503)
+++ /BAORadio/libindi/libindi/libs/indibase/defaultdriver.cpp	(revision 504)
@@ -8,4 +8,18 @@
 #include "base64.h"
 
+void timerfunc(void *t)
+{
+    //fprintf(stderr,"Got a timer hit with %x\n",t);
+    INDI::DefaultDriver *devPtr = static_cast<INDI::DefaultDriver *> (t);
+    if (devPtr != NULL)
+    {
+        //  this was for my device
+        //  but we dont have a way of telling
+        //  WHICH timer was hit :(
+        devPtr->TimerHit();
+    }
+    return;
+}
+
 
 INDI::DefaultDriver::DefaultDriver()
@@ -13,4 +27,14 @@
     pDebug = false;
     pSimulation = false;
+
+    //switchPtr conSw(new ISwitchVectorProperty);
+    ConnectionSP = new ISwitchVectorProperty;
+
+    IUFillSwitch(&ConnectionS[0],"CONNECT","Connect",ISS_OFF);
+    IUFillSwitch(&ConnectionS[1],"DISCONNECT","Disconnect",ISS_ON);
+    IUFillSwitchVector(ConnectionSP,ConnectionS,2,deviceName(),"CONNECTION","Connection","Main Control",IP_RW,ISR_1OFMANY,60,IPS_IDLE);
+
+    registerProperty(ConnectionSP, INDI_SWITCH);
+
 }
 
@@ -32,6 +56,12 @@
 bool INDI::DefaultDriver::saveConfig()
 {
-    std::vector<pOrder>::const_iterator orderi;
+    //std::vector<orderPtr>::iterator orderi;
+
+    std::map< boost::shared_ptr<void>, INDI_TYPE>::iterator orderi;
+
     ISwitchVectorProperty *svp=NULL;
+    INumberVectorProperty *nvp=NULL;
+    ITextVectorProperty   *tvp=NULL;
+    IBLOBVectorProperty   *bvp=NULL;
     char errmsg[MAXRBUF];
     FILE *fp = NULL;
@@ -49,14 +79,18 @@
     for (orderi = pAll.begin(); orderi != pAll.end(); orderi++)
     {
-        switch ( (*orderi).type)
+
+        switch (orderi->second)
         {
         case INDI_NUMBER:
-             IUSaveConfigNumber(fp, static_cast<INumberVectorProperty *> ((*orderi).p));
+             nvp = static_cast<INumberVectorProperty *>((orderi->first).get());
+             IDLog("Trying to save config for number %s\n", nvp->name);
+             IUSaveConfigNumber(fp, nvp);
              break;
         case INDI_TEXT:
-             IUSaveConfigText(fp, static_cast<ITextVectorProperty *> ((*orderi).p));
+             tvp = static_cast<ITextVectorProperty *>((orderi->first).get());
+             IUSaveConfigText(fp, tvp);
              break;
         case INDI_SWITCH:
-             svp = static_cast<ISwitchVectorProperty *> ((*orderi).p);
+             svp = static_cast<ISwitchVectorProperty *>((orderi->first).get());
              /* Never save CONNECTION property. Don't save switches with no switches on if the rule is one of many */
              if (!strcmp(svp->name, "CONNECTION") || (svp->r == ISR_1OFMANY && !IUFindOnSwitch(svp)))
@@ -65,5 +99,6 @@
              break;
         case INDI_BLOB:
-             IUSaveConfigBLOB(fp, static_cast<IBLOBVectorProperty *> ((*orderi).p));
+             bvp = static_cast<IBLOBVectorProperty *>((orderi->first).get());
+             IUSaveConfigBLOB(fp, bvp);
              break;
         }
@@ -116,4 +151,50 @@
     if (!svp)
         return false;
+
+     if(!strcmp(svp->name,ConnectionSP->name))
+     {
+        bool rc;
+        
+      for (int i=0; i < n; i++)
+      {
+        if ( !strcmp(names[i], "CONNECT") && (states[i] == ISS_ON))
+        {
+            // If not connected, attempt to connect
+            if (isConnected() == false)
+            {
+                rc = Connect();
+
+                // If connection is successful, set it thus
+                if (rc)
+                  setConnected(true);
+                else
+                  setConnected(false, IPS_ALERT);
+
+                updateProperties();
+            }
+            else
+                // Just tell client we're connected yes
+                setConnected(true);
+        }
+        else if ( !strcmp(names[i], "DISCONNECT") && (states[i] == ISS_ON))
+        {
+            // If connected, then true to disconnect.
+            if (isConnected() == true)
+                rc = Disconnect();
+            else
+                rc = true;
+
+            if (rc)
+                setConnected(false, IPS_IDLE);
+            else
+                setConnected(true, IPS_ALERT);
+
+            updateProperties();
+        }
+    }
+
+        return true;
+    }
+
 
     if (!strcmp(svp->name, "DEBUG"))
@@ -174,5 +255,5 @@
 }
 
-void INDI::DefaultDriver::addAuxControls()
+void INDI::DefaultDriver::addDebugControl()
 {
     /**************************************************************************/
@@ -180,11 +261,10 @@
     if (!DebugSP)
     {
-        DebugSP = new ISwitchVectorProperty;
+        switchPtr debSw(new ISwitchVectorProperty);
+        DebugSP = debSw.get();
         IUFillSwitch(&DebugS[0], "ENABLE", "Enable", ISS_OFF);
         IUFillSwitch(&DebugS[1], "DISABLE", "Disable", ISS_ON);
         IUFillSwitchVector(DebugSP, DebugS, NARRAY(DebugS), deviceID, "DEBUG", "Debug", "Options", IP_RW, ISR_1OFMANY, 0, IPS_IDLE);
-        pSwitches.push_back(DebugSP);
-        pOrder debo = {INDI_SWITCH, DebugSP};
-        pAll.push_back(debo);
+        pAll[debSw] = INDI_SWITCH;
     }
     else
@@ -197,15 +277,18 @@
     /**************************************************************************/
 
+}
+
+void INDI::DefaultDriver::addSimulationControl()
+{
     /**************************************************************************/
     SimulationSP = getSwitch("SIMULATION");
     if (!SimulationSP)
     {
-        SimulationSP = new ISwitchVectorProperty;
+        switchPtr simSw(new ISwitchVectorProperty);
+        SimulationSP = simSw.get();
         IUFillSwitch(&SimulationS[0], "ENABLE", "Enable", ISS_OFF);
         IUFillSwitch(&SimulationS[1], "DISABLE", "Disable", ISS_ON);
         IUFillSwitchVector(SimulationSP, SimulationS, NARRAY(SimulationS), deviceID, "SIMULATION", "Simulation", "Options", IP_RW, ISR_1OFMANY, 0, IPS_IDLE);
-        pSwitches.push_back(SimulationSP);
-        pOrder simo = {INDI_SWITCH, SimulationSP};
-        pAll.push_back(simo);
+        pAll[simSw] = INDI_SWITCH;
     }
     else
@@ -216,17 +299,19 @@
                 pSimulation = true;
     }
-
+}
+
+void INDI::DefaultDriver::addConfigurationControl()
+{
     /**************************************************************************/
     ConfigProcessSP = getSwitch("CONFIG_PROCESS");
     if (!ConfigProcessSP)
     {
-        ConfigProcessSP = new ISwitchVectorProperty;
+        switchPtr configSw(new ISwitchVectorProperty);
+        ConfigProcessSP = configSw.get();
         IUFillSwitch(&ConfigProcessS[0], "CONFIG_LOAD", "Load", ISS_OFF);
         IUFillSwitch(&ConfigProcessS[1], "CONFIG_SAVE", "Save", ISS_OFF);
         IUFillSwitch(&ConfigProcessS[2], "CONFIG_DEFAULT", "Default", ISS_OFF);
         IUFillSwitchVector(ConfigProcessSP, ConfigProcessS, NARRAY(ConfigProcessS), deviceID, "CONFIG_PROCESS", "Configuration", "Options", IP_RW, ISR_1OFMANY, 0, IPS_IDLE);
-        pSwitches.push_back(ConfigProcessSP);
-        pOrder cpono = {INDI_SWITCH, ConfigProcessSP};
-        pAll.push_back(cpono);
+        pAll[configSw] = INDI_SWITCH;
     }
     /**************************************************************************/
@@ -234,6 +319,16 @@
 }
 
+void INDI::DefaultDriver::addAuxControls()
+{
+   addDebugControl();
+   addSimulationControl();
+   addConfigurationControl();
+}
+
 void INDI::DefaultDriver::setDebug(bool enable)
 {
+    if (!DebugSP)
+        return;
+
     if (pDebug == enable)
     {
@@ -242,7 +337,4 @@
         return;
     }
-
-    if (!DebugSP)
-        return;
 
     IUResetSwitch(DebugSP);
@@ -275,4 +367,7 @@
 void INDI::DefaultDriver::setSimulation(bool enable)
 {
+    if (!SimulationSP)
+        return;
+
    if (pSimulation == enable)
    {
@@ -281,7 +376,4 @@
        return;
    }
-
-   if (!SimulationSP)
-       return;
 
    IUResetSwitch(SimulationSP);
@@ -324,42 +416,63 @@
 void INDI::DefaultDriver::ISGetProperties (const char *dev)
 {
-    std::vector<pOrder>::const_iterator orderi;
+    std::map< boost::shared_ptr<void>, INDI_TYPE>::iterator orderi;
+    static int isInit = 0;
+
+    //fprintf(stderr,"Enter ISGetProperties '%s'\n",dev);
+    if(isInit == 0)
+    {
+        if(dev != NULL)
+             setDeviceName(dev);
+        else
+        {
+            char *envDev = getenv("INDIDEV");
+            if (envDev != NULL)
+                setDeviceName(envDev);
+            else
+               setDeviceName(getDefaultName());
+        }
+
+        strncpy(ConnectionSP->device, deviceName(), MAXINDIDEVICE);
+        initProperties();
+        addConfigurationControl();
+
+        isInit = 1;
+    }
 
     for (orderi = pAll.begin(); orderi != pAll.end(); orderi++)
     {
-        switch ( (*orderi).type)
+        switch (orderi->second)
         {
         case INDI_NUMBER:
-             IDDefNumber(static_cast<INumberVectorProperty *>((*orderi).p) , NULL);
+             IDDefNumber(static_cast<INumberVectorProperty *>((orderi->first).get()) , NULL);
              break;
         case INDI_TEXT:
-             IDDefText(static_cast<ITextVectorProperty *>((*orderi).p) , NULL);
+             IDDefText(static_cast<ITextVectorProperty *>((orderi->first).get()) , NULL);
              break;
         case INDI_SWITCH:
-             IDDefSwitch(static_cast<ISwitchVectorProperty *>((*orderi).p) , NULL);
+             IDDefSwitch(static_cast<ISwitchVectorProperty *>((orderi->first).get()) , NULL);
              break;
         case INDI_LIGHT:
-             IDDefLight(static_cast<ILightVectorProperty *>((*orderi).p) , NULL);
+             IDDefLight(static_cast<ILightVectorProperty *>((orderi->first).get()) , NULL);
              break;
         case INDI_BLOB:
-             IDDefBLOB(static_cast<IBLOBVectorProperty *>((*orderi).p) , NULL);
+             IDDefBLOB(static_cast<IBLOBVectorProperty *>((orderi->first).get()) , NULL);
              break;
         }
     }
-
 }
 
 void INDI::DefaultDriver::resetProperties()
 {
-    std::vector<INumberVectorProperty *>::const_iterator numi;
-    std::vector<ISwitchVectorProperty *>::const_iterator switchi;
-    std::vector<ITextVectorProperty *>::const_iterator texti;
-    std::vector<ILightVectorProperty *>::const_iterator lighti;
-    std::vector<IBLOBVectorProperty *>::const_iterator blobi;
+    /*std::vector<numberPtr>::const_iterator numi;
+    std::vector<switchPtr>::const_iterator switchi;
+    std::vector<textPtr>::const_iterator texti;
+    std::vector<lightPtr>::const_iterator lighti;
+    std::vector<blobPtr>::const_iterator blobi;
 
     for ( numi = pNumbers.begin(); numi != pNumbers.end(); numi++)
     {
         (*numi)->s = IPS_IDLE;
-        IDSetNumber( (*numi), NULL);
+        IDSetNumber( (*numi).get(), NULL);
     }
 
@@ -367,5 +480,5 @@
    {
        (*switchi)->s = IPS_IDLE;
-       IDSetSwitch( (*switchi), NULL);
+       IDSetSwitch( (*switchi).get(), NULL);
    }
 
@@ -373,5 +486,5 @@
    {
       (*texti)->s = IPS_IDLE;
-      IDSetText( (*texti), NULL);
+      IDSetText( (*texti).get(), NULL);
    }
 
@@ -379,5 +492,5 @@
    {
        (*lighti)->s = IPS_IDLE;
-       IDSetLight( (*lighti), NULL);
+       IDSetLight( (*lighti).get(), NULL);
    }
 
@@ -385,5 +498,108 @@
    {
        (*blobi)->s = IPS_IDLE;
-       IDSetBLOB( (*blobi), NULL);
-   }
-}
+       IDSetBLOB( (*blobi).get(), NULL);
+   }*/
+}
+
+void INDI::DefaultDriver::setConnected(bool status, IPState state, const char *msg)
+{
+    ISwitch *sp = NULL;
+    ISwitchVectorProperty *svp = getSwitch("CONNECTION");
+    if (!svp)
+        return;
+
+    IUResetSwitch(svp);
+
+    // Connect
+    if (status)
+    {
+        sp = IUFindSwitch(svp, "CONNECT");
+        if (!sp)
+            return;
+        sp->s = ISS_ON;
+    }
+    // Disconnect
+    else
+    {
+        sp = IUFindSwitch(svp, "DISCONNECT");
+        if (!sp)
+            return;
+        sp->s = ISS_ON;
+    }
+
+    svp->s = state;
+
+    IDSetSwitch(svp, msg, NULL);
+}
+
+//  This is a helper function
+//  that just encapsulates the Indi way into our clean c++ way of doing things
+int INDI::DefaultDriver::SetTimer(int t)
+{
+    return IEAddTimer(t,timerfunc,this);
+}
+
+//  Just another helper to help encapsulate indi into a clean class
+void INDI::DefaultDriver::RemoveTimer(int t)
+{
+    IERmTimer(t);
+    return;
+}
+
+//  This is just a placeholder
+//  This function should be overriden by child classes if they use timers
+//  So we should never get here
+void INDI::DefaultDriver::TimerHit()
+{
+    return;
+}
+
+
+bool INDI::DefaultDriver::updateProperties()
+{
+    //  The base device has no properties to update
+    return true;
+}
+
+
+bool INDI::DefaultDriver::initProperties()
+{
+   return true;
+}
+
+bool INDI::DefaultDriver::deleteProperty(const char *propertyName)
+{
+    removeProperty(propertyName);
+    IDDelete(deviceName(), propertyName ,NULL);
+    return true;
+}
+
+void INDI::DefaultDriver::defineNumber(INumberVectorProperty *nvp)
+{
+    registerProperty(nvp, INDI_NUMBER);
+    IDDefNumber(nvp, NULL);
+}
+
+void INDI::DefaultDriver::defineText(ITextVectorProperty *tvp)
+{
+    registerProperty(tvp, INDI_TEXT);
+    IDDefText(tvp, NULL);
+}
+
+void INDI::DefaultDriver::defineSwitch(ISwitchVectorProperty *svp)
+{
+    registerProperty(svp, INDI_SWITCH);
+    IDDefSwitch(svp, NULL);
+}
+
+void INDI::DefaultDriver::defineLight(ILightVectorProperty *lvp)
+{
+    registerProperty(lvp, INDI_LIGHT);
+    IDDefLight(lvp, NULL);
+}
+
+void INDI::DefaultDriver::defineBLOB(IBLOBVectorProperty *bvp)
+{
+    registerProperty(bvp, INDI_BLOB);
+    IDDefBLOB(bvp, NULL);
+}
Index: /BAORadio/libindi/libindi/libs/indibase/defaultdriver.h
===================================================================
--- /BAORadio/libindi/libindi/libs/indibase/defaultdriver.h	(revision 503)
+++ /BAORadio/libindi/libindi/libs/indibase/defaultdriver.h	(revision 504)
@@ -26,7 +26,63 @@
     void addAuxControls();
 
+    /** \brief Add Debug control to the driver */
+    void addDebugControl();
+
+    /** \brief Add Simulation control to the driver */
+    void addSimulationControl();
+
+    /** \brief Add Configuration control to the driver */
+    void addConfigurationControl();
+
     /** \brief Set all properties to IDLE state */
     void resetProperties();
 
+    /** \brief Define number vector to client & register it. Alternatively, IDDefNumber can be used but the property will not
+               get registered and the driver will not be able to save configuration files.
+         \param nvp The number vector property to be defined
+    */
+    void defineNumber(INumberVectorProperty *nvp);
+
+    /** \brief Define text vector to client & register it. Alternatively, IDDefText can be used but the property will not
+               get registered and the driver will not be able to save configuration files.
+         \param tvp The text vector property to be defined
+    */
+    void defineText(ITextVectorProperty *tvp);
+
+    /** \brief Define switch vector to client & register it. Alternatively, IDDefswitch can be used but the property will not
+               get registered and the driver will not be able to save configuration files.
+         \param svp The switch vector property to be defined
+    */
+    void defineSwitch(ISwitchVectorProperty *svp);
+
+    /** \brief Define light vector to client & register it. Alternatively, IDDeflight can be used but the property will not
+               get registered and the driver will not be able to save configuration files.
+         \param lvp The light vector property to be defined
+    */
+    void defineLight(ILightVectorProperty *lvp);
+
+    /** \brief Define BLOB vector to client & register it. Alternatively, IDDefBLOB can be used but the property will not
+               get registered and the driver will not be able to save configuration files.
+         \param bvp The BLOB vector property to be defined
+    */
+    void defineBLOB(IBLOBVectorProperty *bvp);
+
+
+    /** \brief Delete a property and unregister it. It will also be deleted from all clients.
+        \param propertyName name of property to be deleted.
+    */
+    virtual bool deleteProperty(const char *propertyName);
+
+    /** \brief Connect or Disconnect a device.
+      \param status If true, the driver will attempt to connect to the device (CONNECT=ON). If false, it will attempt
+to disconnect the device.
+      \param msg A message to be sent along with connect/disconnect command.
+    */
+    virtual void setConnected(bool status, IPState state=IPS_OK, const char *msg = NULL);
+
+    int SetTimer(int);
+    void RemoveTimer(int);
+    virtual void TimerHit();
+
 protected:
 
@@ -95,4 +151,39 @@
     /** \return True if Simulation is on, False otherwise. */
     bool isSimulation();
+
+    //  These are the properties we define, that are generic to pretty much all devices
+    //  They are public to make them available to all dervied classes and thier children
+    ISwitchVectorProperty *ConnectionSP;
+    ISwitch ConnectionS[2];
+
+
+    /** \brief Initilize properties initial state and value. The child class must implement this function.
+        \return True if initilization is successful, false otherwise.
+    */
+    virtual bool initProperties();
+
+    /** \brief updateProperties is called whenever there is a change in the CONNECTION status of the driver.
+        This will enable the driver to react to changes of switching ON/OFF a device. For example, a driver
+        may only define a set of properties after a device is connected, but not before.
+        \return True if update is successful, false otherwise.
+    */
+    virtual bool updateProperties();
+
+    /** \brief Connect to a device. Child classes must implement this function and perform the connection
+        routine in the function.
+        \return True if connection to device is successful, false otherwise.
+    */
+    virtual bool Connect()=0;
+
+    /** \brief Disconnect from a device. Child classes must implement this function and perform the disconnection
+        routine in the function.
+        \return True if disconnection from a device is successful, false otherwise.
+    */
+    virtual bool Disconnect()=0;
+
+    /** \return Default name of the device. */
+    virtual const char *getDefaultName()=0;
+
+
 
 private:
Index: /BAORadio/libindi/libindi/libs/indibase/indibase.h
===================================================================
--- /BAORadio/libindi/libindi/libs/indibase/indibase.h	(revision 503)
+++ /BAORadio/libindi/libindi/libs/indibase/indibase.h	(revision 504)
@@ -26,4 +26,9 @@
     class BaseDriver;
     class DefaultDriver;
+    class CCD;
+    class Telescope;
+    class FilterWheel;
+    class Focuser;
+    class USBDevice;
 }
 
@@ -31,5 +36,5 @@
 /**
  * \class INDI::BaseMediator
-   \brief Meditates event notification as generated by devices and passed to clients.
+   \brief Meditates event notification as generated by driver and passed to clients.
 */
 class INDI::BaseMediator
@@ -38,6 +43,13 @@
 
     /** \brief Emmited when a new device is created from INDI server.
+        \param device_name Name of the new device
     */
-    virtual void newDevice()  =0;
+    virtual void newDevice(const char *device_name)  =0;
+
+    /** \brief Emmited when a new property is created for an INDI driver.
+        \param device_name Name of the device
+        \param property_name Name of the new property
+    */
+    virtual void newProperty(const char *device_name, const char *property_name)  =0;
 
     /** \brief Emmited when a new BLOB value arrives from INDI server.
@@ -66,4 +78,8 @@
     virtual void newLight(ILightVectorProperty *lvp) =0;
 
+    /** \brief Emmited when the server is connected.
+    */
+    virtual void serverConnected() =0;
+
     /** \brief Emmited when the server gets disconnected.
     */
Index: /BAORadio/libindi/libindi/libs/indibase/indiccd.cpp
===================================================================
--- /BAORadio/libindi/libindi/libs/indibase/indiccd.cpp	(revision 504)
+++ /BAORadio/libindi/libindi/libs/indibase/indiccd.cpp	(revision 504)
@@ -0,0 +1,757 @@
+/*******************************************************************************
+  Copyright(c) 2010 Gerry Rozema. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published by the Free
+  Software Foundation; either version 2 of the License, or (at your option)
+  any later version.
+
+  This program is distributed in the hope that it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc., 59
+  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+  The full GNU General Public License is included in this distribution in the
+  file called LICENSE.
+*******************************************************************************/
+
+#include "indiccd.h"
+
+#include <string.h>
+
+#include <fitsio.h>
+#include <zlib.h>
+
+INDI::CCD::CCD()
+{
+    //ctor
+    SendCompressed=false;
+    GuiderCompressed=false;
+    HasGuideHead=false;
+    HasSt4Port=false;
+
+    RawFrame=NULL;
+    RawFrameSize=0;
+
+    RawGuideSize=0;
+    RawGuiderFrame=NULL;
+
+    FrameType=FRAME_TYPE_LIGHT;
+
+}
+
+INDI::CCD::~CCD()
+{
+    //dtor
+}
+
+bool INDI::CCD::initProperties()
+{
+    //IDLog("INDI::CCD initProperties '%s'\n",deviceName());
+
+    DefaultDriver::initProperties();   //  let the base class flesh in what it wants
+
+    //IDLog("INDI::CCD::initProperties()\n");
+    IUFillNumber(&ImageFrameN[0],"X","Left ","%4.0f",0,1392.0,0,0);
+    IUFillNumber(&ImageFrameN[1],"Y","Top","%4.0f",0,1040,0,0);
+    IUFillNumber(&ImageFrameN[2],"WIDTH","Width","%4.0f",0,1392.0,0,1392.0);
+    IUFillNumber(&ImageFrameN[3],"HEIGHT","Height","%4.0f",0,1040,0,1040);
+    IUFillNumberVector(&ImageFrameNV,ImageFrameN,4,deviceName(),"CCD_FRAME","Frame","Image Settings",IP_RW,60,IPS_IDLE);
+
+    IUFillSwitch(&FrameTypeS[0],"FRAME_LIGHT","Light",ISS_ON);
+    IUFillSwitch(&FrameTypeS[1],"FRAME_BIAS","Bias",ISS_OFF);
+    IUFillSwitch(&FrameTypeS[2],"FRAME_DARK","Dark",ISS_OFF);
+    IUFillSwitch(&FrameTypeS[3],"FRAME_FLAT","Flat",ISS_OFF);
+    IUFillSwitchVector(&FrameTypeSV,FrameTypeS,4,deviceName(),"CCD_FRAME_TYPE","FrameType","Image Settings",IP_RW,ISR_1OFMANY,60,IPS_IDLE);
+
+    IUFillNumber(&ImageExposureN[0],"CCD_EXPOSURE_VALUE","Duration (s)","%5.2f",0,36000,0,1.0);
+    IUFillNumberVector(&ImageExposureNV,ImageExposureN,1,deviceName(),"CCD_EXPOSURE","Expose","Main Control",IP_RW,60,IPS_IDLE);
+    //IUFillNumber(&CcdExposureReqN[0],"CCD_EXPOSURE_VALUE","Duration","%5.2f",0,36000,0,1.0);
+    //IUFillNumberVector(&CcdExposureReqNV,CcdExposureReqN,1,deviceName(),"CCD_EXPOSURE_REQUEST","Expose","Main Control",IP_WO,60,IPS_IDLE);
+
+    IUFillNumber(&ImageBinN[0],"HOR_BIN","X","%2.0f",1,4,1,1);
+    IUFillNumber(&ImageBinN[1],"VER_BIN","Y","%2.0f",1,4,1,1);
+    IUFillNumberVector(&ImageBinNV,ImageBinN,2,deviceName(),"CCD_BINNING","Binning","Image Settings",IP_RW,60,IPS_IDLE);
+
+    IUFillNumber(&ImagePixelSizeN[0],"CCD_MAX_X","Resolution x","%4.0f",1,40,0,6.45);
+    IUFillNumber(&ImagePixelSizeN[1],"CCD_MAX_Y","Resolution y","%4.0f",1,40,0,6.45);
+    IUFillNumber(&ImagePixelSizeN[2],"CCD_PIXEL_SIZE","Pixel size (um)","%5.2f",1,40,0,6.45);
+    IUFillNumber(&ImagePixelSizeN[3],"CCD_PIXEL_SIZE_X","Pixel size X","%5.2f",1,40,0,6.45);
+    IUFillNumber(&ImagePixelSizeN[4],"CCD_PIXEL_SIZE_Y","Pixel size Y","%5.2f",1,40,0,6.45);
+    IUFillNumber(&ImagePixelSizeN[5],"CCD_BITSPERPIXEL","Bits per pixel","%3.0f",1,40,0,6.45);
+    IUFillNumberVector(&ImagePixelSizeNV,ImagePixelSizeN,6,deviceName(),"CCD_INFO","Ccd Information","Image Info",IP_RO,60,IPS_IDLE);
+
+
+
+    IUFillNumber(&GuiderFrameN[0],"X","Left ","%4.0f",0,1392.0,0,0);
+    IUFillNumber(&GuiderFrameN[1],"Y","Top","%4.0f",0,1040,0,0);
+    IUFillNumber(&GuiderFrameN[2],"WIDTH","Width","%4.0f",0,1392.0,0,1392.0);
+    IUFillNumber(&GuiderFrameN[3],"HEIGHT","Height","%4.0f",0,1040,0,1040);
+    IUFillNumberVector(&GuiderFrameNV,GuiderFrameN,4,deviceName(),"GUIDER_FRAME","Frame","Guidehead Settings",IP_RW,60,IPS_IDLE);
+
+
+    IUFillNumber(&GuiderPixelSizeN[0],"GUIDER_MAX_X","Resolution x","%4.0f",1,40,0,6.45);
+    IUFillNumber(&GuiderPixelSizeN[1],"GUIDER_MAX_Y","Resolution y","%4.0f",1,40,0,6.45);
+    IUFillNumber(&GuiderPixelSizeN[2],"GUIDER_PIXEL_SIZE","Pixel size (um)","%5.2f",1,40,0,6.45);
+    IUFillNumber(&GuiderPixelSizeN[3],"GUIDER_PIXEL_SIZE_X","Pixel size X","%5.2f",1,40,0,6.45);
+    IUFillNumber(&GuiderPixelSizeN[4],"GUIDER_PIXEL_SIZE_Y","Pixel size Y","%5.2f",1,40,0,6.45);
+    IUFillNumber(&GuiderPixelSizeN[5],"GUIDER_BITSPERPIXEL","Bits per pixel","%3.0f",1,40,0,6.45);
+    IUFillNumberVector(&GuiderPixelSizeNV,GuiderPixelSizeN,6,deviceName(),"GUIDER_INFO","Guidehead Information","Guidehead Info",IP_RO,60,IPS_IDLE);
+
+
+    IUFillNumber(&GuiderExposureN[0],"GUIDER_EXPOSURE_VALUE","Duration (s)","%5.2f",0,36000,0,1.0);
+    IUFillNumberVector(&GuiderExposureNV,GuiderExposureN,1,deviceName(),"GUIDER_EXPOSURE","Guider","Main Cntrol",IP_RW,60,IPS_IDLE);
+
+
+    IUFillSwitch(&GuiderVideoS[0],"ON","on",ISS_OFF);
+    IUFillSwitch(&GuiderVideoS[1],"OFF","off",ISS_OFF);
+    IUFillSwitchVector(&GuiderVideoSV,GuiderVideoS,2,deviceName(),"VIDEO_STREAM","Guider Stream","Guidehead Settings",IP_RW,ISR_1OFMANY,60,IPS_IDLE);
+
+    //IDLog("Setting up blob\n");
+
+    IUFillSwitch(&CompressS[0],"COMPRESS","Compress",ISS_OFF);
+    IUFillSwitch(&CompressS[1],"RAW","Raw",ISS_ON);
+    IUFillSwitchVector(&CompressSV,CompressS,2,deviceName(),"COMPRESSION","Image","Data Channel",IP_RW,ISR_1OFMANY,60,IPS_IDLE);
+
+    IUFillSwitch(&GuiderCompressS[0],"GCOMPRESS","Compress",ISS_OFF);
+    IUFillSwitch(&GuiderCompressS[1],"GRAW","Raw",ISS_ON);
+    IUFillSwitchVector(&GuiderCompressSV,GuiderCompressS,2,deviceName(),"GCOMPRESSION","Guider","Data Channel",IP_RW,ISR_1OFMANY,60,IPS_IDLE);
+
+    IUFillBLOB(&FitsB,"CCD1","Image","");
+    IUFillBLOBVector(&FitsBV,&FitsB,1,deviceName(),"CCD1","Image Data","Data Channel",IP_RO,60,IPS_IDLE);
+
+    IUFillBLOB(&GuiderB,"CCD2","Guider","");
+    IUFillBLOBVector(&GuiderBV,&GuiderB,1,deviceName(),"CCD2","Guider Data","Data Channel",IP_RO,60,IPS_IDLE);
+
+    IUFillNumber(&GuideNS[0],"TIMED_GUIDE_N","North (sec)","%g",0,10,0.001,0);
+    IUFillNumber(&GuideNS[1],"TIMED_GUIDE_S","South (sec)","%g",0,10,0.001,0);
+    IUFillNumberVector(&GuideNSV,GuideNS,2,deviceName(),"TELESCOPE_TIMED_GUIDE_NS","Guide North/South","GuiderControl",IP_RW,60,IPS_IDLE);
+
+    IUFillNumber(&GuideEW[0],"TIMED_GUIDE_E","East (sec)","%g",0,10,0.001,0);
+    IUFillNumber(&GuideEW[1],"TIMED_GUIDE_W","West (sec)","%g",0,10,0.001,0);
+    IUFillNumberVector(&GuideEWV,GuideEW,2,deviceName(),"TELESCOPE_TIMED_GUIDE_WE","Guide East/West","GuiderControl",IP_RW,60,IPS_IDLE);
+
+
+    //IDLog("Setting up ccdpreview stuff\n");
+    //IUFillNumber(&GuiderN[0],"WIDTH","Width","%4.0f",0.,1392.0,0.,1392.);
+    //IUFillNumber(&GuiderN[1],"HEIGHT","Height","%4.0f",0.,1040.,0.,1040.);
+    //IUFillNumber(&GuiderN[2],"MAXGOODDATA","max good","%5.0f",0.,65535.0,0.,65535.0);
+    //IUFillNumber(&GuiderN[3],"BYTESPERPIXEL","BPP","%1.0f",1.,4.,1.,2.);
+    //IUFillNumber(&GuiderN[4],"BYTEORDER","BO","%1.0f",1.,2.,1.,1.);
+    //IUFillNumberVector(&GuiderNV,GuiderN,5,deviceName(),"CCDPREVIEW_CTRL","Image Size","Guider Settings",IP_RW,60,IPS_IDLE);
+
+    return 0;
+}
+
+void INDI::CCD::ISGetProperties (const char *dev)
+{
+    //  First we let our parent populate
+
+    //IDLog("INDI::CCD IsGetProperties with %s\n",dev);
+
+    DefaultDriver::ISGetProperties(dev);
+
+    return;
+}
+
+bool INDI::CCD::updateProperties()
+{
+    //IDLog("INDI::CCD UpdateProperties isConnected returns %d %d\n",isConnected(),Connected);
+    if(isConnected()) {
+        defineNumber(&ImageExposureNV);
+        defineNumber(&ImageFrameNV);
+        defineNumber(&ImageBinNV);
+
+
+        if(HasGuideHead) {
+            IDLog("Sending Guider Stuff\n");
+            defineNumber(&GuiderExposureNV);
+            defineNumber(&GuiderFrameNV);
+            defineSwitch(&GuiderVideoSV);
+        }
+
+        defineNumber(&ImagePixelSizeNV);
+        if(HasGuideHead) {
+            defineNumber(&GuiderPixelSizeNV);
+        }
+        defineSwitch(&CompressSV);
+        defineBLOB(&FitsBV);
+        if(HasGuideHead)
+        {
+            defineSwitch(&GuiderCompressSV);
+            defineBLOB(&GuiderBV);
+        }
+        if(HasSt4Port)
+        {
+            defineNumber(&GuideNSV);
+            defineNumber(&GuideEWV);
+        }
+        defineSwitch(&FrameTypeSV);
+    } else {
+        deleteProperty(ImageFrameNV.name);
+        deleteProperty(ImageBinNV.name);
+        deleteProperty(ImagePixelSizeNV.name);
+        deleteProperty(ImageExposureNV.name);
+        deleteProperty(FitsBV.name);
+        deleteProperty(CompressSV.name);
+        if(HasGuideHead) {
+            deleteProperty(GuiderVideoSV.name);
+            deleteProperty(GuiderExposureNV.name);
+            deleteProperty(GuiderFrameNV.name);
+            deleteProperty(GuiderPixelSizeNV.name);
+            deleteProperty(GuiderBV.name);
+            deleteProperty(GuiderCompressSV.name);
+        }
+        if(HasSt4Port) {
+            deleteProperty(GuideNSV.name);
+            deleteProperty(GuideEWV.name);
+
+        }
+        deleteProperty(FrameTypeSV.name);
+    }
+    return true;
+}
+
+bool INDI::CCD::ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n)
+{
+    //  first check if it's for our device
+    //IDLog("INDI::CCD::ISNewNumber %s\n",name);
+    if(strcmp(dev,deviceName())==0) {
+        //  This is for our device
+        //  Now lets see if it's something we process here
+        if(strcmp(name,"CCD_EXPOSURE")==0) {
+            float n;
+            int rc;
+
+            n=values[0];
+
+            ImageExposureN[0].value=n;
+            ImageExposureNV.s=IPS_BUSY;
+            //  now we have a new number, this is our requested exposure time
+            //  Tell the clients we are busy with this exposure
+
+            //  And now call the physical hardware layer to start the exposure
+            rc=StartExposure(n);
+            switch(rc) {
+                case 0: //  normal case, exposure running on timers, callbacks when it's finished
+                    ImageExposureNV.s=IPS_BUSY;
+                    break;
+                case 1: //  Short exposure, it's already done
+                    ImageExposureNV.s=IPS_OK;
+                    break;
+                case -1:    //  error condition
+                    ImageExposureNV.s=IPS_ALERT;
+                break;
+            }
+            IDSetNumber(&ImageExposureNV,NULL);
+            return true;
+        }
+
+        if(strcmp(name,"GUIDER_EXPOSURE")==0) {
+            float n;
+            int rc;
+
+            n=values[0];
+
+            GuiderExposureN[0].value=n;
+            GuiderExposureNV.s=IPS_BUSY;
+            //  now we have a new number, this is our requested exposure time
+            //  Tell the clients we are busy with this exposure
+
+            //  And now call the physical hardware layer to start the exposure
+            //  change of plans, this is just changing exposure time
+            //  the the start/stop stream buttons do the rest
+            rc=StartGuideExposure(n);
+            //rc=1;   //  set it to ok
+            switch(rc) {
+                case 0: //  normal case, exposure running on timers, callbacks when it's finished
+                    GuiderExposureNV.s=IPS_BUSY;
+                    break;
+                case 1: //  Short exposure, it's already done
+                    GuiderExposureNV.s=IPS_OK;
+                    break;
+                case -1:    //  error condition
+                    GuiderExposureNV.s=IPS_ALERT;
+                break;
+            }
+            IDSetNumber(&GuiderExposureNV,NULL);
+            return true;
+        }
+        if(strcmp(name,"CCD_BINNING")==0) {
+            //  We are being asked to set camera binning
+            ImageBinNV.s=IPS_OK;
+            IUUpdateNumber(&ImageBinNV,values,names,n);
+            //  Update client display
+            IDSetNumber(&ImageBinNV,NULL);
+
+            //IDLog("Binning set to %4.0f x %4.0f\n",CcdBinN[0].value,CcdBinN[1].value);
+            BinX=ImageBinN[0].value;
+            BinY=ImageBinN[1].value;
+        }
+        if(strcmp(name,"CCD_FRAME")==0) {
+            //  We are being asked to set camera binning
+            ImageFrameNV.s=IPS_OK;
+            IUUpdateNumber(&ImageFrameNV,values,names,n);
+            //  Update client display
+            IDSetNumber(&ImageFrameNV,NULL);
+
+            //IDLog("Frame set to %4.0f,%4.0f %4.0f x %4.0f\n",CcdFrameN[0].value,CcdFrameN[1].value,CcdFrameN[2].value,CcdFrameN[3].value);
+            SubX=ImageFrameN[0].value;
+            SubY=ImageFrameN[1].value;
+            SubW=ImageFrameN[2].value;
+            SubH=ImageFrameN[3].value;
+            return true;
+        }
+
+        if(strcmp(name,"GUIDER_FRAME")==0) {
+            //  We are being asked to set camera binning
+            GuiderFrameNV.s=IPS_OK;
+            IUUpdateNumber(&GuiderFrameNV,values,names,n);
+            //  Update client display
+            IDSetNumber(&GuiderFrameNV,NULL);
+
+            IDLog("GuiderFrame set to %4.0f,%4.0f %4.0f x %4.0f\n",
+                  GuiderFrameN[0].value,GuiderFrameN[1].value,GuiderFrameN[2].value,GuiderFrameN[3].value);
+            GSubX=GuiderFrameN[0].value;
+            GSubY=GuiderFrameN[1].value;
+            GSubW=GuiderFrameN[2].value;
+            GSubH=GuiderFrameN[3].value;
+            return true;
+        }
+
+        if(strcmp(name,GuideNSV.name)==0) {
+            //  We are being asked to send a guide pulse north/south on the st4 port
+            GuideNSV.s=IPS_BUSY;
+            IUUpdateNumber(&GuideNSV,values,names,n);
+            //  Update client display
+            IDSetNumber(&GuideNSV,NULL);
+
+            fprintf(stderr,"GuideNorthSouth set to %7.3f,%7.3f\n",
+                  GuideNS[0].value,GuideNS[1].value);
+
+            if(GuideNS[0].value != 0) {
+                GuideNorth(GuideNS[0].value);
+            }
+            if(GuideNS[1].value != 0) {
+                GuideSouth(GuideNS[1].value);
+            }
+            GuideNS[0].value=0;
+            GuideNS[1].value=0;
+            GuideNSV.s=IPS_OK;
+            IDSetNumber(&GuideNSV,NULL);
+
+            return true;
+        }
+        if(strcmp(name,GuideEWV.name)==0) {
+            //  We are being asked to send a guide pulse north/south on the st4 port
+            GuideEWV.s=IPS_BUSY;
+            IUUpdateNumber(&GuideEWV,values,names,n);
+            //  Update client display
+            IDSetNumber(&GuideEWV,NULL);
+
+            fprintf(stderr,"GuiderEastWest set to %6.3f,%6.3f\n",
+                  GuideEW[0].value,GuideEW[1].value);
+
+            if(GuideEW[0].value != 0) {
+                GuideEast(GuideEW[0].value);
+            } else {
+                GuideWest(GuideEW[1].value);
+            }
+
+            GuideEW[0].value=0;
+            GuideEW[1].value=0;
+            GuideEWV.s=IPS_OK;
+            IDSetNumber(&GuideEWV,NULL);
+
+            return true;
+        }
+
+        /*
+        if(strcmp(name,"CCDPREVIEW_CTRL")==0) {
+            //  We are being asked to set camera binning
+            GuiderNV.s=IPS_OK;
+            IUUpdateNumber(&GuiderNV,values,names,n);
+            //  Update client display
+            IDSetNumber(&GuiderNV,NULL);
+            return true;
+        }
+        */
+
+    }
+    //  if we didn't process it, continue up the chain, let somebody else
+    //  give it a shot
+    return DefaultDriver::ISNewNumber(dev,name,values,names,n);
+}
+
+bool INDI::CCD::ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n)
+{
+
+    //  Ok, lets Process any switches we actually handle here
+    //IDLog("INDI::CCD IsNewSwitch %s %s\n",dev,name);
+
+
+    if(strcmp(dev,deviceName())==0) {
+        //  it's for this device
+
+        //for(int x=0; x<n; x++) {
+        //    IDLog("Switch %s\n",names[x]);
+        //}
+
+        if(strcmp(name,CompressSV.name)==0) {
+
+            IUUpdateSwitch(&CompressSV,states,names,n);
+            IDSetSwitch(&CompressSV,NULL);
+
+            if(CompressS[0].s==ISS_ON    ) {
+                SendCompressed=true;
+            } else {
+                SendCompressed=false;
+            }
+            return true;
+        }
+        if(strcmp(name,GuiderCompressSV.name)==0) {
+
+            IUUpdateSwitch(&GuiderCompressSV,states,names,n);
+            IDSetSwitch(&GuiderCompressSV,NULL);
+
+            if(GuiderCompressS[0].s==ISS_ON    ) {
+                SendCompressed=true;
+            } else {
+                SendCompressed=false;
+            }
+            return true;
+        }
+
+        if(strcmp(name,GuiderVideoSV.name)==0) {
+            //  Compression Update
+            IUUpdateSwitch(&GuiderVideoSV,states,names,n);
+            if(GuiderVideoS[0].s==ISS_ON    ) {
+                GuiderVideoSV.s=IPS_OK;
+                StartGuideExposure(GuiderExposureN[0].value);
+            } else {
+                AbortGuideExposure();
+                GuiderVideoSV.s=IPS_IDLE;
+            }
+
+            IDSetSwitch(&GuiderVideoSV,NULL);
+            return true;
+        }
+
+        if(strcmp(name,FrameTypeSV.name)==0) {
+            //  Compression Update
+            IUUpdateSwitch(&FrameTypeSV,states,names,n);
+            FrameTypeSV.s=IPS_OK;
+            if(FrameTypeS[0].s==ISS_ON) SetFrameType(FRAME_TYPE_LIGHT);
+            if(FrameTypeS[1].s==ISS_ON) SetFrameType(FRAME_TYPE_BIAS);
+            if(FrameTypeS[2].s==ISS_ON) SetFrameType(FRAME_TYPE_DARK);
+            if(FrameTypeS[3].s==ISS_ON) SetFrameType(FRAME_TYPE_FLAT);
+
+
+            IDSetSwitch(&FrameTypeSV,NULL);
+            return true;
+        }
+
+    }
+
+
+    // let the default driver have a crack at it
+    return DefaultDriver::ISNewSwitch(dev, name, states, names, n);
+}
+
+
+int INDI::CCD::StartExposure(float duration)
+{
+    IDLog("INDI::CCD::StartExposure %4.2f -  Should never get here\n",duration);
+    return -1;
+}
+
+int INDI::CCD::StartGuideExposure(float duration)
+{
+    IDLog("INDI::CCD::StartGuide Exposure %4.2f -  Should never get here\n",duration);
+    return -1;
+}
+bool INDI::CCD::ExposureComplete()
+{
+    void *memptr;
+    size_t memsize;
+    int status=0;
+    long naxes[2];
+    long naxis=2;
+
+    fitsfile *fptr=NULL;
+
+
+    //IDLog("Enter Exposure Complete %d %d %d %d\n",SubW,SubH,BinX,BinY);
+
+
+    naxes[0]=SubW/BinX;
+    naxes[1]=SubH/BinY;
+    //  Now we have to send fits format data to the client
+    memsize=5760;
+    memptr=malloc(memsize);
+    if(!memptr) {
+        IDLog("Error: failed to allocate memory: %lu\n",(unsigned long)memsize);
+    }
+    fits_create_memfile(&fptr,&memptr,&memsize,2880,realloc,&status);
+    if(status) {
+		IDLog("Error: Failed to create FITS image\n");
+		fits_report_error(stderr, status);  /* print out any error messages */
+		return false;
+    }
+  	fits_create_img(fptr, USHORT_IMG , naxis, naxes, &status);
+	if (status)
+	{
+		IDLog("Error: Failed to create FITS image\n");
+		fits_report_error(stderr, status);  /* print out any error messages */
+		return false;
+	}
+
+    fits_write_img(fptr,TUSHORT,1,SubW*SubH/BinX/BinY,RawFrame,&status);
+    if (status)
+	{
+		IDLog("Error: Failed to write FITS image\n");
+		fits_report_error(stderr, status);  /* print out any error messages */
+		return false;
+	}
+	fits_close_file(fptr,&status);
+	//IDLog("Built the fits file\n");
+
+    //  ok, undo the kludge we threw in for
+    //  guider frames, and set the resolution back
+
+    //ImageFrameN[2].value=SubW;
+    //ImageFrameN[3].value=SubH;
+    //IDSetNumber(&ImageFrameNV,NULL);
+
+
+    ImageExposureNV.s=IPS_OK;
+    IDSetNumber(&ImageExposureNV,NULL);
+
+    uploadfile(memptr,memsize);
+    free(memptr);
+    return true;
+}
+
+bool INDI::CCD::GuideExposureComplete()
+{
+
+    //IDLog("Enter GuideExposure Complete %d %d\n",GSubW,GSubH);
+
+    if(GuiderVideoS[0].s==ISS_ON) {
+        //  if our stream switch for the guider
+        //  is on, then send this as a video stream
+        //  frame, and, start another frame
+
+        //  Ok, bit of a kludge here
+        //  we need to send a new size to kstars
+        //ImageFrameN[2].value=GSubW;
+        //ImageFrameN[3].value=GSubH;
+        //IDSetNumber(&ImageFrameNV,NULL);
+
+        //IDLog("Sending guider stream blob\n");
+
+        GuiderExposureNV.s=IPS_OK;
+        IDSetNumber(&GuiderExposureNV,NULL);
+        GuiderB.blob=RawGuiderFrame;
+        GuiderB.bloblen=GSubW*GSubH;
+        GuiderB.size=GSubW*GSubH;
+        strcpy(GuiderB.format,".stream");
+        GuiderBV.s=IPS_OK;
+        IDSetBLOB(&GuiderBV,NULL);
+        StartGuideExposure(GuiderExposureN[0].value);
+    } else {
+        //  We are not streaming
+        //  So, lets send this as an 8 bit fits frame
+        void *memptr;
+        size_t memsize;
+        int status=0;
+        long naxes[2];
+        long naxis=2;
+
+        fitsfile *fptr=NULL;
+        naxes[0]=GSubW;
+        naxes[1]=GSubH;
+        //  Now we have to send fits format data to the client
+        memsize=5760;
+        memptr=malloc(memsize);
+        if(!memptr) {
+            IDLog("Error: failed to allocate memory: %lu\n",(unsigned long)memsize);
+        }
+        fits_create_memfile(&fptr,&memptr,&memsize,2880,realloc,&status);
+        if(status) {
+            IDLog("Error: Failed to create FITS image\n");
+            fits_report_error(stderr, status);  /* print out any error messages */
+            return false;
+        }
+        fits_create_img(fptr, BYTE_IMG , naxis, naxes, &status);
+        if (status)
+        {
+            IDLog("Error: Failed to create FITS image\n");
+            fits_report_error(stderr, status);  /* print out any error messages */
+            return false;
+        }
+
+        fits_write_img(fptr,TBYTE,1,GSubW*GSubH,RawGuiderFrame,&status);
+        if (status)
+        {
+            IDLog("Error: Failed to write FITS image\n");
+            fits_report_error(stderr, status);  /* print out any error messages */
+            return false;
+        }
+        fits_close_file(fptr,&status);
+        IDLog("Built the Guider fits file\n");
+        GuiderExposureNV.s=IPS_OK;
+        IDSetNumber(&GuiderExposureNV,NULL);
+
+        IDLog("Sending guider fits file via %s\n",GuiderBV.name);
+        GuiderB.blob=memptr;
+        GuiderB.bloblen=memsize;
+        GuiderB.size=memsize;
+        strcpy(GuiderB.format,".fits");
+        GuiderBV.s=IPS_OK;
+        IDSetBLOB(&GuiderBV,NULL);
+        free(memptr);
+    }
+
+
+    return true;
+}
+
+
+int INDI::CCD::sendPreview()
+{
+    int numbytes;
+    int xw;
+    int yw;
+    //unsigned char *compressed;
+    //uLongf compressedbytes=0;
+    //int ccount;
+    //int r;
+
+    return 0;
+    xw=SubW/BinX;
+    yw=SubH/BinY;
+
+    //GuiderNV.s=IPS_OK;
+    //GuiderN[0].value=xw;
+    //GuiderN[1].value=yw;
+    //IDLog("Guider Frame %d x %d\n",xw,yw);
+    //IDSetNumber(&GuiderNV,"Starting to send new preview frame\n");
+
+    numbytes=xw*yw;
+    numbytes=numbytes*2;
+    //compressedbytes=numbytes+numbytes/64+16+3;
+    //compressed=(unsigned char *)malloc(numbytes+numbytes/64+16+3);
+    //r=compress2(compressed,&compressedbytes,(unsigned char *)RawFrame,numbytes,9);
+    //if(r != Z_OK) {
+    //    IDLog("Got an error from compress\n");
+    //    return -1;
+    //}
+
+
+    //FitsB.blob=compressed;
+    //FitsB.bloblen=compressedbytes;
+    FitsB.blob=RawFrame;
+    FitsB.bloblen=numbytes;
+    FitsB.size=numbytes;
+    FitsBV.s=IPS_OK;
+    strcpy(FitsB.format,".ccdpreview");
+    IDSetBLOB(&FitsBV,NULL);
+    //IDLog("Done with SetBlob with %d compressed to %d\n",numbytes,compressedbytes);
+    //free(compressed);
+    return 0;
+
+}
+
+int INDI::CCD::uploadfile(void *fitsdata,int total)
+{
+    //  lets try sending a ccd preview
+
+
+    //IDLog("Enter Uploadfile with %d total sending via %s\n",total,FitsBV.name);
+    FitsB.blob=fitsdata;
+    FitsB.bloblen=total;
+    FitsB.size=total;
+    strcpy(FitsB.format,".fits");
+    FitsBV.s=IPS_OK;
+    IDSetBLOB(&FitsBV,NULL);
+    //IDLog("Done with SetBlob\n");
+
+    return 0;
+}
+
+int INDI::CCD::SetCCDParams(int x,int y,int bpp,float xf,float yf)
+{
+    XRes=x;
+    YRes=y;
+    SubX=0;
+    SubY=0;
+    SubW=XRes;
+    SubH=YRes;
+    BinX=1;
+    BinY=1;
+
+    PixelSizex=xf;
+    PixelSizey=yf;
+    ImageFrameN[2].value=x;
+    ImageFrameN[3].value=y;
+    ImagePixelSizeN[0].value=x;
+    ImagePixelSizeN[1].value=y;
+    ImagePixelSizeN[2].value=xf;
+    ImagePixelSizeN[3].value=xf;
+    ImagePixelSizeN[4].value=yf;
+    ImagePixelSizeN[5].value=bpp;
+    return 0;
+}
+
+int INDI::CCD::SetGuidHeadParams(int x,int y,int bpp,float xf,float yf)
+{
+    HasGuideHead=true;
+    GXRes=x;
+    GYRes=y;
+    GSubX=0;
+    GSubY=0;
+    GSubW=GXRes;
+    GSubH=GYRes;
+    GuiderFrameN[2].value=x;
+    GuiderFrameN[3].value=y;
+    GuiderPixelSizeN[0].value=x;
+    GuiderPixelSizeN[1].value=y;
+    GuiderPixelSizeN[2].value=xf;
+    GuiderPixelSizeN[3].value=xf;
+    GuiderPixelSizeN[4].value=yf;
+    GuiderPixelSizeN[5].value=bpp;
+    return 0;
+}
+
+bool INDI::CCD::AbortGuideExposure()
+{
+    return false;
+}
+
+int INDI::CCD::GuideNorth(float)
+{
+    return -1;
+}
+int INDI::CCD::GuideSouth(float)
+{
+    return -1;
+}
+int INDI::CCD::GuideEast(float)
+{
+    return -1;
+}
+int INDI::CCD::GuideWest(float)
+{
+    return -1;
+}
+int INDI::CCD::SetFrameType(int t)
+{
+    //fprintf(stderr,"Set frame type to %d\n",t);
+    FrameType=t;
+    return 0;
+}
Index: /BAORadio/libindi/libindi/libs/indibase/indiccd.h
===================================================================
--- /BAORadio/libindi/libindi/libs/indibase/indiccd.h	(revision 504)
+++ /BAORadio/libindi/libindi/libs/indibase/indiccd.h	(revision 504)
@@ -0,0 +1,165 @@
+/*******************************************************************************
+  Copyright(c) 2010 Gerry Rozema. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published by the Free
+  Software Foundation; either version 2 of the License, or (at your option)
+  any later version.
+
+  This program is distributed in the hope that it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc., 59
+  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+  The full GNU General Public License is included in this distribution in the
+  file called LICENSE.
+*******************************************************************************/
+
+#ifndef INDI_CCD_H
+#define INDI_CCD_H
+
+#include "defaultdriver.h"
+
+#define FRAME_TYPE_LIGHT 0
+#define FRAME_TYPE_BIAS 1
+#define FRAME_TYPE_DARK 2
+#define FRAME_TYPE_FLAT 3
+
+class INDI::CCD : public INDI::DefaultDriver
+{
+    protected:
+
+        char *RawFrame;
+        int RawFrameSize;
+
+        //  Altho these numbers are indeed stored in the indi properties
+        //  It makes for much cleaner code if we have 'plain old number' copies
+        //  So, when we process messages, just update both
+
+        int XRes;   //  native resolution of the ccd
+        int YRes;   //  ditto
+        int SubX;   //  left side of the subframe we are requesting
+        int SubY;   //  top of the subframe requested
+        int SubW;   //  width of the subframe
+        int SubH;   //  height of the subframe
+        int BinX;   //  Binning requested in the x direction
+        int BinY;   //  Binning requested in the Y direction
+        float PixelSizex;   //  pixel size in microns, x direction
+        float PixelSizey;   //  pixel size in microns, y direction
+        bool SendCompressed;
+
+        bool HasSt4Port;
+
+        //  If the camera has a second ccd, or integrated guide head
+        //  we need information on that one too
+        bool HasGuideHead;
+        char *RawGuiderFrame;
+        int RawGuideSize;
+        int GXRes;  //  native resolution of the guide head
+        int GYRes;  //  native resolution
+        int GSubX;  //  left side of the guide image subframe
+        int GSubY;  //  top of the guide image subframe
+        int GSubW;  //  Width of the guide image
+        int GSubH;  //  Height of the guide image
+        float GPixelSizex;  //  phyiscal size of the guider pixels
+        float GPixelSizey;
+        bool GuiderCompressed;
+
+        int FrameType;
+
+
+    private:
+    public:
+        CCD();
+        virtual ~CCD();
+
+        //  A ccd needs to desribe the frame
+        //INumberVectorProperty CcdFrameNV;
+        //INumberVectorProperty CcdExposureNV;
+        //INumberVectorProperty CcdBinNV;
+        //INumberVectorProperty CcdPixelSizeNV;
+
+
+        INumberVectorProperty ImageFrameNV;
+        INumber ImageFrameN[4];
+
+        INumberVectorProperty ImageBinNV;
+        INumber ImageBinN[2];
+
+        INumberVectorProperty ImagePixelSizeNV;
+        INumber ImagePixelSizeN[6];
+
+        INumberVectorProperty ImageExposureNV;
+        INumber ImageExposureN[1];
+
+        //INumberVectorProperty ImageExposureReqNV;
+        //INumber ImageExposureReqN[1];
+
+        INumberVectorProperty GuiderFrameNV;
+        INumber GuiderFrameN[4];
+        INumberVectorProperty GuiderPixelSizeNV;
+        INumber GuiderPixelSizeN[6];
+        INumberVectorProperty GuiderExposureNV;
+        INumber GuiderExposureN[1];
+
+        ISwitch FrameTypeS[4];
+        ISwitchVectorProperty FrameTypeSV;
+
+
+        ISwitch CompressS[2];
+        ISwitchVectorProperty CompressSV;
+
+        ISwitch GuiderCompressS[2];
+        ISwitchVectorProperty GuiderCompressSV;
+
+
+        ISwitch GuiderVideoS[2];
+        ISwitchVectorProperty GuiderVideoSV;
+
+        INumber GuideNS[2];
+        INumberVectorProperty GuideNSV;
+        INumber GuideEW[2];
+        INumberVectorProperty GuideEWV;
+
+        IBLOB FitsB;
+        IBLOBVectorProperty FitsBV;
+
+        IBLOB GuiderB;
+        IBLOBVectorProperty GuiderBV;
+
+        virtual bool  initProperties();
+        virtual bool updateProperties();
+        virtual void ISGetProperties (const char *dev);
+
+        virtual bool ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n);
+        virtual bool ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n);
+
+        virtual bool ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n) {return false;}
+
+
+        virtual int StartExposure(float duration);
+        virtual bool ExposureComplete();
+        virtual int StartGuideExposure(float duration);
+        virtual bool AbortGuideExposure();
+        virtual bool GuideExposureComplete();
+        virtual int uploadfile(void *fitsdata,int total);
+        virtual int sendPreview();
+
+        //  Handy functions for child classes
+        virtual int SetCCDParams(int x,int y,int bpp,float xf,float yf);
+        virtual int SetGuidHeadParams(int x,int y,int bpp,float xf,float yf);
+
+        virtual int GuideNorth(float);
+        virtual int GuideSouth(float);
+        virtual int GuideEast(float);
+        virtual int GuideWest(float);
+
+        virtual int SetFrameType(int);
+
+};
+
+#endif // INDI:CCD_H
Index: /BAORadio/libindi/libindi/libs/indibase/indidevice.cpp
===================================================================
--- /BAORadio/libindi/libindi/libs/indibase/indidevice.cpp	(revision 504)
+++ /BAORadio/libindi/libindi/libs/indibase/indidevice.cpp	(revision 504)
@@ -0,0 +1,363 @@
+/*******************************************************************************
+  Copyright(c) 2010 Gerry Rozema. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published by the Free
+  Software Foundation; either version 2 of the License, or (at your option)
+  any later version.
+
+  This program is distributed in the hope that it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc., 59
+  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+  The full GNU General Public License is included in this distribution in the
+  file called LICENSE.
+*******************************************************************************/
+
+#include "IndiDevice.h"
+
+#include <string.h>
+
+IndiDevice *device=NULL;
+
+
+/**************************************************************************************
+**
+***************************************************************************************/
+void ISGetProperties (const char *dev)
+{
+    //fprintf(stderr,"Enter ISGetProperties '%s'\n",dev);
+    if(device==NULL) {
+        //IDLog("Create device for %s\n",dev);
+        device=_create_device();
+        if(dev != NULL) {
+            //fprintf(stderr,"Calling setDeviceName %s\n",dev);
+            device->setDeviceName(dev);
+            //fprintf(stderr,"deviceName() returns  %s\n",device->deviceName());
+            //fprintf(stderr,"getDefaultName() returns  %s\n",device->getDefaultName());
+        } else {
+            //device->setDeviceName("junker");
+            device->setDeviceName(device->getDefaultName());
+        }
+        device->addConfigurationControl();
+        device->init_properties();
+    }
+    device->ISGetProperties(dev);
+}
+
+/**************************************************************************************
+**
+***************************************************************************************/
+void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n)
+{
+    //fprintf(stderr,"Enter ISNewSwitch %s\n",dev);
+
+    //ISInit();
+    //fprintf(stderr,"Calling Device->IsNewSwitch for device %0x\n",(void *)device);
+    device->ISNewSwitch(dev, name, states, names, n);
+}
+
+/**************************************************************************************
+**
+***************************************************************************************/
+void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n)
+{
+    //fprintf(stderr,"Enter ISNewText\n");
+    //ISInit();
+    device->ISNewText(dev, name, texts, names, n);
+}
+
+/**************************************************************************************
+**
+***************************************************************************************/
+void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n)
+{
+    //fprintf(stderr,"OutsideClass::Enter ISNewNumber\n");
+    //ISInit();
+    device->ISNewNumber(dev, name, values, names, n);
+}
+
+/**************************************************************************************
+**
+***************************************************************************************/
+void ISNewBLOB (const char *dev, const char *name, int sizes[], int blobsizes[], char *blobs[], char *formats[], char *names[], int n)
+{
+  INDI_UNUSED(dev);
+  INDI_UNUSED(name);
+  INDI_UNUSED(sizes);
+  INDI_UNUSED(blobsizes);
+  INDI_UNUSED(blobs);
+  INDI_UNUSED(formats);
+  INDI_UNUSED(names);
+  INDI_UNUSED(n);
+}
+
+/**************************************************************************************
+**
+***************************************************************************************/
+void ISSnoopDevice (XMLEle *root)
+{
+    return device->ISSnoopDevice(root);
+}
+
+void timerfunc(void *t)
+{
+    //fprintf(stderr,"Got a timer hit with %x\n",t);
+    if(t==device) {
+        //  this was for my device
+        //  but we dont have a way of telling
+        //  WHICH timer was hit :(
+        device->TimerHit();
+    }
+    return;
+}
+
+
+IndiDevice::IndiDevice()
+{
+    //ctor
+    Connected=false;
+}
+
+IndiDevice::~IndiDevice()
+{
+    //dtor
+}
+
+
+int IndiDevice::init_properties()
+{
+    //  All devices should have a connection switch defined
+    //  so lets create it
+
+    //IDLog("IndiDevice::init_properties()  MyDev=%s\n",deviceName());
+    IUFillSwitch(&ConnectionS[0],"CONNECT","Connect",ISS_OFF);
+    IUFillSwitch(&ConnectionS[1],"DISCONNECT","Disconnect",ISS_ON);
+    IUFillSwitchVector(&ConnectionSV,ConnectionS,2,deviceName(),"CONNECTION","Connection","Main Control",IP_RW,ISR_1OFMANY,60,IPS_IDLE);
+
+    return 0;
+}
+
+bool IndiDevice::DeleteProperty(char *n)
+{
+    IDDelete(deviceName(),n,NULL);
+    return true;
+}
+
+void IndiDevice::ISGetProperties(const char *dev)
+{
+
+    //  Now lets send the ones we have defined
+    //IDLog("IndiDevice::ISGetProperties %s\n",dev);
+    IDDefSwitch (&ConnectionSV, NULL);
+
+    if(Connected) UpdateProperties();   //  If already connected, send the rest
+    //  And now get the default driver to send what it wants to send
+    INDI::DefaultDriver::ISGetProperties(dev);
+
+
+}
+
+/**************************************************************************************
+** Process Text properties
+***************************************************************************************/
+bool IndiDevice::ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n)
+{
+
+    //  And this base class doesn't actually process anything
+    return INDI::DefaultDriver::ISNewText(dev,name,texts,names,n);
+}
+
+/**************************************************************************************
+**  Process Numbers
+***************************************************************************************/
+bool IndiDevice::ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n)
+{
+
+    //  Our base class doesn't actually do any processing
+    return INDI::DefaultDriver::ISNewNumber(dev,name,values,names,n);
+}
+
+/**************************************************************************************
+**  Process switches
+***************************************************************************************/
+bool IndiDevice::ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n)
+{
+
+    //  Ok, lets Process any switches we actually handle here
+    if(strcmp(dev,deviceName())==0) {
+        //  it's for this device
+
+        if(strcmp(name,ConnectionSV.name)==0) {
+                bool rc;
+                //IDLog("IndiDevice Switch %s\n",names[x]);
+
+                IUUpdateSwitch(&ConnectionSV,states,names,n);
+
+                if(ConnectionS[0].s==ISS_ON) {
+                    if(!Connected) {
+                        rc=Connect();
+                        if(rc) {
+                            ConnectionSV.s=IPS_OK;
+                            //setConnected(true,"calling setconnected");
+                            //ConnectionS[0].s=ISS_ON;
+                            //ConnectionS[1].s=ISS_OFF;
+                            Connected=true;
+                        } else {
+                            //ConnectionS[0].s=ISS_OFF;
+                            //ConnectionS[1].s=ISS_ON;
+                            ConnectionSV.s=IPS_ALERT;
+                            Connected=false;
+                        }
+                    }
+                    UpdateProperties();
+                    IDSetSwitch(&ConnectionSV,NULL);
+                } else {
+                    if(Connected) rc=Disconnect();
+                    //ConnectionS[0].s=ISS_OFF;
+                    //ConnectionS[1].s=ISS_ON;
+                    ConnectionSV.s=IPS_IDLE;
+                    Connected=false;
+                    UpdateProperties();
+                    IDSetSwitch(&ConnectionSV,NULL);
+                }
+
+                /*
+                if(strcmp(names[x],"CONNECT")==0) {
+                    //  We are being requested to make a physical connection to the device
+                    rc=Connect();
+                    if(rc) {
+                        //  Connection Succeeded
+                        ConnectionSV.s=IPS_OK;
+                        Connected=true;
+
+                    } else {
+                        //  Connection Failed
+                        ConnectionSV.s=IPS_ALERT;
+                        Connected=false;
+                    }
+                    IUUpdateSwitch(&ConnectionSV,states,names,n);
+                    IDSetSwitch(&ConnectionSV,NULL);
+                    IDLog("Connect ccalling update properties\n");
+                    UpdateProperties();
+                    //return true;
+                }
+                if(strcmp(names[x],"DISCONNECT")==0) {
+                    //  We are being told to disconnect from the device
+                    rc=Disconnect();
+                    if(rc) {
+                        ConnectionSV.s=IPS_IDLE;
+                    } else {
+                        ConnectionSV.s=IPS_ALERT;
+                    }
+                    Connected=false;
+                    IDLog("Disconnect calling update properties\n");
+                    UpdateProperties();
+                    //  And now lets tell everybody how it went
+                    IUUpdateSwitch(&ConnectionSV,states,names,n);
+                    IDSetSwitch(&ConnectionSV,NULL);
+                    return true;
+                }
+                */
+            //}
+        }
+    }
+
+
+    // let the default driver have a crack at it
+    return INDI::DefaultDriver::ISNewSwitch(dev, name, states, names, n);
+}
+
+//  This is a helper function
+//  that just encapsulates the Indi way into our clean c++ way of doing things
+int IndiDevice::SetTimer(int t)
+{
+    return IEAddTimer(t,timerfunc,this);
+}
+
+//  Just another helper to help encapsulate indi into a clean class
+void IndiDevice::RemoveTimer(int t)
+{
+    IERmTimer(t);
+    return;
+}
+//  This is just a placeholder
+//  This function should be overriden by child classes if they use timers
+//  So we should never get here
+void IndiDevice::TimerHit()
+{
+    return;
+}
+
+bool IndiDevice::Connect()
+{
+    //  We dont actually implement a device here
+    //  So we cannot connect to it
+    IDMessage(deviceName(),"IndiDevice:: has no device attached....");
+    return false;
+}
+
+bool IndiDevice::Disconnect()
+{
+    //  Since we cannot connect, we cant disconnect either
+    IDMessage(deviceName(),"IndiDevice:: has no device to detach....");
+    return false;
+}
+
+bool IndiDevice::UpdateProperties()
+{
+    //  The base device has no properties to update
+    return true;
+}
+
+void IndiDevice::ISSnoopDevice (XMLEle *root)
+{
+      INDI_UNUSED(root);
+}
+
+bool IndiDevice::SaveConfig()
+{
+
+    // FIXME REMOVE THIS
+    return true;
+
+    char err[MAXRBUF];
+    FILE *fp;
+    //int rc;
+
+    fp=IUGetConfigFP(NULL,deviceName(),err);
+    if(fp != NULL) {
+        IUSaveConfigTag(fp,0);
+        //IUSaveConfigText(fp,&FilterNameTV);
+        //  Tell child classes to write any items they want
+        //  into persistent storage
+        WritePersistentConfig(fp);
+        IUSaveConfigTag(fp,1);
+        fclose(fp);
+        //IDMessage(deviceName(),"Configuration Saved\n");
+        return true;
+    } else {
+        IDMessage(deviceName(),"Save config failed\n");
+    }
+    return false;
+}
+
+bool IndiDevice::WritePersistentConfig(FILE *f)
+{
+    return false;
+}
+
+bool IndiDevice::LoadConfig()
+{
+    char err[MAXRBUF];
+    int rc;
+
+    rc=IUReadConfig(NULL,deviceName(),err);
+    if(rc==0) return true;
+    return false;
+}
Index: /BAORadio/libindi/libindi/libs/indibase/indidevice.h
===================================================================
--- /BAORadio/libindi/libindi/libs/indibase/indidevice.h	(revision 504)
+++ /BAORadio/libindi/libindi/libs/indibase/indidevice.h	(revision 504)
@@ -0,0 +1,86 @@
+/*******************************************************************************
+  Copyright(c) 2010 Gerry Rozema. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published by the Free
+  Software Foundation; either version 2 of the License, or (at your option)
+  any later version.
+
+  This program is distributed in the hope that it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc., 59
+  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+  The full GNU General Public License is included in this distribution in the
+  file called LICENSE.
+*******************************************************************************/
+#ifndef INDIDEVICE_H
+#define INDIDEVICE_H
+
+#include <libindi/indidevapi.h>
+#include <libindi/indicom.h>
+#include <libindi/defaultdriver.h>
+
+
+class IndiDevice : public INDI::DefaultDriver
+{
+
+    private:
+
+    protected:
+    public:
+        IndiDevice();
+        virtual ~IndiDevice();
+
+        //  These are the properties we define, that are generic to pretty much all devices
+        //  They are public to make them available to all dervied classes and thier children
+        ISwitchVectorProperty ConnectionSV; //  Vector of switches for our connection stuff
+        ISwitch ConnectionS[2];
+
+        //  Helper functions that encapsulate the indi way of doing things
+        //  and give us a clean c++ class method
+
+        virtual int init_properties();
+        //  This will be called after connecting
+        //  to flesh out and update properties to the
+        //  client when the device is connected
+        virtual bool UpdateProperties();
+
+        //  A helper for child classes
+        virtual bool DeleteProperty(char *);
+
+        //  A state variable applicable to all devices
+        //  and I cant get any intelligent result from the parent
+        //  class calling isConnected or setConnected, so, we wont use it
+        bool Connected;
+
+        int SetTimer(int);
+        void RemoveTimer(int);
+        virtual void TimerHit();
+
+        //  The function dispatchers required for all drivers
+        virtual void ISGetProperties (const char *dev);
+        virtual bool ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n);
+        virtual bool ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n);
+        virtual bool ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n);
+        virtual void ISSnoopDevice (XMLEle *root);
+
+        //  some virtual functions that our underlying classes are meant to override
+        virtual bool Connect();
+        virtual bool Disconnect();
+        virtual char *getDefaultName()=0;
+
+        virtual bool SaveConfig();
+        virtual bool LoadConfig();
+        virtual bool WritePersistentConfig(FILE *);
+
+};
+
+extern IndiDevice *device;
+extern IndiDevice *_create_device();
+
+#endif // INDIDEVICE_H
Index: /BAORadio/libindi/libindi/libs/indibase/indifilterwheel.cpp
===================================================================
--- /BAORadio/libindi/libindi/libs/indibase/indifilterwheel.cpp	(revision 504)
+++ /BAORadio/libindi/libindi/libs/indibase/indifilterwheel.cpp	(revision 504)
@@ -0,0 +1,194 @@
+/*******************************************************************************
+  Copyright(c) 2010 Gerry Rozema. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published by the Free
+  Software Foundation; either version 2 of the License, or (at your option)
+  any later version.
+
+  This program is distributed in the hope that it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc., 59
+  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+  The full GNU General Public License is included in this distribution in the
+  file called LICENSE.
+*******************************************************************************/
+
+#include "indifilterwheel.h"
+
+#include <string.h>
+
+INDI::FilterWheel::FilterWheel()
+{
+    //ctor
+    MaxFilter=12;
+}
+
+INDI::FilterWheel::~FilterWheel()
+{
+    //dtor
+}
+
+bool INDI::FilterWheel::initProperties()
+{
+    DefaultDriver::initProperties();   //  let the base class flesh in what it wants
+
+    IUFillNumber(&FilterSlotN[0],"FILTER_SLOT_VALUE","Filter","%3.0f",1.0,12.0,1.0,1.0);
+    IUFillNumberVector(&FilterSlotNV,FilterSlotN,1,deviceName(),"FILTER_SLOT","Filter","Main Control",IP_RW,60,IPS_IDLE);
+
+    IUFillText(&FilterNameT[0],"FILTER1","1","");
+    IUFillText(&FilterNameT[1],"FILTER2","2","");
+    IUFillText(&FilterNameT[2],"FILTER3","3","");
+    IUFillText(&FilterNameT[3],"FILTER4","4","");
+    IUFillText(&FilterNameT[4],"FILTER5","5","");
+    IUFillText(&FilterNameT[5],"FILTER6","6","");
+    IUFillText(&FilterNameT[6],"FILTER7","7","");
+    IUFillText(&FilterNameT[7],"FILTER8","8","");
+    IUFillText(&FilterNameT[8],"FILTER9","9","");
+    IUFillText(&FilterNameT[9],"FILTER10","10","");
+    IUFillText(&FilterNameT[10],"FILTER11","11","");
+    IUFillText(&FilterNameT[11],"FILTER12","12","");
+    IUFillTextVector(&FilterNameTV,FilterNameT,12,deviceName(),"FILTER_NAME","Filter","Filters",IP_RW,60,IPS_IDLE);
+
+    return 0;
+}
+
+void INDI::FilterWheel::ISGetProperties (const char *dev)
+{
+    //  First we let our parent populate
+    //IDLog("INDI::FilterWheel::ISGetProperties %s\n",dev);
+    DefaultDriver::ISGetProperties(dev);
+    if(isConnected())
+    {
+        defineNumber(&FilterSlotNV);
+        defineText(&FilterNameTV);
+    }
+    return;
+}
+
+bool INDI::FilterWheel::updateProperties()
+{
+    //  Define more properties after we are connected
+    //  first we want to update the values to reflect our actual wheel
+
+    if(isConnected())
+    {
+        IUFillNumber(&FilterSlotN[0],"FILTER_SLOT_VALUE","Filter","%3.0f",MinFilter,MaxFilter,1.0,CurrentFilter);
+        defineNumber(&FilterSlotNV);
+        IUFillTextVector(&FilterNameTV,FilterNameT,MaxFilter,deviceName(),"FILTER_NAME","Filter","Filters",IP_RW,60,IPS_IDLE);
+        defineText(&FilterNameTV);
+        //LoadFilterNames();
+    } else
+    {
+        deleteProperty(FilterSlotNV.name);
+        deleteProperty(FilterNameTV.name);
+    }
+
+    return true;
+}
+
+bool INDI::FilterWheel::ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n)
+{
+    //  first check if it's for our device
+    //IDLog("INDI::FilterWheel::ISNewNumber %s\n",name);
+    if(strcmp(dev,deviceName())==0) {
+        //  This is for our device
+        //  Now lets see if it's something we process here
+
+        if(strcmp(name,"FILTER_SLOT")==0) {
+
+            int f;
+
+            f=-1;
+            for(int x=0; x<n; x++) {
+                if(strcmp(names[x],"FILTER_SLOT_VALUE")==0) {
+                    //  This is the new filter number we are being asked
+                    //  to set as active
+                    f=values[x];
+                }
+            }
+
+            if(f != -1) {
+                //IDLog("Filter wheel got a filter slot change\n");
+                //  tell the client we are busy changing the filter
+                FilterSlotNV.s=IPS_BUSY;
+                IDSetNumber(&FilterSlotNV,NULL);
+                //  Tell the hardware to change
+                SelectFilter(f);
+                //  tell the caller we processed this
+                return true;
+            }
+        }
+    }
+    //  if we didn't process it, continue up the chain, let somebody else
+    //  give it a shot
+    return DefaultDriver::ISNewNumber(dev,name,values,names,n);
+}
+
+bool INDI::FilterWheel::ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n)
+{
+    //  Ok, lets see if this is a property wer process
+    //IDLog("INDI::FilterWheel got %d new text items name %s\n",n,name);
+    //  first check if it's for our device
+    if(strcmp(dev,deviceName())==0) {
+        //  This is for our device
+        //  Now lets see if it's something we process here
+        if(strcmp(name,FilterNameTV.name)==0) {
+            //  This is our port, so, lets process it
+
+            //  Some clients insist on sending a port
+            //  and they may not be configured for the
+            //  correct port
+            //  If we are already connected
+            //  and running, it makes absolutely no sense
+            //  to accept a new port value
+            //  so lets just lie to them and say
+            //  we did this, but, dont actually change anything
+            //if(Connected) return true;
+
+            int rc;
+            //IDLog("calling update text\n");
+            FilterNameTV.s=IPS_OK;
+            rc=IUUpdateText(&FilterNameTV,texts,names,n);
+            //IDLog("update text returns %d\n",rc);
+            //  Update client display
+            IDSetText(&FilterNameTV,NULL);
+            //SaveConfig();
+
+            //  We processed this one, so, tell the world we did it
+            return true;
+        }
+
+    }
+
+    return DefaultDriver::ISNewText(dev,name,texts,names,n);
+}
+
+int INDI::FilterWheel::SelectFilterDone(int f)
+{
+    //  The hardware has finished changing
+    //  filters
+    FilterSlotN[0].value=f;
+    FilterSlotNV.s=IPS_OK;
+    // Tell the clients we are done, and
+    //  filter is now useable
+    IDSetNumber(&FilterSlotNV,NULL);
+    return 0;
+}
+
+int INDI::FilterWheel::SelectFilter(int)
+{
+    return -1;
+}
+
+int INDI::FilterWheel::QueryFilter()
+{
+    return -1;
+}
+
+
Index: /BAORadio/libindi/libindi/libs/indibase/indifilterwheel.h
===================================================================
--- /BAORadio/libindi/libindi/libs/indibase/indifilterwheel.h	(revision 504)
+++ /BAORadio/libindi/libindi/libs/indibase/indifilterwheel.h	(revision 504)
@@ -0,0 +1,66 @@
+/*******************************************************************************
+  Copyright(c) 2010 Gerry Rozema. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published by the Free
+  Software Foundation; either version 2 of the License, or (at your option)
+  any later version.
+
+  This program is distributed in the hope that it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc., 59
+  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+  The full GNU General Public License is included in this distribution in the
+  file called LICENSE.
+*******************************************************************************/
+#ifndef INDI_FILTERWHEEL_H
+#define INDI_FILTERWHEEL_H
+
+#include "defaultdriver.h"
+
+class INDI::FilterWheel: public INDI::DefaultDriver
+{
+    protected:
+    private:
+
+    public:
+        FilterWheel();
+        virtual ~FilterWheel();
+
+        INumberVectorProperty FilterSlotNV;   //  A number vector for filter slot
+        INumber FilterSlotN[1];
+
+        ITextVectorProperty FilterNameTV; //  A text vector that stores out physical port name
+        IText FilterNameT[12];
+
+        int MinFilter;
+        int MaxFilter;
+        int CurrentFilter;
+        int TargetFilter;
+
+
+        virtual bool initProperties();
+        virtual bool updateProperties();
+        virtual void ISGetProperties (const char *dev);
+
+        //  Ok, we do need our virtual functions from the base class for processing
+        //  client requests
+        //  We process Numbers and text in a filter wheel
+        virtual bool ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n);
+        virtual bool ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n);
+        virtual bool ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n) { return false; }
+
+        virtual int SelectFilter(int);
+        virtual int SelectFilterDone(int);
+        virtual int QueryFilter();
+        //int SaveFilterNames();
+        //int LoadFilterNames();
+
+};
+
+#endif // INDI::FilterWheel_H
Index: /BAORadio/libindi/libindi/libs/indibase/indifocuser.cpp
===================================================================
--- /BAORadio/libindi/libindi/libs/indibase/indifocuser.cpp	(revision 504)
+++ /BAORadio/libindi/libindi/libs/indibase/indifocuser.cpp	(revision 504)
@@ -0,0 +1,165 @@
+/*******************************************************************************
+  Copyright(c) 2010 Gerry Rozema. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published by the Free
+  Software Foundation; either version 2 of the License, or (at your option)
+  any later version.
+
+  This program is distributed in the hope that it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc., 59
+  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+  The full GNU General Public License is included in this distribution in the
+  file called LICENSE.
+*******************************************************************************/
+#include "indifocuser.h"
+
+#include <string.h>
+
+INDI::Focuser::Focuser()
+{
+    //ctor
+}
+
+INDI::Focuser::~Focuser()
+{
+    //dtor
+}
+
+bool INDI::Focuser::initProperties()
+{
+    DefaultDriver::initProperties();   //  let the base class flesh in what it wants
+
+    IUFillNumber(&FocusspeedN[0],"FOCUS_SPEED_VALUE","Focus Speed","%3.0f",0.0,255.0,1.0,255.0);
+    IUFillNumberVector(&FocusspeedNV,FocusspeedN,1,deviceName(),"FOCUS_SPEED","Speed","Main Control",IP_RW,60,IPS_OK);
+
+    IUFillNumber(&FocustimerN[0],"FOCUS_TIMER_VALUE","Focus Timer","%4.0f",0.0,1000.0,10.0,1000.0);
+    IUFillNumberVector(&FocustimerNV,FocustimerN,1,deviceName(),"FOCUS_TIMER","Timer","Main Control",IP_RW,60,IPS_OK);
+
+    IUFillSwitch(&FocusmotionS[0],"FOCUS_INWARD","Focus In",ISS_ON);
+    IUFillSwitch(&FocusmotionS[1],"FOCUS_OUTWARD","Focus Out",ISS_OFF);
+    IUFillSwitchVector(&FocusmotionSV,FocusmotionS,2,deviceName(),"FOCUS_MOTION","Focus Direction","Main Control",IP_RW,ISR_1OFMANY,60,IPS_OK);
+
+
+    return 0;
+}
+
+void INDI::Focuser::ISGetProperties (const char *dev)
+{
+    //  First we let our parent populate
+    IDLog("INDI::Focuser::ISGetProperties %s\n",dev);
+    DefaultDriver::ISGetProperties(dev);
+
+    return;
+}
+
+bool INDI::Focuser::updateProperties()
+{
+    if(isConnected())
+    {
+        //  Now we add our focusser specific stuff
+        IDDefSwitch(&FocusmotionSV, NULL);
+        IDDefNumber(&FocusspeedNV, NULL);
+        IDDefNumber(&FocustimerNV, NULL);
+    } else
+    {
+        deleteProperty(FocusmotionSV.name);
+        deleteProperty(FocusspeedNV.name);
+        deleteProperty(FocustimerNV.name);
+    }
+    return true;
+}
+
+
+bool INDI::Focuser::ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n)
+{
+    //  first check if it's for our device
+    IDLog("INDI::Focuser::ISNewNumber %s\n",name);
+    if(strcmp(dev,deviceName())==0) {
+        //  This is for our device
+        //  Now lets see if it's something we process here
+        if(strcmp(name,"FOCUS_TIMER")==0) {
+            //  Ok, gotta move the focusser now
+            int dir;
+            int speed;
+            int t;
+
+            //IDLog(")
+            //  first we get all the numbers just sent to us
+            FocustimerNV.s=IPS_OK;
+            IUUpdateNumber(&FocustimerNV,values,names,n);
+
+            //  Now lets find what we need for this move
+            speed=FocusspeedN[0].value;
+            if(FocusmotionS[0].s==ISS_ON) dir=1;
+            else dir=0;
+            t=FocustimerN[0].value;
+
+            Move(dir,speed,t);
+
+
+            //  Update client display
+            IDSetNumber(&FocustimerNV,NULL);
+            return true;
+        }
+
+
+        if(strcmp(name,"FOCUS_SPEED")==0) {
+
+
+            FocusspeedNV.s=IPS_OK;
+            IUUpdateNumber(&FocusspeedNV,values,names,n);
+
+
+
+            //  Update client display
+            IDSetNumber(&FocusspeedNV,NULL);
+            return true;
+        }
+
+    }
+
+
+    return DefaultDriver::ISNewNumber(dev,name,values,names,n);
+}
+
+bool INDI::Focuser::ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n)
+{
+    IDLog("Enter IsNewSwitch for %s\n",name);
+    //for(int x=0; x<n; x++) {
+    //    IDLog("Switch %s %d\n",names[x],states[x]);
+    //}
+
+    if(strcmp(dev,deviceName())==0) {
+        //  This one is for us
+        if(strcmp(name,"FOCUS_MOTION")==0) {
+            //  client is telling us what to do with focus direction
+            FocusmotionSV.s=IPS_OK;
+            IUUpdateSwitch(&FocusmotionSV,states,names,n);
+            //  Update client display
+            IDSetSwitch(&FocusmotionSV,NULL);
+
+            return true;
+        }
+
+    }
+
+    //  Nobody has claimed this, so, ignore it
+    return DefaultDriver::ISNewSwitch(dev,name,states,names,n);
+}
+
+int INDI::Focuser::Move(int,int,int)
+{
+    //  This should be a virtual function, because the low level hardware class
+    //  must override this
+    //  but it's much easier early development if the method actually
+    //  exists for now
+    return -1;
+}
+
Index: /BAORadio/libindi/libindi/libs/indibase/indifocuser.h
===================================================================
--- /BAORadio/libindi/libindi/libs/indibase/indifocuser.h	(revision 504)
+++ /BAORadio/libindi/libindi/libs/indibase/indifocuser.h	(revision 504)
@@ -0,0 +1,61 @@
+/*******************************************************************************
+  Copyright(c) 2010 Gerry Rozema. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published by the Free
+  Software Foundation; either version 2 of the License, or (at your option)
+  any later version.
+
+  This program is distributed in the hope that it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc., 59
+  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+  The full GNU General Public License is included in this distribution in the
+  file called LICENSE.
+*******************************************************************************/
+
+#ifndef INDIFOCUSSER_H
+#define INDIFOCUSSER_H
+
+#include "defaultdriver.h"
+
+class INDI::Focuser : public INDI::DefaultDriver
+{
+
+    protected:
+    private:
+
+    public:
+        Focuser();
+        virtual ~Focuser();
+
+        INumberVectorProperty FocusspeedNV;
+        INumber FocusspeedN[1];
+        ISwitchVectorProperty FocusmotionSV; //  A Switch in the client interface to park the scope
+        ISwitch FocusmotionS[2];
+        INumberVectorProperty FocustimerNV;
+        INumber FocustimerN[1];
+
+
+        virtual bool initProperties();
+        virtual void ISGetProperties (const char *dev);
+        bool updateProperties();
+
+
+        //  Ok, we do need our virtual functions from the base class for processing
+        //  client requests
+        //  We process Numbers in a focusser
+        virtual bool ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n);
+        virtual bool ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n);
+
+        //  And here are the virtual functions we will have for easy overrides
+        virtual int Move(int, int, int);
+
+};
+
+#endif // INDIFOCUSSER_H
Index: /BAORadio/libindi/libindi/libs/indibase/inditelescope.cpp
===================================================================
--- /BAORadio/libindi/libindi/libs/indibase/inditelescope.cpp	(revision 504)
+++ /BAORadio/libindi/libindi/libs/indibase/inditelescope.cpp	(revision 504)
@@ -0,0 +1,458 @@
+/*******************************************************************************
+  Copyright(c) 2010 Gerry Rozema. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published by the Free
+  Software Foundation; either version 2 of the License, or (at your option)
+  any later version.
+
+  This program is distributed in the hope that it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc., 59
+  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+  The full GNU General Public License is included in this distribution in the
+  file called LICENSE.
+*******************************************************************************/
+
+#include "inditelescope.h"
+#include "libs/indicom.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <math.h>
+#include <unistd.h>
+#include <time.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <termios.h>
+
+#define POLLMS 1000
+
+INDI::Telescope::Telescope()
+{
+    //ctor
+}
+
+INDI::Telescope::~Telescope()
+{
+    //dtor
+}
+
+bool INDI::Telescope::initProperties()
+{
+    DefaultDriver::initProperties();
+
+    EqNV = new INumberVectorProperty;
+
+    IUFillNumber(&EqN[0],"RA","RA (hh:mm:ss)","%010.6m",0,24,0,0);
+    IUFillNumber(&EqN[1],"DEC","DEC (dd:mm:ss)","%010.6m",-90,90,0,0);
+    IUFillNumberVector(EqNV,EqN,2,deviceName(),"EQUATORIAL_EOD_COORD","Eq. Coordinates","Main Control",IP_RO,60,IPS_IDLE);
+
+    EqReqNV = new INumberVectorProperty;
+
+    IUFillNumber(&EqReqN[0],"RA","RA (hh:mm:ss)","%010.6m",0,24,0,0);
+    IUFillNumber(&EqReqN[1],"DEC","DEC (dd:mm:ss)","%010.6m",-90,90,0,0);
+    IUFillNumberVector(EqReqNV,EqReqN,2,deviceName(),"EQUATORIAL_EOD_COORD_REQUEST","GOTO","Controls",IP_WO,60,IPS_IDLE);
+
+    LocationNV = new INumberVectorProperty;
+
+    IUFillNumber(&LocationN[0],"LAT","Lat (dd:mm:ss)","%010.6m",-90,90,0,0.0);
+    IUFillNumber(&LocationN[1],"LONG","Lon (dd:mm:ss)","%010.6m",0,360,0,0.0 );
+    IUFillNumberVector(LocationNV,LocationN,2,deviceName(),"GEOGRAPHIC_COORD","Scope Location","Location",IP_RW,60,IPS_OK);
+
+    CoordSV = new ISwitchVectorProperty;
+
+    IUFillSwitch(&CoordS[0],"TRACK","Track",ISS_OFF);
+    IUFillSwitch(&CoordS[1],"SLEW","Slew",ISS_OFF);
+    IUFillSwitch(&CoordS[2],"SYNC","Sync",ISS_OFF);
+    IUFillSwitchVector(CoordSV,CoordS,3,deviceName(),"ON_COORD_SET","On Set","Controls",IP_RW,ISR_1OFMANY,60,IPS_IDLE);
+
+    ParkSV = new ISwitchVectorProperty;
+
+    IUFillSwitch(&ParkS[0],"PARK","Park",ISS_OFF);
+    IUFillSwitchVector(ParkSV,ParkS,1,deviceName(),"TELESCOPE_PARK","Park","Controls",IP_RW,ISR_1OFMANY,60,IPS_IDLE);
+
+    PortTV = new ITextVectorProperty;
+
+    IUFillText(&PortT[0],"PORT","Port","/dev/ttyUSB0");
+    IUFillTextVector(PortTV,PortT,1,deviceName(),"DEVICE_PORT","Ports","Options",IP_RW,60,IPS_IDLE);
+
+    TrackState=SCOPE_PARKED;
+    return 0;
+}
+
+void INDI::Telescope::ISGetProperties (const char *dev)
+{
+    //  First we let our parent populate
+    //IDLog("INDI::Telescope::ISGetProperties %s\n",dev);
+    DefaultDriver::ISGetProperties(dev);
+
+    //  We may need the port set before we can connect
+    //IDDefText(&PortTV,NULL);
+    //LoadConfig();
+
+    if(isConnected())
+    {
+        //  Now we add our telescope specific stuff
+        defineSwitch(CoordSV);
+        defineNumber(EqNV);
+        defineNumber(EqReqNV);
+        defineNumber(LocationNV);
+        defineSwitch(ParkSV);
+    }
+    return;
+}
+
+bool INDI::Telescope::updateProperties()
+{
+    if(isConnected())
+    {
+        //  Now we add our telescope specific stuff
+        //IDLog("INDI::Telescope adding properties\n");
+        defineSwitch(CoordSV);
+        defineNumber(EqNV);
+        defineNumber(EqReqNV);
+        //IDDefText(&PortTV,NULL);
+        defineNumber(LocationNV);
+        defineSwitch(ParkSV);
+    } else
+    {
+        //IDLog("INDI::Telescope deleting properties\n");
+        deleteProperty(CoordSV->name);
+        deleteProperty(EqNV->name);
+        deleteProperty(EqReqNV->name);
+        //DeleteProperty(PortTV.name);
+        deleteProperty(LocationNV->name);
+        deleteProperty(ParkSV->name);
+
+        initProperties();
+    }
+    return true;
+}
+
+int INDI::Telescope::NewRaDec(double ra,double dec)
+{
+    //  Lets set our eq values to these numbers
+    //  which came from the hardware
+    EqN[0].value=ra;
+    EqN[1].value=dec;
+
+    if (TrackState == SCOPE_TRACKING && EqReqNV->s != IPS_OK)
+    {
+        EqReqNV->s = IPS_OK;
+        IDSetNumber(EqReqNV, NULL);
+    }
+    if ( (TrackState == SCOPE_PARKED || TrackState == SCOPE_IDLE) && EqReqNV->s != IPS_IDLE)
+    {
+        EqReqNV->s = IPS_IDLE;
+        IDSetNumber(EqReqNV, NULL);
+    }
+
+    return 0;
+}
+
+bool INDI::Telescope::ReadScopeStatus()
+{
+    //  Return an error, because we sholdn't get here
+    return false;
+}
+
+bool INDI::Telescope::Goto(double ra,double dec)
+{
+    //  if we get here, it's because our derived hardware class
+    //  does not support goto
+    return false;
+}
+
+bool INDI::Telescope::Sync(double ra,double dec)
+{
+    //  if we get here, our mount doesn't support sync
+    IDMessage(deviceName(),"Mount does not support Sync");
+    return false;
+}
+
+/**************************************************************************************
+** Process Text properties
+***************************************************************************************/
+bool INDI::Telescope::ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n)
+{
+    //  Ok, lets see if this is a property wer process
+    //IDLog("INDI::Telescope got %d new text items name %s\n",n,name);
+    //  first check if it's for our device
+    if(strcmp(dev,deviceName())==0)
+    {
+        //  This is for our device
+        //  Now lets see if it's something we process here
+        if(strcmp(name,PortTV->name)==0)
+        {
+            //  This is our port, so, lets process it
+
+            //  Some clients insist on sending a port
+            //  and they may not be configured for the
+            //  correct port
+            //  If we are already connected
+            //  and running, it makes absolutely no sense
+            //  to accept a new port value
+            //  so lets just lie to them and say
+            //  we did this, but, dont actually change anything
+            //if(Connected) return true;
+
+            int rc;
+            //IDLog("calling update text\n");
+            PortTV->s=IPS_OK;
+            rc=IUUpdateText(PortTV,texts,names,n);
+            //IDLog("update text returns %d\n",rc);
+            //  Update client display
+            IDSetText(PortTV,NULL);
+            //SaveConfig();
+            //  We processed this one, so, tell the world we did it
+            return true;
+        }
+
+    }
+
+    return DefaultDriver::ISNewText(dev,name,texts,names,n);
+}
+
+/**************************************************************************************
+**
+***************************************************************************************/
+bool INDI::Telescope::ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n)
+{
+    //  first check if it's for our device
+    //IDLog("INDI::Telescope::ISNewNumber %s\n",name);
+    if(strcmp(dev,deviceName())==0)
+    {
+        if(strcmp(name,"EQUATORIAL_EOD_COORD_REQUEST")==0)
+        {
+            //  this is for us, and it is a goto
+            bool rc=false;
+            double ra=-1;
+            double dec=-100;
+
+            for (int x=0; x<n; x++)
+            {
+
+                //IDLog("request stuff %s %4.2f\n",names[x],values[x]);
+
+                INumber *eqp = IUFindNumber (EqNV, names[x]);
+                if (eqp == &EqN[0])
+                {
+                    ra = values[x];
+                } else if (eqp == &EqN[1])
+                {
+                    dec = values[x];
+                }
+            }
+            //IDLog("Got %4.2f %4.2f\n",ra,dec);
+            if ((ra>=0)&&(ra<=24)&&(dec>=-90)&&(dec<=90))
+            {
+                //  we got an ra and a dec, both in range
+                //  And now we let the underlying hardware specific class
+                //  perform the goto
+                //  Ok, lets see if we should be doing a goto
+                //  or a sync
+                ISwitch *sw;
+                sw=IUFindSwitch(CoordSV,"SYNC");
+                if((sw != NULL)&&( sw->s==ISS_ON ))
+                {
+                    //IDLog("Got a sync, we dont process yet\n");
+                    rc=Sync(ra,dec);
+                } else {
+                    //  Ensure we are not showing Parked status
+                    ParkSV->s=IPS_IDLE;
+                    IDSetSwitch(ParkSV,NULL);
+                    rc=Goto(ra,dec);
+                }
+                //  Ok, now we have to put our switches back
+            }
+            return rc;
+        }
+
+        if(strcmp(name,"GEOGRAPHIC_COORD")==0)
+        {
+            //  Client wants to update the lat/long
+            //  For now, we'll allow this, but, in future
+            //  If we have lat/lon from gps, we'll prevent this
+            //  from being updated
+            LocationNV->s=IPS_OK;
+            IUUpdateNumber(LocationNV,values,names,n);
+            //  Update client display
+            IDSetNumber(LocationNV,NULL);
+        }
+    }
+
+
+
+    return DefaultDriver::ISNewNumber(dev,name,values,names,n);
+}
+
+/**************************************************************************************
+**
+***************************************************************************************/
+bool INDI::Telescope::ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n)
+{
+    //IDLog("Enter IsNewSwitch for %s\n",name);
+    //for(int x=0; x<n; x++) {
+    //    IDLog("Switch %s %d\n",names[x],states[x]);
+    //}
+
+    if(strcmp(dev,deviceName())==0)
+    {
+        //  This one is for us
+        if(strcmp(name,"ON_COORD_SET")==0)
+        {
+            //  client is telling us what to do with co-ordinate requests
+            CoordSV->s=IPS_OK;
+            IUUpdateSwitch(CoordSV,states,names,n);
+            //  Update client display
+            IDSetSwitch(CoordSV,NULL);
+
+            for(int x=0; x<n; x++)
+            {
+
+
+            }
+            return true;
+        }
+
+        if(strcmp(name,"TELESCOPE_PARK")==0)
+        {
+            Park();
+        }
+    }
+
+    //  Nobody has claimed this, so, ignore it
+    return DefaultDriver::ISNewSwitch(dev,name,states,names,n);
+}
+
+bool INDI::Telescope::Connect()
+{
+    //  Parent class is wanting a connection
+    //IDLog("INDI::Telescope calling connect with %s\n",PortT[0].text);
+    bool rc=false;
+
+    if(isConnected()) return true;
+
+    //IDLog("Calling Connect\n");
+
+    rc=Connect(PortT[0].text);
+
+    if(rc)
+        SetTimer(POLLMS);
+    return rc;
+}
+
+bool INDI::Telescope::Connect(const char *port)
+{
+    //  We want to connect to a port
+    //  For now, we will assume it's a serial port
+    //struct termios tty;
+
+    int connectrc=0;
+    char errorMsg[MAXRBUF];
+    bool rc;
+
+
+    if ( (connectrc = tty_connect(port, B9600, 8, 0, 1, &PortFD)) != TTY_OK)
+    {
+        tty_error_msg(connectrc, errorMsg, MAXRBUF);
+
+        if (isDebug())
+            IDLog("Failed to connect o port %s. Error: %s", port, errorMsg);
+        IDMessage(deviceName(), "Failed to connect to port %s. Error: %s", port, errorMsg);
+
+        return false;
+
+    }
+
+    /* Flush the input (read) buffer */
+
+    tcflush(PortFD,TCIOFLUSH);
+
+    /* Test connection */
+    rc=ReadScopeStatus();
+    if(rc)
+    {
+        //  We got a valid scope status read
+        IDMessage(deviceName(),"Telescope is online.");
+        return rc;
+    }
+
+    //  Ok, we didn't get a valid read
+    //  So, we need to close our handle and send error messages
+    close(PortFD);
+    //IDMessage(deviceName(),"Didn't find a synscan mount on Serial Port");
+
+    return false;
+}
+
+bool INDI::Telescope::Disconnect()
+{
+    //  We dont actually close the serial connection
+    //  because clients can screw each other up if we allow that
+    //Connected=false;
+
+    close(PortFD);
+    IDMessage(deviceName(),"Telescope is offline.");
+
+    return true;
+}
+
+
+void INDI::Telescope::TimerHit()
+{
+    //IDLog("Timer Hit\n");
+    if(isConnected())
+    {
+        bool rc;
+
+        rc=ReadScopeStatus();
+        //IDLog("TrackState after read is %d\n",TrackState);
+        if(rc)
+        {
+            //  read was good
+            switch(TrackState)
+            {
+              case SCOPE_IDLE:
+              case SCOPE_PARKED:
+                EqNV->s=IPS_IDLE;
+                break;
+
+             case SCOPE_SLEWING:
+             case SCOPE_PARKING:
+                EqNV->s=IPS_BUSY;
+                break;
+
+            case SCOPE_TRACKING:
+                EqNV->s=IPS_OK;
+                break;
+            }
+        } else
+        {
+            //  read was not good
+            EqNV->s=IPS_ALERT;
+        }
+        //IDLog("IsConnected, re-arm timer\n");
+        //  Now update the Client data
+        IDSetNumber(EqNV,NULL);
+        SetTimer(POLLMS);
+    }
+}
+
+
+bool INDI::Telescope::Park()
+{
+    //  We want to park our telescope
+    //  but the scope doesn't seem to support park
+    //  or it wouldn't have gotten here
+    return false;
+}
+
Index: /BAORadio/libindi/libindi/libs/indibase/inditelescope.h
===================================================================
--- /BAORadio/libindi/libindi/libs/indibase/inditelescope.h	(revision 504)
+++ /BAORadio/libindi/libindi/libs/indibase/inditelescope.h	(revision 504)
@@ -0,0 +1,125 @@
+/*******************************************************************************
+  Copyright(c) 2010 Gerry Rozema. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published by the Free
+  Software Foundation; either version 2 of the License, or (at your option)
+  any later version.
+
+  This program is distributed in the hope that it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc., 59
+  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+  The full GNU General Public License is included in this distribution in the
+  file called LICENSE.
+*******************************************************************************/
+
+#ifndef INDI_TELESCOPE_H
+#define INDI_TELESCOPE_H
+
+#include "defaultdriver.h"
+
+class INDI::Telescope : public INDI::DefaultDriver
+{
+    protected:
+        //bool Connected;
+
+    private:
+
+    public:
+        Telescope();
+        virtual ~Telescope();
+
+        enum TelescopeStatus { SCOPE_IDLE, SCOPE_SLEWING, SCOPE_TRACKING, SCOPE_PARKING, SCOPE_PARKED };
+
+        //  All telescopes should produce equatorial co-ordinates
+        INumberVectorProperty *EqNV;
+        INumber EqN[2];
+
+        //  And we need a vector to store requests, ie, where are we asked to go
+        INumberVectorProperty *EqReqNV;
+        INumber EqReqN[2];
+
+        ISwitchVectorProperty *CoordSV; //  A switch vector that stores how we should readct
+        ISwitch CoordS[3];              //  On a coord_set message, sync, or slew
+
+        INumberVectorProperty *LocationNV;   //  A number vector that stores lattitude and longitude
+        INumber LocationN[2];
+
+        ISwitchVectorProperty *ParkSV; //  A Switch in the client interface to park the scope
+        ISwitch ParkS[1];
+
+        //  I dont know of any telescopes that dont
+        //  need a port for connection
+        //  So lets put all the port connect framework
+        //  into our generic telescope super class
+        ITextVectorProperty *PortTV; //  A text vector that stores out physical port name
+        IText PortT[1];
+
+
+        //  Ok, we do need our virtual functions from the base class for processing
+        //  client requests
+        //  We process numbers,switches and text in the telescope
+        //  These are the base IndiDevice overrides we process
+        virtual bool ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n);
+        virtual bool ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n);
+        virtual bool ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n);
+        virtual void ISGetProperties (const char *dev);
+
+        //  overrides of base class virtual functions
+        //  that are specific to our way of implementing Indi
+        virtual bool initProperties();      //  Called to initialize basic properties required all the time
+        virtual bool updateProperties();    //  Called when connected state changes, to add/remove properties
+
+        virtual void TimerHit();
+        virtual bool Connect();
+        virtual bool Disconnect();
+
+        virtual bool Connect(const char *);
+
+
+        //  Since every mount I know of actually uses a serial port for control
+        //  We put the serial helper into the base telescope class
+        //  One less piece to worry about in the hardware specific
+        //  low level stuff
+        int PortFD;
+
+
+        //  This is a variable filled in by the ReadStatus telescope
+        //  low level code, used to report current state
+        //  are we slewing, tracking, or parked.
+        int TrackState;
+
+
+        //  These functions are telescope specific
+        //  and meant to make life really easy for deriving
+        //  hardware specific telescope classes
+        int NewRaDec(double,double);    //  The child class will call this when it has updates
+
+
+        //  And these are the hardware specific functions our children need to override
+        //  They are not pure virtual, because, not all functions are relavent for all types
+        //  of mount, ie, a Goto is not relavent for a Push-to mount
+
+        /** \brief Read telescope status.
+         This function checks the following:
+         <ol>
+           <li>Check if the link to the telescope is alive.</li>
+           <li>Update telescope status: Idle, Slewing, Parking..etc.</li>
+           <li>Read coordinates</li>
+         </ol>
+          \return True if reading scope status is OK, false if an error is encounterd. */
+        virtual bool ReadScopeStatus();
+
+        virtual bool Goto(double ra,double dec);
+        virtual bool Sync(double ra,double dec);
+        virtual bool Park();
+
+};
+
+#endif // INDI::Telescope_H
Index: /BAORadio/libindi/libindi/libs/indibase/indiusbdevice.cpp
===================================================================
--- /BAORadio/libindi/libindi/libs/indibase/indiusbdevice.cpp	(revision 504)
+++ /BAORadio/libindi/libindi/libs/indibase/indiusbdevice.cpp	(revision 504)
@@ -0,0 +1,184 @@
+/*******************************************************************************
+  Copyright(c) 2010 Gerry Rozema. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published by the Free
+  Software Foundation; either version 2 of the License, or (at your option)
+  any later version.
+
+  This program is distributed in the hope that it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc., 59
+  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+  The full GNU General Public License is included in this distribution in the
+  file called LICENSE.
+*******************************************************************************/
+#include "indiusbdevice.h"
+
+#include <string.h>
+
+INDI::USBDevice::USBDevice()
+{
+	dev=NULL;
+	usb_handle=NULL;
+	OutputEndpoint=0;
+	InputEndpoint=0;
+
+	usb_init();
+	usb_find_busses();
+	usb_find_devices();
+}
+
+
+INDI::USBDevice::~USBDevice()
+{
+}
+
+struct usb_device * INDI::USBDevice::FindDevice(int vendor, int product, int searchindex)
+{
+    struct usb_device *dev;
+    struct usb_bus *usb_bus;
+    int index=0;
+
+    for(usb_bus=usb_busses; usb_bus; usb_bus=usb_bus->next) {
+        for(dev=usb_bus->devices; dev; dev=dev->next) {
+            if(dev->descriptor.idVendor==vendor) {
+                if(dev->descriptor.idProduct==product) {
+                    if(index==searchindex) {
+                        fprintf(stderr,"Device has %d configurations\n",dev->descriptor.bNumConfigurations);
+                        return dev;
+                    }
+                    else index++;
+                }
+            }
+        }
+    }
+    return NULL;
+
+}
+
+int INDI::USBDevice::Open()
+{
+	if(dev==NULL) return -1;
+
+	usb_handle=usb_open(dev);
+	if(usb_handle != NULL) {
+		//printf("Opened ok\n");
+
+		return FindEndpoints();
+		//return 0;
+	}
+	return -1;
+}
+
+int INDI::USBDevice::FindEndpoints()
+{
+
+	int rc=0;
+	struct usb_interface_descriptor *intf;
+
+
+
+	intf=&dev->config[0].interface[0].altsetting[0];
+	for(int i=0; i<intf->bNumEndpoints; i++) {
+		fprintf(stderr,"%04x %04x\n",
+			   intf->endpoint[i].bEndpointAddress,
+			   intf->endpoint[i].bmAttributes
+			   );
+
+		int dir;
+		int addr;
+		addr=intf->endpoint[i].bEndpointAddress;
+		addr = addr & (USB_ENDPOINT_DIR_MASK^0xffff);
+		//printf("%02x ",addr);
+
+		int attr;
+		int tp;
+		attr=intf->endpoint[i].bmAttributes;
+		tp=attr&USB_ENDPOINT_TYPE_MASK;
+		//if(tp==USB_ENDPOINT_TYPE_BULK) printf("Bulk  ");
+		//if(tp==USB_ENDPOINT_TYPE_INTERRUPT) printf("Interrupt ");
+
+
+
+		dir=intf->endpoint[i].bEndpointAddress;
+		dir=dir&USB_ENDPOINT_DIR_MASK;
+		if(dir==USB_ENDPOINT_IN) {
+			//printf("Input  ");
+			fprintf(stderr,"Got an input endpoint\n");
+			InputEndpoint=addr;
+			InputType=tp;
+		}
+		if(dir==USB_ENDPOINT_OUT) {
+			//printf("Output ");
+			fprintf(stderr,"got an output endpoint\n");
+			OutputEndpoint=addr;
+			OutputType=tp;
+		}
+		//printf("\n");
+	}
+
+	//printf("claim interface returns %d\n",rc);
+	return rc;
+
+}
+
+int INDI::USBDevice::ReadInterrupt(char *buf,int c,int timeout)
+{
+	int rc;
+
+	rc=usb_interrupt_read(usb_handle,InputEndpoint,buf,c,timeout);
+	//rc=usb_bulk_read(usb_handle,InputEndpoint,buf,c,timeout);
+	return rc;
+
+}
+
+int INDI::USBDevice::WriteInterrupt(char *buf,int c,int timeout)
+{
+	int rc;
+
+	//printf("Writing %02x to endpoint %d\n",buf[0],OutputEndpoint);
+	rc=usb_interrupt_write(usb_handle,OutputEndpoint,buf,c,timeout);
+	return rc;
+
+}
+
+int INDI::USBDevice::ReadBulk(char *buf,int c,int timeout)
+{
+	int rc;
+
+	//rc=usb_interrupt_read(usb_handle,InputEndpoint,buf,c,timeout);
+	rc=usb_bulk_read(usb_handle,InputEndpoint,buf,c,timeout);
+	return rc;
+
+}
+
+int INDI::USBDevice::WriteBulk(char *buf,int c,int timeout)
+{
+	int rc;
+
+	//printf("Writing %02x to endpoint %d\n",buf[0],OutputEndpoint);
+	//rc=usb_interrupt_write(usb_handle,OutputEndpoint,buf,c,timeout);
+	rc=usb_bulk_write(usb_handle,OutputEndpoint,buf,c,timeout);
+	return rc;
+
+}
+
+int INDI::USBDevice::ControlMessage()
+{
+    char buf[3];
+    int rc;
+
+    buf[0]=0;
+    buf[1]=0;
+    buf[2]=0;
+
+    rc=usb_control_msg(usb_handle,0xc2&USB_ENDPOINT_IN, 0x12,0,0,buf,3,1000);
+    fprintf(stderr,"UsbControlMessage returns %d\n",rc);
+    return 0;
+}
Index: /BAORadio/libindi/libindi/libs/indibase/indiusbdevice.h
===================================================================
--- /BAORadio/libindi/libindi/libs/indibase/indiusbdevice.h	(revision 504)
+++ /BAORadio/libindi/libindi/libs/indibase/indiusbdevice.h	(revision 504)
@@ -0,0 +1,67 @@
+/*******************************************************************************
+  Copyright(c) 2010 Gerry Rozema. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published by the Free
+  Software Foundation; either version 2 of the License, or (at your option)
+  any later version.
+
+  This program is distributed in the hope that it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc., 59
+  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+  The full GNU General Public License is included in this distribution in the
+  file called LICENSE.
+*******************************************************************************/
+
+#ifndef USBDEVICE_H
+#define USBDEVICE_H
+
+#pragma once
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <usb.h>
+
+#include "indibase.h"
+
+class INDI::USBDevice
+{
+protected:
+	struct usb_device *dev;
+	struct usb_dev_handle *usb_handle;
+
+	int ProductId;
+	int VendorId;
+
+	int OutputType;
+	int OutputEndpoint;
+	int InputType;
+	int InputEndpoint;
+
+	struct usb_device * FindDevice(int,int,int);
+
+public:
+	int WriteInterrupt(char *,int,int);
+	int ReadInterrupt(char *,int,int);
+
+	int ControlMessage();
+
+	int WriteBulk(char *,int,int);
+	int ReadBulk(char *,int,int);
+	int FindEndpoints();
+	int Open();
+        USBDevice(void);
+        USBDevice(struct usb_device *);
+        virtual ~USBDevice(void);
+};
+
+#endif // USBDEVICE_H
Index: /BAORadio/libindi/libindi/libs/indicom.c
===================================================================
--- /BAORadio/libindi/libindi/libs/indicom.c	(revision 503)
+++ /BAORadio/libindi/libindi/libs/indicom.c	(revision 504)
@@ -34,5 +34,5 @@
 #include <sys/param.h>
 
-//#include <config.h>
+#include <config.h>
 
 #ifdef HAVE_NOVA_H
@@ -248,4 +248,7 @@
 int tty_timeout(int fd, int timeout)
 {
+ if (fd == -1)
+        return TTY_ERRNO;
+
   struct timeval tv;
   fd_set readout;
@@ -276,4 +279,7 @@
 int tty_write(int fd, const char * buf, int nbytes, int *nbytes_written)
 {
+    if (fd == -1)
+           return TTY_ERRNO;
+
   int bytes_w = 0;   
   *nbytes_written = 0;
@@ -297,4 +303,7 @@
 int tty_write_string(int fd, const char * buf, int *nbytes_written)
 {
+    if (fd == -1)
+           return TTY_ERRNO;
+
   unsigned int nbytes;
   int bytes_w = 0;
@@ -321,4 +330,6 @@
 int tty_read(int fd, char *buf, int nbytes, int timeout, int *nbytes_read)
 {
+    if (fd == -1)
+           return TTY_ERRNO;
 
  int bytesRead = 0;
@@ -349,4 +360,6 @@
 int tty_read_section(int fd, char *buf, char stop_char, int timeout, int *nbytes_read)
 {
+    if (fd == -1)
+           return TTY_ERRNO;
 
  int bytesRead = 0;
@@ -496,5 +509,5 @@
                         break;
                 default:
-                        if (snprintf(msg, sizeof(msg), "tty_connect: %d is not a valid bit rate.", bit_rate)  0)
+                        if (snprintf(msg, sizeof(msg), "tty_connect: %d is not a valid bit rate.", bit_rate) < 0)
                                 perror(NULL);
                         else
@@ -521,5 +534,5 @@
 
                         fprintf( stderr, "Default\n") ;
-                        if (snprintf(msg, sizeof(msg), "tty_connect: %d is not a valid data bit count.", word_size)  0)
+                        if (snprintf(msg, sizeof(msg), "tty_connect: %d is not a valid data bit count.", word_size) < 0)
                                 perror(NULL);
                         else
@@ -542,5 +555,5 @@
 
                         fprintf( stderr, "Default1\n") ;
-                        if (snprintf(msg, sizeof(msg), "tty_connect: %d is not a valid parity selection value.", parity)  0)
+                        if (snprintf(msg, sizeof(msg), "tty_connect: %d is not a valid parity selection value.", parity) < 0)
                                 perror(NULL);
                         else
@@ -559,5 +572,5 @@
                 default:
                         fprintf( stderr, "Default2\n") ;
-                        if (snprintf(msg, sizeof(msg), "tty_connect: %d is not a valid stop bit count.", stop_bits)  0)
+                        if (snprintf(msg, sizeof(msg), "tty_connect: %d is not a valid stop bit count.", stop_bits) < 0)
                                 perror(NULL);
                         else
@@ -651,4 +664,5 @@
     {
         close(t_fd);
+        *fd = -1;
     }
 
@@ -662,5 +676,5 @@
 
 #else
- int t_fd=0;
+ int t_fd=-1;
  char msg[80];
  int bps;
@@ -668,5 +682,8 @@
 
  if ( (t_fd = open(device, O_RDWR | O_NOCTTY )) == -1)
+ {
+     *fd = -1;
     return TTY_PORT_FAILURE;
+ }
 
     /* Control Modes
@@ -853,4 +870,7 @@
 int tty_disconnect(int fd)
 {
+    if (fd == -1)
+           return TTY_ERRNO;
+
 #ifdef _WIN32
 	return TTY_ERRNO;
Index: /BAORadio/libindi/libindi/tools/setINDIproperty.c
===================================================================
--- /BAORadio/libindi/libindi/tools/setINDIproperty.c	(revision 503)
+++ /BAORadio/libindi/libindi/tools/setINDIproperty.c	(revision 504)
@@ -71,5 +71,7 @@
 static int readServerChar (FILE *fp);
 static void findSet (XMLEle *root, FILE *fp);
-static void scanEV (SetSpec *sp, char e[], char v[]);
+static void scanEV (SetSpec *specp, char ev[]);
+static void scanEEVV (SetSpec *specp, char *ep, char ev[]);
+static void scanEVEV (SetSpec *specp, char ev[]);
 static void sendNew (FILE *fp, INDIDef *dp, SetSpec *sp);
 static void sendSpecs(FILE *wfp);
@@ -205,7 +207,6 @@
 {
 	fprintf(stderr, "Purpose: set one or more writable INDI properties\n");
-	fprintf(stderr, "%s\n", "$Revision: 1.4 $");
-	fprintf(stderr, "Usage: %s [options] {[type] device.property.e1[;e2...]=v1[;v2...]} ...\n",
-									    me);
+	fprintf(stderr, "%s\n", "$Revision: 1.6 $");
+	fprintf(stderr, "Usage: %s [options] {[type] spec} ...\n", me);
 	fprintf(stderr, "Options:\n");
 	fprintf(stderr, "  -d f  : use file descriptor f already open to server\n");
@@ -213,6 +214,6 @@
 	fprintf(stderr, "  -p p  : alternate port, default is %d\n", INDIPORT);
 	fprintf(stderr, "  -t t  : max time to wait, default is %d secs\n",TIMEOUT);
-	fprintf(stderr, "  -v    : verbose (cumulative)\n");
-	fprintf(stderr, "Each property optionally preceded by its type is sent without first confirming\n");
+	fprintf(stderr, "  -v    : verbose (more are cumulative)\n");
+	fprintf(stderr, "Each spec optionally preceded by its type is sent without first confirming\n");
 	fprintf(stderr, "its structure. This is much more efficient but there is no error checking.\n");
 	fprintf(stderr, "Types are indicated with the following flags:\n");
@@ -220,4 +221,8 @@
 	fprintf(stderr, "  -n    : Number\n");
 	fprintf(stderr, "  -s    : Switch\n");
+	fprintf(stderr, "Spec may be either:\n");
+	fprintf(stderr, "    device.property.e1[;e2...]=v1[;v2...]\n");
+	fprintf(stderr, "  or\n");
+	fprintf(stderr, "    device.property.e1=v1[;e2=v2...]\n");
 	fprintf(stderr, "Exit status:\n");
 	fprintf(stderr, "  0: all settings successful\n");
@@ -234,5 +239,5 @@
 crackSpec (int *acp, char **avp[])
 {
-	char d[1024], p[1024], e[2048], v[2048];
+	char d[128], p[128], ev[2048];
 	char *spec = *avp[0];
 	INDIDef *dp = NULL;
@@ -254,6 +259,6 @@
 
 	/* then scan arg for property spec */
-	if (sscanf (spec, "%[^.].%[^.].%[^.=]=%s", d, p, e, v) != 4) {
-	    fprintf (stderr, "Bad property format: %s\n", spec);
+	if (sscanf (spec, "%[^.].%[^.].%s", d, p, ev) != 3) {
+	    fprintf (stderr, "Malformed property spec: %s\n", spec);
 	    usage();
 	}
@@ -268,5 +273,5 @@
 	sets[nsets].ev = (SetEV *) malloc (1);		/* seed realloc */
 	sets[nsets].nev = 0;
-	scanEV (&sets[nsets++], e, v);
+	scanEV (&sets[nsets++], ev);
 
 	/* update caller's pointers */
@@ -466,30 +471,57 @@
 }
 
-/* scan e1[;e2...] v1[;v2,...] from e[] and v[] and add to spec sp.
+/* scan ev for element definitions in either of two forms and add to sp:
+ *    e1[;e2...]=v1[;v2...]
+ *  or
+ *    e1=v1[;e2=v2...]
+ * exit if nothing sensible found.
+ */
+static void
+scanEV (SetSpec *specp, char ev[])
+{
+	char *ep, *sp;		/* pointers to = and ; */
+
+	if (verbose > 1)
+	    fprintf (stderr, "Scanning assignments %s\n", ev);
+
+	ep = strchr (ev, '=');
+	sp = strchr (ev, ';');
+
+	if (!ep) {
+	    fprintf (stderr, "Malformed assignment: %s\n", ev);
+	    usage();
+	}
+
+	if (sp < ep)
+	    scanEEVV (specp, ep, ev);	/* including just one E=V */
+	else
+	    scanEVEV (specp, ev);
+}
+
+/* add specs of the form e1[;e2...]=v1[;v2...] to sp.
+ * v is pointer to equal sign.
  * exit if trouble.
- */
-static void
-scanEV (SetSpec *sp, char e[], char v[])
+ * N.B. e[] and v[] are modified in place.
+ */
+static void
+scanEEVV (SetSpec *sp, char *v, char *e)
 {
 	static char sep[] = ";";
-	char *ep, *vp;
-
-	if (verbose > 1)
-	    fprintf (stderr, "Scanning %s = %s\n", e, v);
+	char *ec, *vc;
+
+	*v++ = '\0';
 
 	while (1) {
-	    char *e0 = strtok_r (e, sep, &ep);
-	    char *v0 = strtok_r (v, sep, &vp);
+	    char *e0 = strtok_r (e, sep, &ec);
+	    char *v0 = strtok_r (v, sep, &vc);
 
 	    if (!e0 && !v0)
 		break;
 	    if (!e0) {
-		fprintf (stderr, "More values than elements for %s.%s\n",
-								sp->d, sp->p);
+		fprintf (stderr, "More values than elements for %s.%s\n", sp->d, sp->p);
 		exit(2);
 	    }
 	    if (!v0) {
-		fprintf (stderr, "More elements than values for %s.%s\n",
-								sp->d, sp->p);
+		fprintf (stderr, "More elements than values for %s.%s\n", sp->d, sp->p);
 		exit(2);
 	    }
@@ -498,4 +530,6 @@
 	    sp->ev[sp->nev].e = strcpy (malloc(strlen(e0)+1), e0);
 	    sp->ev[sp->nev].v = strcpy (malloc(strlen(v0)+1), v0);
+	    if (verbose > 1)
+		fprintf (stderr, "Found assignment %s=%s\n", sp->ev[sp->nev].e, sp->ev[sp->nev].v);
 	    sp->nev++;
 
@@ -503,4 +537,42 @@
 	    v = NULL;
 	}
+}
+
+/* add specs of the form e1=v1[;e2=v2...] to sp.
+ * exit if trouble.
+ * N.B. ev[] is modified in place.
+ */
+static void
+scanEVEV (SetSpec *sp, char ev[])
+{
+	char *s, *e;
+	int last = 0;
+
+	do {
+	    s = strchr (ev, ';');
+	    if (s)
+		*s++ = '\0';
+	    else {
+		s = ev + strlen (ev);
+		last = 1;
+	    }
+	    e = strchr (ev, '=');
+	    if (e)
+		*e++ = '\0';
+	    else {
+		fprintf (stderr, "Malformed assignment: %s\n", ev);
+		usage();
+	    }
+
+	    sp->ev = (SetEV *) realloc (sp->ev, (sp->nev+1)*sizeof(SetEV));
+	    sp->ev[sp->nev].e = strcpy (malloc(strlen(ev)+1), ev);
+	    sp->ev[sp->nev].v = strcpy (malloc(strlen(e)+1), e);
+	    if (verbose > 1)
+		fprintf (stderr, "Found assignment %s=%s\n", sp->ev[sp->nev].e, sp->ev[sp->nev].v);
+	    sp->nev++;
+
+	    ev = s;
+
+	} while (!last);
 }
 
@@ -517,3 +589,3 @@
 
 /* For RCS Only -- Do Not Edit */
-static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: setINDI.c,v $ $Date: 2007/10/11 20:12:11 $ $Revision: 1.4 $ $Name:  $"};
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: setINDI.c,v $ $Date: 2010/11/07 07:13:59 $ $Revision: 1.6 $ $Name:  $"};
