summaryrefslogtreecommitdiff
path: root/libopie2/opiepim/core
authoreilers <eilers>2003-08-01 12:30:16 (UTC)
committer eilers <eilers>2003-08-01 12:30:16 (UTC)
commit6c715b67a8f0e32a4edca5be91332622834c8d91 (patch) (unidiff)
treeae2d660e1fd9c990c2d725c075ce6c42480b0af8 /libopie2/opiepim/core
parentcb45aa10043fdd6fddcab42ef0e07ddafc3d506d (diff)
downloadopie-6c715b67a8f0e32a4edca5be91332622834c8d91.zip
opie-6c715b67a8f0e32a4edca5be91332622834c8d91.tar.gz
opie-6c715b67a8f0e32a4edca5be91332622834c8d91.tar.bz2
Merging changes from BRANCH_1_0 to HEAD
Diffstat (limited to 'libopie2/opiepim/core') (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opiepim/core/ocontactaccess.h11
-rw-r--r--libopie2/opiepim/core/oconversion.h5
-rw-r--r--libopie2/opiepim/core/opimaccesstemplate.h4
-rw-r--r--libopie2/opiepim/core/opimcache.h6
-rw-r--r--libopie2/opiepim/core/opimxrefmanager.h2
-rw-r--r--libopie2/opiepim/core/otemplatebase.h7
6 files changed, 35 insertions, 0 deletions
diff --git a/libopie2/opiepim/core/ocontactaccess.h b/libopie2/opiepim/core/ocontactaccess.h
index e90db32..9b0a719 100644
--- a/libopie2/opiepim/core/ocontactaccess.h
+++ b/libopie2/opiepim/core/ocontactaccess.h
@@ -1,43 +1,51 @@
1/* 1/*
2 * Class to manage the Contacts. 2 * Class to manage the Contacts.
3 * 3 *
4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) 4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de)
5 * Copyright (c) 2002 by Holger Freyther (zecke@handhelds.org) 5 * Copyright (c) 2002 by Holger Freyther (zecke@handhelds.org)
6 * 6 *
7 * ===================================================================== 7 * =====================================================================
8 *This program is free software; you can redistribute it and/or 8 *This program is free software; you can redistribute it and/or
9 *modify it under the terms of the GNU Library General Public 9 *modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; 10 * License as published by the Free Software Foundation;
11 * either version 2 of the License, or (at your option) any later 11 * either version 2 of the License, or (at your option) any later
12 * version. 12 * version.
13 * ===================================================================== 13 * =====================================================================
14 * ToDo: Define enum for query settings 14 * ToDo: Define enum for query settings
15 * ===================================================================== 15 * =====================================================================
16 * Version: $Id$ 16 * Version: $Id$
17 * ===================================================================== 17 * =====================================================================
18 * History: 18 * History:
19 * $Log$ 19 * $Log$
20 * Revision 1.9 2003/08/01 12:30:16 eilers
21 * Merging changes from BRANCH_1_0 to HEAD
22 *
23 * Revision 1.8.2.1 2003/06/30 14:34:19 eilers
24 * Patches from Zecke:
25 * Fixing and cleaning up extraMap handling
26 * Adding d_ptr for binary compatibility in the future
27 *
20 * Revision 1.8 2003/05/08 13:55:09 tille 28 * Revision 1.8 2003/05/08 13:55:09 tille
21 * search stuff 29 * search stuff
22 * and match, toRichText & toShortText in oevent 30 * and match, toRichText & toShortText in oevent
23 * 31 *
24 * Revision 1.7 2003/04/13 18:07:10 zecke 32 * Revision 1.7 2003/04/13 18:07:10 zecke
25 * More API doc 33 * More API doc
26 * QString -> const QString& 34 * QString -> const QString&
27 * QString = 0l -> QString::null 35 * QString = 0l -> QString::null
28 * 36 *
29 * Revision 1.6 2003/01/02 14:27:12 eilers 37 * Revision 1.6 2003/01/02 14:27:12 eilers
30 * Improved query by example: Search by date is possible.. First step 38 * Improved query by example: Search by date is possible.. First step
31 * for a today plugin for birthdays.. 39 * for a today plugin for birthdays..
32 * 40 *
33 * Revision 1.5 2002/11/13 14:14:51 eilers 41 * Revision 1.5 2002/11/13 14:14:51 eilers
34 * Added sorted for Contacts.. 42 * Added sorted for Contacts..
35 * 43 *
36 * Revision 1.4 2002/11/01 15:10:42 eilers 44 * Revision 1.4 2002/11/01 15:10:42 eilers
37 * Added regExp-search in database for all fields in a contact. 45 * Added regExp-search in database for all fields in a contact.
38 * 46 *
39 * Revision 1.3 2002/10/16 10:52:40 eilers 47 * Revision 1.3 2002/10/16 10:52:40 eilers
40 * Added some docu to the interface and now using the cache infrastucture by zecke.. :) 48 * Added some docu to the interface and now using the cache infrastucture by zecke.. :)
41 * 49 *
42 * Revision 1.2 2002/10/14 16:21:54 eilers 50 * Revision 1.2 2002/10/14 16:21:54 eilers
43 * Some minor interface updates 51 * Some minor interface updates
@@ -144,27 +152,30 @@ class OContactAccess: public QObject, public OPimAccessTemplate<OContact>
144 * Save is more a "commit". After calling this function, all changes are public available. 152 * Save is more a "commit". After calling this function, all changes are public available.
145 * @return true if successful 153 * @return true if successful
146 */ 154 */
147 bool save(); 155 bool save();
148 156
149 signals: 157 signals:
150 /* Signal is emitted if the database was changed. Therefore 158 /* Signal is emitted if the database was changed. Therefore
151 * we may need to reload to stay consistent. 159 * we may need to reload to stay consistent.
152 * @param which Pointer to the database who created this event. This pointer 160 * @param which Pointer to the database who created this event. This pointer
153 * is useful if an application has to handle multiple databases at the same time. 161 * is useful if an application has to handle multiple databases at the same time.
154 * @see reload() 162 * @see reload()
155 */ 163 */
156 void signalChanged ( const OContactAccess *which ); 164 void signalChanged ( const OContactAccess *which );
157 165
158 166
159 private: 167 private:
160 // class OContactAccessPrivate; 168 // class OContactAccessPrivate;
161 // OContactAccessPrivate* d; 169 // OContactAccessPrivate* d;
162 OContactAccessBackend *m_backEnd; 170 OContactAccessBackend *m_backEnd;
163 bool m_loading:1; 171 bool m_loading:1;
164 172
165 private slots: 173 private slots:
166 void copMessage( const QCString &msg, const QByteArray &data ); 174 void copMessage( const QCString &msg, const QByteArray &data );
167 175
176 private:
177 class Private;
178 Private *d;
168 179
169}; 180};
170#endif 181#endif
diff --git a/libopie2/opiepim/core/oconversion.h b/libopie2/opiepim/core/oconversion.h
index 13367e1..4c0a497 100644
--- a/libopie2/opiepim/core/oconversion.h
+++ b/libopie2/opiepim/core/oconversion.h
@@ -16,28 +16,33 @@
16** not clear to you. 16** not clear to you.
17**********************************************************************/ 17**********************************************************************/
18 18
19#ifndef __oconversion_h__ 19#ifndef __oconversion_h__
20#define __oconversion_h__ 20#define __oconversion_h__
21 21
22/* #include <time.h> */ 22/* #include <time.h> */
23/* #include <sys/types.h> */ 23/* #include <sys/types.h> */
24#include <qdatetime.h> 24#include <qdatetime.h>
25 25
26/* FIXME namespace? -zecke */ 26/* FIXME namespace? -zecke */
27class OConversion 27class OConversion
28{ 28{
29public: 29public:
30 static QString dateToString( const QDate &d ); 30 static QString dateToString( const QDate &d );
31 static QDate dateFromString( const QString &datestr ); 31 static QDate dateFromString( const QString &datestr );
32 32
33 /** 33 /**
34 * simple function to store DateTime as string and read from string 34 * simple function to store DateTime as string and read from string
35 * no timezone changing is done 35 * no timezone changing is done
36 * DDMMYYYYHHMMSS is the simple format 36 * DDMMYYYYHHMMSS is the simple format
37 */ 37 */
38 static QString dateTimeToString( const QDateTime& ); 38 static QString dateTimeToString( const QDateTime& );
39 static QDateTime dateTimeFromString( const QString& ); 39 static QDateTime dateTimeFromString( const QString& );
40
41private:
42 class Private;
43 Private* d;
44
40}; 45};
41 46
42#endif // __oconversion_h__ 47#endif // __oconversion_h__
43 48
diff --git a/libopie2/opiepim/core/opimaccesstemplate.h b/libopie2/opiepim/core/opimaccesstemplate.h
index 8ff205c..ecbeb68 100644
--- a/libopie2/opiepim/core/opimaccesstemplate.h
+++ b/libopie2/opiepim/core/opimaccesstemplate.h
@@ -1,36 +1,37 @@
1#ifndef OPIE_PIM_ACCESS_TEMPLATE_H 1#ifndef OPIE_PIM_ACCESS_TEMPLATE_H
2#define OPIE_PIM_ACCESS_TEMPLATE_H 2#define OPIE_PIM_ACCESS_TEMPLATE_H
3 3
4#include <qarray.h> 4#include <qarray.h>
5 5
6#include <opie/opimrecord.h> 6#include <opie/opimrecord.h>
7#include <opie/opimaccessbackend.h> 7#include <opie/opimaccessbackend.h>
8#include <opie/orecordlist.h> 8#include <opie/orecordlist.h>
9 9
10#include "opimcache.h" 10#include "opimcache.h"
11#include "otemplatebase.h" 11#include "otemplatebase.h"
12 12
13class OPimAccessTemplatePrivate;
13/** 14/**
14 * Thats the frontend to our OPIE PIM 15 * Thats the frontend to our OPIE PIM
15 * Library. Either you want to use it's 16 * Library. Either you want to use it's
16 * interface or you want to implement 17 * interface or you want to implement
17 * your own Access lib 18 * your own Access lib
18 * Just create a OPimRecord and inherit from 19 * Just create a OPimRecord and inherit from
19 * the plugins 20 * the plugins
20 */ 21 */
21 22
22template <class T = OPimRecord > 23template <class T = OPimRecord >
23class OPimAccessTemplate : public OTemplateBase<T> { 24class OPimAccessTemplate : public OTemplateBase<T> {
24public: 25public:
25 enum Access { 26 enum Access {
26 Random = 0, 27 Random = 0,
27 SortedAccess 28 SortedAccess
28 }; 29 };
29 typedef ORecordList<T> List; 30 typedef ORecordList<T> List;
30 typedef OPimAccessBackend<T> BackEnd; 31 typedef OPimAccessBackend<T> BackEnd;
31 typedef OPimCache<T> Cache; 32 typedef OPimCache<T> Cache;
32 33
33 /** 34 /**
34 * c'tor BackEnd 35 * c'tor BackEnd
35 * enum Access a small hint on how to handle the backend 36 * enum Access a small hint on how to handle the backend
36 */ 37 */
@@ -131,48 +132,51 @@ public:
131 virtual bool replace( const T& t) ; 132 virtual bool replace( const T& t) ;
132 133
133 void setReadAhead( uint count ); 134 void setReadAhead( uint count );
134 /** 135 /**
135 * @internal 136 * @internal
136 */ 137 */
137 void cache( const T& )const; 138 void cache( const T& )const;
138 void setSaneCacheSize( int ); 139 void setSaneCacheSize( int );
139 140
140 QArray<int> records()const; 141 QArray<int> records()const;
141protected: 142protected:
142 /** 143 /**
143 * invalidate the cache 144 * invalidate the cache
144 */ 145 */
145 void invalidateCache(); 146 void invalidateCache();
146 147
147 void setBackEnd( BackEnd* end ); 148 void setBackEnd( BackEnd* end );
148 /** 149 /**
149 * returns the backend 150 * returns the backend
150 */ 151 */
151 BackEnd* backEnd(); 152 BackEnd* backEnd();
152 BackEnd* m_backEnd; 153 BackEnd* m_backEnd;
153 Cache m_cache; 154 Cache m_cache;
154 155
156private:
157 OPimAccessTemplatePrivate *d;
158
155}; 159};
156 160
157template <class T> 161template <class T>
158OPimAccessTemplate<T>::OPimAccessTemplate( BackEnd* end ) 162OPimAccessTemplate<T>::OPimAccessTemplate( BackEnd* end )
159 : OTemplateBase<T>(), m_backEnd( end ) 163 : OTemplateBase<T>(), m_backEnd( end )
160{ 164{
161 if (end ) 165 if (end )
162 end->setFrontend( this ); 166 end->setFrontend( this );
163} 167}
164template <class T> 168template <class T>
165OPimAccessTemplate<T>::~OPimAccessTemplate() { 169OPimAccessTemplate<T>::~OPimAccessTemplate() {
166 qWarning("~OPimAccessTemplate<T>"); 170 qWarning("~OPimAccessTemplate<T>");
167 delete m_backEnd; 171 delete m_backEnd;
168} 172}
169template <class T> 173template <class T>
170bool OPimAccessTemplate<T>::load() { 174bool OPimAccessTemplate<T>::load() {
171 invalidateCache(); 175 invalidateCache();
172 return m_backEnd->load(); 176 return m_backEnd->load();
173} 177}
174template <class T> 178template <class T>
175bool OPimAccessTemplate<T>::reload() { 179bool OPimAccessTemplate<T>::reload() {
176 invalidateCache(); // zecke: I think this should be added (se) 180 invalidateCache(); // zecke: I think this should be added (se)
177 return m_backEnd->reload(); 181 return m_backEnd->reload();
178} 182}
diff --git a/libopie2/opiepim/core/opimcache.h b/libopie2/opiepim/core/opimcache.h
index 73414e5..7f7cff5 100644
--- a/libopie2/opiepim/core/opimcache.h
+++ b/libopie2/opiepim/core/opimcache.h
@@ -1,72 +1,78 @@
1#ifndef OPIE_PIM_CACHE_H 1#ifndef OPIE_PIM_CACHE_H
2#define OPIE_PIM_CACHE_H 2#define OPIE_PIM_CACHE_H
3 3
4#include <qintcache.h> 4#include <qintcache.h>
5 5
6#include "opimrecord.h" 6#include "opimrecord.h"
7 7
8class OPimCacheItemPrivate;
9
8template <class T = OPimRecord> 10template <class T = OPimRecord>
9class OPimCacheItem { 11class OPimCacheItem {
10public: 12public:
11 OPimCacheItem( const T& t = T() ); 13 OPimCacheItem( const T& t = T() );
12 OPimCacheItem( const OPimCacheItem& ); 14 OPimCacheItem( const OPimCacheItem& );
13 ~OPimCacheItem(); 15 ~OPimCacheItem();
14 16
15 OPimCacheItem &operator=( const OPimCacheItem& ); 17 OPimCacheItem &operator=( const OPimCacheItem& );
16 18
17 T record()const; 19 T record()const;
18 void setRecord( const T& ); 20 void setRecord( const T& );
19private: 21private:
20 T m_t; 22 T m_t;
23 OPimCacheItemPrivate *d;
21}; 24};
22 25
26
27class OPimCachePrivate;
23/** 28/**
24 * OPimCache for caching the items 29 * OPimCache for caching the items
25 * We support adding, removing 30 * We support adding, removing
26 * and finding 31 * and finding
27 */ 32 */
28template <class T = OPimRecord> 33template <class T = OPimRecord>
29class OPimCache { 34class OPimCache {
30public: 35public:
31 typedef OPimCacheItem<T> Item; 36 typedef OPimCacheItem<T> Item;
32 OPimCache(); 37 OPimCache();
33 OPimCache( const OPimCache& ); 38 OPimCache( const OPimCache& );
34 ~OPimCache(); 39 ~OPimCache();
35 40
36 OPimCache &operator=( const OPimCache& ); 41 OPimCache &operator=( const OPimCache& );
37 42
38 bool contains(int uid)const; 43 bool contains(int uid)const;
39 void invalidate(); 44 void invalidate();
40 void setSize( int size ); 45 void setSize( int size );
41 46
42 T find(int uid )const; 47 T find(int uid )const;
43 void add( const T& ); 48 void add( const T& );
44 void remove( int uid ); 49 void remove( int uid );
45 void replace( const T& ); 50 void replace( const T& );
46 51
47private: 52private:
48 QIntCache<Item> m_cache; 53 QIntCache<Item> m_cache;
54 OPimCachePrivate* d;
49}; 55};
50 56
51// Implementation 57// Implementation
52template <class T> 58template <class T>
53OPimCacheItem<T>::OPimCacheItem( const T& t ) 59OPimCacheItem<T>::OPimCacheItem( const T& t )
54 : m_t(t) { 60 : m_t(t) {
55} 61}
56template <class T> 62template <class T>
57OPimCacheItem<T>::~OPimCacheItem() { 63OPimCacheItem<T>::~OPimCacheItem() {
58 64
59} 65}
60template <class T> 66template <class T>
61T OPimCacheItem<T>::record()const { 67T OPimCacheItem<T>::record()const {
62 return m_t; 68 return m_t;
63} 69}
64template <class T> 70template <class T>
65void OPimCacheItem<T>::setRecord( const T& t ) { 71void OPimCacheItem<T>::setRecord( const T& t ) {
66 m_t = t; 72 m_t = t;
67} 73}
68// Cache 74// Cache
69template <class T> 75template <class T>
70OPimCache<T>::OPimCache() 76OPimCache<T>::OPimCache()
71 : m_cache(100, 53 ) 77 : m_cache(100, 53 )
72{ 78{
diff --git a/libopie2/opiepim/core/opimxrefmanager.h b/libopie2/opiepim/core/opimxrefmanager.h
index 39e5eef..c485e98 100644
--- a/libopie2/opiepim/core/opimxrefmanager.h
+++ b/libopie2/opiepim/core/opimxrefmanager.h
@@ -15,27 +15,29 @@ class OPimXRefManager {
15public: 15public:
16 OPimXRefManager(); 16 OPimXRefManager();
17 OPimXRefManager( const OPimXRefManager& ); 17 OPimXRefManager( const OPimXRefManager& );
18 ~OPimXRefManager(); 18 ~OPimXRefManager();
19 19
20 OPimXRefManager& operator=( const OPimXRefManager& ); 20 OPimXRefManager& operator=( const OPimXRefManager& );
21 bool operator==( const OPimXRefManager& ); 21 bool operator==( const OPimXRefManager& );
22 22
23 void add( const OPimXRef& ); 23 void add( const OPimXRef& );
24 void remove( const OPimXRef& ); 24 void remove( const OPimXRef& );
25 void replace( const OPimXRef& ); 25 void replace( const OPimXRef& );
26 26
27 void clear(); 27 void clear();
28 28
29 /** 29 /**
30 * apps participating 30 * apps participating
31 */ 31 */
32 QStringList apps()const; 32 QStringList apps()const;
33 OPimXRef::ValueList list()const; 33 OPimXRef::ValueList list()const;
34 OPimXRef::ValueList list( const QString& service )const; 34 OPimXRef::ValueList list( const QString& service )const;
35 OPimXRef::ValueList list( int uid )const; 35 OPimXRef::ValueList list( int uid )const;
36 36
37private: 37private:
38 OPimXRef::ValueList m_list; 38 OPimXRef::ValueList m_list;
39 class Private;
40 Private *d;
39}; 41};
40 42
41#endif 43#endif
diff --git a/libopie2/opiepim/core/otemplatebase.h b/libopie2/opiepim/core/otemplatebase.h
index 29fb6ec..cadac74 100644
--- a/libopie2/opiepim/core/otemplatebase.h
+++ b/libopie2/opiepim/core/otemplatebase.h
@@ -1,87 +1,94 @@
1#ifndef OPIE_TEMPLATE_BASE_H 1#ifndef OPIE_TEMPLATE_BASE_H
2#define OPIE_TEMPLATE_BASE_H 2#define OPIE_TEMPLATE_BASE_H
3 3
4#include <qarray.h> 4#include <qarray.h>
5 5
6#include <opie/opimrecord.h> 6#include <opie/opimrecord.h>
7 7
8 8
9/** 9/**
10 * Templates do not have a base class, This is why 10 * Templates do not have a base class, This is why
11 * we've this class 11 * we've this class
12 * this is here to give us the possibility 12 * this is here to give us the possibility
13 * to have a common base class 13 * to have a common base class
14 * You may not want to use that interface internaly 14 * You may not want to use that interface internaly
15 * POOR mans interface 15 * POOR mans interface
16 */ 16 */
17class OPimBasePrivate;
17struct OPimBase { 18struct OPimBase {
18 /** 19 /**
19 * return the rtti 20 * return the rtti
20 */ 21 */
21 virtual int rtti()= 0; 22 virtual int rtti()= 0;
22 virtual OPimRecord* record()const = 0; 23 virtual OPimRecord* record()const = 0;
23 virtual OPimRecord* record(int uid)const = 0; 24 virtual OPimRecord* record(int uid)const = 0;
24 virtual bool add( const OPimRecord& ) = 0; 25 virtual bool add( const OPimRecord& ) = 0;
25 virtual bool remove( int uid ) = 0; 26 virtual bool remove( int uid ) = 0;
26 virtual bool remove( const OPimRecord& ) = 0; 27 virtual bool remove( const OPimRecord& ) = 0;
27 virtual void clear() = 0; 28 virtual void clear() = 0;
28 virtual bool load() = 0; 29 virtual bool load() = 0;
29 virtual bool save() = 0; 30 virtual bool save() = 0;
30 virtual QArray<int> records()const = 0; 31 virtual QArray<int> records()const = 0;
31 /* 32 /*
32 * ADD editing here? 33 * ADD editing here?
33 * -zecke 34 * -zecke
34 */ 35 */
36private:
37 OPimBasePrivate* d;
35 38
36}; 39};
37/** 40/**
38 * internal template base 41 * internal template base
39 * T needs to implement the copy c'tor!!! 42 * T needs to implement the copy c'tor!!!
40 */ 43 */
44class OTemplateBasePrivate;
41template <class T = OPimRecord> 45template <class T = OPimRecord>
42class OTemplateBase : public OPimBase { 46class OTemplateBase : public OPimBase {
43public: 47public:
44 enum CacheDirection { Forward=0, Reverse }; 48 enum CacheDirection { Forward=0, Reverse };
45 OTemplateBase() { 49 OTemplateBase() {
46 }; 50 };
47 virtual ~OTemplateBase() { 51 virtual ~OTemplateBase() {
48 } 52 }
49 virtual T find( int uid )const = 0; 53 virtual T find( int uid )const = 0;
50 54
51 /** 55 /**
52 * read ahead find 56 * read ahead find
53 */ 57 */
54 virtual T find( int uid, const QArray<int>& items, 58 virtual T find( int uid, const QArray<int>& items,
55 uint current, CacheDirection dir = Forward )const = 0; 59 uint current, CacheDirection dir = Forward )const = 0;
56 virtual void cache( const T& )const = 0; 60 virtual void cache( const T& )const = 0;
57 virtual void setSaneCacheSize( int ) = 0; 61 virtual void setSaneCacheSize( int ) = 0;
58 62
59 /* reimplement of OPimBase */ 63 /* reimplement of OPimBase */
60 int rtti(); 64 int rtti();
61 OPimRecord* record()const; 65 OPimRecord* record()const;
62 OPimRecord* record(int uid )const; 66 OPimRecord* record(int uid )const;
63 static T* rec(); 67 static T* rec();
68
69private:
70 OTemplateBasePrivate *d;
64}; 71};
65 72
66/* 73/*
67 * implementation 74 * implementation
68 */ 75 */
69template <class T> 76template <class T>
70int 77int
71OTemplateBase<T>::rtti() { 78OTemplateBase<T>::rtti() {
72 return T::rtti(); 79 return T::rtti();
73} 80}
74template <class T> 81template <class T>
75OPimRecord* OTemplateBase<T>::record()const { 82OPimRecord* OTemplateBase<T>::record()const {
76 T* t = new T; 83 T* t = new T;
77 return t; 84 return t;
78} 85}
79template <class T> 86template <class T>
80OPimRecord* OTemplateBase<T>::record(int uid )const { 87OPimRecord* OTemplateBase<T>::record(int uid )const {
81 T t2 = find(uid ); 88 T t2 = find(uid );
82 T* t1 = new T(t2); 89 T* t1 = new T(t2);
83 90
84 return t1; 91 return t1;
85}; 92};
86template <class T> 93template <class T>
87T* OTemplateBase<T>::rec() { 94T* OTemplateBase<T>::rec() {