summaryrefslogtreecommitdiffabout
authorzautrix <zautrix>2004-08-09 14:56:56 (UTC)
committer zautrix <zautrix>2004-08-09 14:56:56 (UTC)
commitad99dd380750834b3ccc4dd6fdcdd446ca5ba7ee (patch) (side-by-side diff)
tree0394df7d796d38e7df637e6d45b82e7945fab55e
parent48f53b2d2e7ed189e88f924259693ab66ff44b7f (diff)
downloadkdepimpi-ad99dd380750834b3ccc4dd6fdcdd446ca5ba7ee.zip
kdepimpi-ad99dd380750834b3ccc4dd6fdcdd446ca5ba7ee.tar.gz
kdepimpi-ad99dd380750834b3ccc4dd6fdcdd446ca5ba7ee.tar.bz2
more phone sync
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--korganizer/calendarview.cpp6
-rw-r--r--libkcal/phoneformat.cpp319
-rw-r--r--libkcal/phoneformat.h13
3 files changed, 156 insertions, 182 deletions
diff --git a/korganizer/calendarview.cpp b/korganizer/calendarview.cpp
index d6ead37..547d02b 100644
--- a/korganizer/calendarview.cpp
+++ b/korganizer/calendarview.cpp
@@ -1186,39 +1186,37 @@ void CalendarView::syncExternal( int mode )
edit_sync_options();
qApp->processEvents();
CalendarLocal* calendar = new CalendarLocal();
calendar->setTimeZoneId(KOPrefs::instance()->mTimeZoneId);
bool syncOK = false;
bool loadSuccess = false;
PhoneFormat* phoneFormat = 0;
#ifndef DESKTOP_VERSION
SharpFormat* sharpFormat = 0;
if ( mode == 0 ) { // sharp
sharpFormat = new SharpFormat () ;
loadSuccess = sharpFormat->load( calendar, mCalendar );
} else
#endif
if ( mode == 1 ) { // phone
- phoneFormat = new PhoneFormat ();
- loadSuccess = phoneFormat->load( calendar,
- mCalendar,
- mCurrentSyncDevice,
+ phoneFormat = new PhoneFormat (mCurrentSyncDevice,
KOPrefs::instance()->mPhoneDevice,
KOPrefs::instance()->mPhoneConnection,
KOPrefs::instance()->mPhoneModel);
+ loadSuccess = phoneFormat->load( calendar,mCalendar);
} else
return;
if ( loadSuccess ) {
getEventViewerDialog()->setSyncMode( true );
syncOK = synchronizeCalendar( mCalendar, calendar, KOPrefs::instance()->mSyncAlgoPrefs );
getEventViewerDialog()->setSyncMode( false );
qApp->processEvents();
if ( syncOK ) {
if ( KOPrefs::instance()->mWriteBackFile )
{
QPtrList<Incidence> iL = mCalendar->rawIncidences();
Incidence* inc = iL.first();
/* obsolete
while ( inc ) {
inc->setZaurusStat( inc->revision () );
diff --git a/libkcal/phoneformat.cpp b/libkcal/phoneformat.cpp
index 596148e..b8fed47 100644
--- a/libkcal/phoneformat.cpp
+++ b/libkcal/phoneformat.cpp
@@ -182,32 +182,33 @@ public:
}
}
// csum *****************************************
QStringList attList;
uint cSum;
if ( todo->hasDueDate() )
attList << dtToString ( todo->dtDue() );
attList << QString::number( id );
attList << todo->summary();
attList << completedString;
attList << QString::number( todo->priority() );
attList << alarmString;
attList << todo->categoriesStr();
attList << todo->secrecyStr();
cSum = PhoneFormat::getCsum(attList );
todo->setCsum( mProfileName, QString::number( cSum ));
+ todo->setTempSyncStat( SYNC_TEMPSTATE_NEW_EXTERNAL );
mCalendar->addTodo( todo);
return true;
}
bool readEvent( Calendar *existingCalendar, GSM_CalendarEntry* Note)
{
int id = Note->Location;
Event *event;
event = existingCalendar->event( mProfileName ,QString::number( id ) );
if ( event )
event = (Event*)event->clone();
else
event = new Event;
event->setID( mProfileName,QString::number( id ) );
event->setTempSyncStat(SYNC_TEMPSTATE_NEW_EXTERNAL );
@@ -484,32 +485,33 @@ public:
}
}
// csum *****************************************
QStringList attList;
uint cSum;
attList << dtToString ( event->dtStart() );
attList << dtToString ( event->dtEnd() );
attList << QString::number( id );
attList << event->summary();
attList << event->location();
attList << alarmString;
attList << recurString;
attList << event->categoriesStr();
attList << event->secrecyStr();
cSum = PhoneFormat::getCsum(attList );
event->setCsum( mProfileName, QString::number( cSum ));
+ event->setTempSyncStat( SYNC_TEMPSTATE_NEW_EXTERNAL );
mCalendar->addEvent( event);
return true;
}
QDateTime fromGSM ( GSM_DateTime* dtp, bool useTz = true ) {
QDateTime dt;
int y,m,t,h,min,sec;
y = dtp->Year;
m = dtp->Month;
t = dtp->Day;
h = dtp->Hour;
min = dtp->Minute;
sec = dtp->Second;
dt = QDateTime(QDate(y,m,t), QTime(h,min,sec));
@@ -578,69 +580,96 @@ public:
case GSM_CAL_T_TENN : CATEGORY = QString("Training/Tennis"); break;
case GSM_CAL_T_TRAV : CATEGORY = QString("Training/Travels"); break;
case GSM_CAL_T_WINT : CATEGORY = QString("Training/Winter Games"); break;
default : CATEGORY = QString("");
}
return CATEGORY;
}
protected:
private:
Calendar *mCalendar;
QString mProfileName ;
};
-PhoneFormat::PhoneFormat()
+PhoneFormat::PhoneFormat(QString profileName, QString device,QString connection, QString model )
{
- ;
+ mProfileName = profileName;
+ mDevice = device;
+ mConnection = connection;
+ mModel = model;
}
PhoneFormat::~PhoneFormat()
{
}
+int PhoneFormat::initDevice(GSM_StateMachine *s)
+{
+ GSM_ReadConfig(NULL, &s->Config[0], 0);
+ s->ConfigNum = 1;
+ GSM_Config *cfg = &s->Config[0];
+ if ( ! mConnection.isEmpty() ) {
+ cfg->Connection = strdup(mConnection.latin1());
+ cfg->DefaultConnection = false;
+ qDebug("Connection set %s ", cfg->Connection );
+
+ }
+ if ( ! mDevice.isEmpty() ) {
+ cfg->Device = strdup(mDevice.latin1());
+ cfg->DefaultDevice = false;
+ qDebug("Device set %s ", cfg->Device);
+
+ }
+ if ( ! mModel.isEmpty() ) {
+ strcpy(cfg->Model,mModel.latin1() );
+ cfg->DefaultModel = false;
+ qDebug("Model set %s ",cfg->Model );
+ }
+ int error=GSM_InitConnection(s,3);
+ return error;
+}
ulong PhoneFormat::getCsum( const QStringList & attList)
{
int max = attList.count() -1;
ulong cSum = 0;
int j,k,i;
int add;
for ( i = 1; i < max ; ++i ) {
QString s = attList[i];
if ( ! s.isEmpty() ){
j = s.length();
for ( k = 0; k < j; ++k ) {
int mul = k +1;
add = s[k].unicode ();
if ( k < 16 )
mul = mul * mul;
add = add * mul *i*i*i;
cSum += add;
}
}
}
return cSum;
}
//extern "C" GSM_Error GSM_InitConnection(GSM_StateMachine *s, int ReplyNum);
#include <stdlib.h>
#define DEBUGMODE false
-bool PhoneFormat::load( Calendar *calendar, Calendar *existingCal ,QString profileName, QString device,QString connection, QString model )
+bool PhoneFormat::load( Calendar *calendar, Calendar *existingCal)
{
- mProfileName = profileName;
GSM_StateMachine s;
qDebug(" load ");
s.opened = false;
s.msg = NULL;
s.ConfigNum = 0;
#if 0
static char *cp;
static INI_Section *cfg = NULL;
cfg=GSM_FindGammuRC();
int i;
for (i = 0; i <= MAX_CONFIG_NUM; i++) {
if (cfg!=NULL) {
cp = (char *)INI_GetValue(cfg, (unsigned char*) "gammu", (unsigned char*)"gammucoding", false);
if (cp) di.coding = cp;
s.Config[i].Localize = (char *)INI_GetValue(cfg, (unsigned char*) "gammu", (unsigned char*) "gammuloc", false);
@@ -663,287 +692,231 @@ bool PhoneFormat::load( Calendar *calendar, Calendar *existingCal ,QString profi
/* Wanted user specific configuration? */
if (!GSM_ReadConfig(cfg, &s.Config[i], i) && i != 0) break;
s.ConfigNum++;
/* We want to use only one file descriptor for global and state machine debug output */
s.Config[i].UseGlobalDebugFile = true;
/* We wanted to read just user specified configuration. */
{break;}
}
#endif
- setlocale(LC_ALL, "");
- GSM_ReadConfig(NULL, &s.Config[0], 0);
- s.ConfigNum = 1;
- GSM_Config *cfg = &s.Config[0];
- if ( ! connection.isEmpty() ) {
- cfg->Connection = strdup(connection.latin1());
- cfg->DefaultConnection = false;
- qDebug("Connection set %s ", cfg->Connection );
-
- }
- if ( ! device.isEmpty() ) {
- cfg->Device = strdup(device.latin1());
- cfg->DefaultDevice = false;
- qDebug("Device set %s ", cfg->Device);
-
- }
- if ( ! model.isEmpty() ) {
- strcpy(cfg->Model,model.latin1() );
- cfg->DefaultModel = false;
- qDebug("Model set %s ",cfg->Model );
-
-
- }
- int error=GSM_InitConnection(&s,3);
+ int error=initDevice(&s);
qDebug("GSM Init %d (no error is %d)", error, ERR_NONE);
if ( error != ERR_NONE )
return false;
GSM_Phone_Functions *Phone;
GSM_CalendarEntry note;
bool start = true;
Phone=s.Phone.Functions;
bool gshutdown = false;
- PhoneParser handler( calendar, profileName );
+ PhoneParser handler( calendar, mProfileName );
int ccc = 0;
qDebug("Debug: only 10 calender items are downloaded ");
while (!gshutdown && ccc++ < 10) {
qDebug("readEvent %d ", ccc);
error=Phone->GetNextCalendar(&s,&note,start);
if (error == ERR_EMPTY) break;
start = false;
handler.readEvent( existingCal, &note );
}
start = true;
GSM_ToDoEntry ToDo;
ccc = 0;
while (!gshutdown) {
error = Phone->GetNextToDo(&s, &ToDo, start);
if (error == ERR_EMPTY) break;
start = false;
qDebug("ReadTodo %d ", ++ccc);
handler.readTodo( existingCal, &ToDo, &s);
}
error=GSM_TerminateConnection(&s);
return true;
}
+void PhoneFormat::event2GSM( Event* ev, GSM_CalendarEntry*Note )
+{
-bool PhoneFormat::save( Calendar *calendar)
+}
+void PhoneFormat::todo2GSM( Todo* todo, GSM_ToDoEntry *gsm )
{
#if 0
- QLabel status ( i18n("Processing/adding events ..."), 0 );
+ QStringList list;
+ list.append( QString::number( todo->zaurusId() ) );
+ list.append( todo->categories().join(",") );
+
+ if ( todo->hasStartDate() ) {
+ list.append( dtToString( todo->dtStart()) );
+ } else
+ list.append( QString() );
+
+ if ( todo->hasDueDate() ) {
+ QTime tim;
+ if ( todo->doesFloat()) {
+ list.append( dtToString( QDateTime(todo->dtDue().date(),QTime( 0,0,0 )), false)) ;
+ } else {
+ list.append( dtToString(todo->dtDue() ) );
+ }
+ } else
+ list.append( QString() );
+
+ if ( todo->isCompleted() ) {
+ list.append( dtToString( todo->completed()) );
+ list.append( "0" ); // yes 0 == completed
+ } else {
+ list.append( dtToString( todo->completed()) );
+ list.append( "1" );
+ }
+ list.append( QString::number( todo->priority() ));
+ if( ! todo->summary().isEmpty() )
+ list.append( todo->summary() );
+ else
+ list.append( "" );
+ if (! todo->description().isEmpty() )
+ list.append( todo->description() );
+ else
+ list.append( "" );
+ for(QStringList::Iterator it=list.begin();
+ it!=list.end(); ++it){
+ QString& s = (*it);
+ s.replace(QRegExp("\""), "\"\"");
+ if(s.contains(QRegExp("[,\"\r\n]")) || s.stripWhiteSpace() != s){
+ s.prepend('\"');
+ s.append('\"');
+ } else if(s.isEmpty() && !s.isNull()){
+ s = "\"\"";
+ }
+ }
+ return list.join(",");
+#endif
+}
+bool PhoneFormat::save( Calendar *calendar)
+{
+ GSM_StateMachine s;
+ qDebug(" save ");
+ s.opened = false;
+ s.msg = NULL;
+ s.ConfigNum = 0;
+ QLabel status ( i18n("Writing data. Opening device ..."), 0 );
int w = status.sizeHint().width()+20 ;
if ( w < 200 ) w = 200;
int h = status.sizeHint().height()+20 ;
int dw = QApplication::desktop()->width();
int dh = QApplication::desktop()->height();
status.setCaption(i18n("Writing DTM Data") );
status.setGeometry( (dw-w)/2, (dh - h )/2 ,w,h );
status.show();
status.raise();
qApp->processEvents();
- bool debug = DEBUGMODE;
- QString codec = "utf8";
- QString answer;
- QString ePrefix = "CARDID,CATEGORY,DSRP,PLCE,MEM1,TIM1,TIM2,ADAY,ARON,ARMN,ARSD,RTYP,RFRQ,RPOS,RDYS,REND,REDT,ALSD,ALED,MDAY\n";
- QString tPrefix = "CARDID,CATEGORY,ETDY,LTDY,FNDY,MARK,PRTY,TITL,MEM1\n";
- QString command;
+
+ int error=initDevice(&s);
+ qDebug("GSM Init %d (no error is %d)", error, ERR_NONE);
+ if ( error != ERR_NONE )
+ return false;
+ GSM_Phone_Functions *Phone;
+ GSM_CalendarEntry Note;
+ bool start = true;
+ Phone=s.Phone.Functions;
+ bool gshutdown = false;
QPtrList<Event> er = calendar->rawEvents();
Event* ev = er.first();
- QString fileName = "/tmp/kopitempout";
- int i = 0;
- QString changeString = ePrefix;
- QString deleteString = ePrefix;
- bool deleteEnt = false;
- bool changeEnt = false;
QString message = i18n("Processing event # ");
int procCount = 0;
while ( ev ) {
//qDebug("i %d ", ++i);
- if ( true /*ev->zaurusStat() != -2*/ ) {
+ if ( ev->tempSyncStat() != SYNC_TEMPSTATE_NEW_EXTERNAL ) { // event was changed during sync or is a new one
+
status.setText ( message + QString::number ( ++procCount ) );
qApp->processEvents();
- QString eString = getEventString( ev );
- if (/* ev->zaurusStat() == -3 */ true) { // delete
- // deleting empty strings does not work.
- // we write first and x and then delete the record with the x
- eString = eString.replace( QRegExp(",\"\""),",\"x\"" );
- changeString += eString + "\n";
- deleteString += eString + "\n";
- deleteEnt = true;
- changeEnt = true;
- }
- else if ( /*ev->zaurusId() == -1*/true ) { // add new
- command = "(echo \"" + ePrefix + eString + "\" ) | db2file datebook -w -g -c " + codec+ " > "+ fileName;
- system ( command.utf8() );
- QFile file( fileName );
- if (!file.open( IO_ReadOnly ) ) {
- return false;
-
+ event2GSM( ev, &Note );
+ if ( ev->tempSyncStat() == SYNC_TEMPSTATE_DELETE ) { // delete
+ error = Phone->DeleteCalendar(&s, &Note);
}
- QTextStream ts( &file );
- ts.setCodec( QTextCodec::codecForName("utf8") );
- answer = ts.read();
- file.close();
- //qDebug("answer \n%s ", answer.latin1());
- getNumFromRecord( answer, ev ) ;
+ else if ( ev->getID(mProfileName).isEmpty() ) { // add new
+ // we have to do this later after deleting
}
else { // change existing
- //qDebug("canging %d %d",ev->zaurusStat() ,ev->zaurusId() );
- //command = "(echo \"" + ePrefix + eString + "\" ) | db2file datebook -w -g -c " + codec+ " > "+ fileName;
- changeString += eString + "\n";
- changeEnt = true;
-
+ error = Phone->AddCalendar(&s, &Note);
}
}
ev = er.next();
}
- status.setText ( i18n("Changing events ...") );
+ ev = er.first();
+ // pending get empty slots
+ while ( ev ) {
+ if ( ev->tempSyncStat() != SYNC_TEMPSTATE_NEW_EXTERNAL && ev->tempSyncStat() != SYNC_TEMPSTATE_DELETE) {
+ if ( ev->getID(mProfileName).isEmpty() ) {
+ status.setText ( message + QString::number ( ++procCount ) );
qApp->processEvents();
- //qDebug("changing... ");
- if ( changeEnt ) {
- QFile file( fileName );
- if (!file.open( IO_WriteOnly ) ) {
- return false;
-
+ int newID ;//= pending
+ ev->setID(mProfileName, QString::number( newID ));
+ event2GSM( ev, &Note );
+ error = Phone->AddCalendar(&s, &Note);
}
- QTextStream ts( &file );
- ts.setCodec( QTextCodec::codecForName("utf8") );
- ts << changeString ;
- file.close();
- command = "db2file datebook -w -g -c " + codec+ " < "+ fileName;
- system ( command.latin1() );
- //qDebug("command %s file :\n%s ", command.latin1(), changeString.latin1());
-
}
- status.setText ( i18n("Deleting events ...") );
- qApp->processEvents();
- //qDebug("deleting... ");
- if ( deleteEnt ) {
- QFile file( fileName );
- if (!file.open( IO_WriteOnly ) ) {
- return false;
-
- }
- QTextStream ts( &file );
- ts.setCodec( QTextCodec::codecForName("utf8") );
- ts << deleteString;
- file.close();
- command = "db2file datebook -d -c " + codec+ " < "+ fileName;
- system ( command.latin1() );
- // qDebug("command %s file :\n%s ", command.latin1(), deleteString.latin1());
+ ev = er.next();
}
-
-
- changeString = tPrefix;
- deleteString = tPrefix;
- status.setText ( i18n("Processing todos ...") );
- qApp->processEvents();
+ GSM_ToDoEntry ToDoEntry;
QPtrList<Todo> tl = calendar->rawTodos();
Todo* to = tl.first();
- i = 0;
+
message = i18n("Processing todo # ");
procCount = 0;
while ( to ) {
- if ( true /*to->zaurusStat() != -2 */) {
+ if ( to->tempSyncStat() != SYNC_TEMPSTATE_NEW_EXTERNAL ) {
status.setText ( message + QString::number ( ++procCount ) );
qApp->processEvents();
- QString eString = getTodoString( to );
- if ( /*to->zaurusStat() == -3*/true ) { // delete
- // deleting empty strings does not work.
- // we write first and x and then delete the record with the x
- eString = eString.replace( QRegExp(",\"\""),",\"x\"" );
- changeString += eString + "\n";
- deleteString += eString + "\n";
- deleteEnt = true;
- changeEnt = true;
- }
- else if ( true /*to->zaurusId() == -1*/ ) { // add new
- command = "(echo \"" + tPrefix + eString + "\" ) | db2file todo -w -g -c " + codec+ " > "+ fileName;
- system ( command.utf8() );
- QFile file( fileName );
- if (!file.open( IO_ReadOnly ) ) {
- return false;
-
+ todo2GSM( to, &ToDoEntry );
+ if ( to->tempSyncStat() == SYNC_TEMPSTATE_DELETE ) { // delete
+ error=Phone->DeleteToDo(&s,&ToDoEntry);
}
- QTextStream ts( &file );
- ts.setCodec( QTextCodec::codecForName("utf8") );
- answer = ts.read();
- file.close();
- //qDebug("answer \n%s ", answer.latin1());
- getNumFromRecord( answer, to ) ;
-
+ else if ( to->getID("Sharp_DTM").isEmpty() ) { // add new
+ ;
}
else { // change existing
- //qDebug("canging %d %d",to->zaurusStat() ,to->zaurusId() );
- //command = "(echo \"" + ePrefix + eString + "\" ) | db2file datebook -w -g -c " + codec+ " > "+ fileName;
- changeString += eString + "\n";
- changeEnt = true;
-
+ error=Phone->AddToDo(&s,&ToDoEntry);
}
}
-
to = tl.next();
}
- status.setText ( i18n("Changing todos ...") );
- qApp->processEvents();
- //qDebug("changing... ");
- if ( changeEnt ) {
- QFile file( fileName );
- if (!file.open( IO_WriteOnly ) ) {
- return false;
-
- }
- QTextStream ts( &file );
- ts.setCodec( QTextCodec::codecForName("utf8") );
- ts << changeString ;
- file.close();
- command = "db2file todo -w -g -c " + codec+ " < "+ fileName;
- system ( command.latin1() );
- //qDebug("command %s file :\n%s ", command.latin1(), changeString.latin1());
- }
- status.setText ( i18n("Deleting todos ...") );
+ // pending get empty slots
+ to = tl.first();
+ while ( to ) {
+ if ( to->tempSyncStat() != SYNC_TEMPSTATE_NEW_EXTERNAL && to->tempSyncStat() != SYNC_TEMPSTATE_DELETE) {
+ if ( to->getID(mProfileName).isEmpty() ) {
+ status.setText ( message + QString::number ( ++procCount ) );
qApp->processEvents();
- //qDebug("deleting... ");
- if ( deleteEnt ) {
- QFile file( fileName );
- if (!file.open( IO_WriteOnly ) ) {
- return false;
-
+ int newID ;//= pending
+ to->setID(mProfileName, QString::number( newID ));
+ todo2GSM( to, &ToDoEntry );
+ error=Phone->AddToDo(&s,&ToDoEntry);
}
- QTextStream ts( &file );
- ts.setCodec( QTextCodec::codecForName("utf8") );
- ts << deleteString;
- file.close();
- command = "db2file todo -d -c " + codec+ " < "+ fileName;
- system ( command.latin1() );
- // qDebug("command %s file :\n%s ", command.latin1(), deleteString.latin1());
}
-#endif
+ to = tl.next();
+ }
return true;
}
QString PhoneFormat::dtToGSM( const QDateTime& dti, bool useTZ )
{
QString datestr;
QString timestr;
int offset = KGlobal::locale()->localTimeOffset( dti );
QDateTime dt;
if (useTZ)
dt = dti.addSecs ( -(offset*60));
else
dt = dti;
if(dt.date().isValid()){
const QDate& date = dt.date();
datestr.sprintf("%04d%02d%02d",
date.year(), date.month(), date.day());
diff --git a/libkcal/phoneformat.h b/libkcal/phoneformat.h
index 8d4e200..1472880 100644
--- a/libkcal/phoneformat.h
+++ b/libkcal/phoneformat.h
@@ -16,45 +16,48 @@
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
#ifndef PHONEFORMAT_H
#define PHONEFORMAT_H
#include <qstring.h>
#include "scheduler.h"
#include "calformat.h"
extern "C" {
#include "../gammu/emb/common/gammu.h"
}
-
namespace KCal {
/**
This class implements the calendar format used by Phone.
*/
-
+ class Event;
+ class Todo;
class PhoneFormat : public QObject {
public:
/** Create new iCalendar format. */
- PhoneFormat();
+ PhoneFormat(QString profileName, QString device,QString connection, QString model);
virtual ~PhoneFormat();
- bool load( Calendar * ,Calendar *, QString profileName, QString device,QString connection, QString model );
+ bool load( Calendar * ,Calendar * );
bool save( Calendar * );
bool fromString( Calendar *, const QString & );
QString toString( Calendar * );
static ulong getCsum( const QStringList & );
private:
+ void event2GSM( Event* ev, GSM_CalendarEntry*Note );
+ void todo2GSM( Todo* ev, GSM_ToDoEntry *ToDo );
+ int initDevice(GSM_StateMachine *s);
QString getEventString( Event* );
QString getTodoString( Todo* );
QString dtToGSM( const QDateTime& dt, bool useTZ = true );
- QString mProfileName;
+ QString mProfileName, mDevice, mConnection, mModel;
};
}
#endif