someone is using an editor that has tabs. stop it.

ecrustified.


SVN revision: 55702
This commit is contained in:
Mike Blumenkrantz 2010-12-22 22:36:13 +00:00
parent 75f95cebe2
commit 76b1e1805f
1 changed files with 251 additions and 231 deletions

View File

@ -14,7 +14,7 @@
# ifdef __cplusplus # ifdef __cplusplus
extern "C" extern "C"
# endif # endif
void *alloca (size_t); void *alloca(size_t);
#endif #endif
#include <stdio.h> #include <stdio.h>
@ -42,13 +42,20 @@ struct _E_Thumb
}; };
/* local subsystem functions */ /* local subsystem functions */
static int _e_ipc_init(void); static int _e_ipc_init(void);
static Eina_Bool _e_ipc_cb_server_add(void *data, int type, void *event); static Eina_Bool _e_ipc_cb_server_add(void *data,
static Eina_Bool _e_ipc_cb_server_del(void *data, int type, void *event); int type,
static Eina_Bool _e_ipc_cb_server_data(void *data, int type, void *event); void *event);
static Eina_Bool _e_ipc_cb_server_del(void *data,
int type,
void *event);
static Eina_Bool _e_ipc_cb_server_data(void *data,
int type,
void *event);
static Eina_Bool _e_cb_timer(void *data); static Eina_Bool _e_cb_timer(void *data);
static void _e_thumb_generate(E_Thumb *eth); static void _e_thumb_generate(E_Thumb *eth);
static char *_e_thumb_file_id(char *file, char *key); static char *_e_thumb_file_id(char *file,
char *key);
/* local subsystem globals */ /* local subsystem globals */
static Ecore_Ipc_Server *_e_ipc_server = NULL; static Ecore_Ipc_Server *_e_ipc_server = NULL;
@ -58,32 +65,33 @@ static char _thumbdir[4096] = "";
/* externally accessible functions */ /* externally accessible functions */
int int
main(int argc, char **argv) main(int argc,
char **argv)
{ {
int i; int i;
for (i = 1; i < argc; i++) for (i = 1; i < argc; i++)
{ {
if ((!strcmp(argv[i], "-h")) || if ((!strcmp(argv[i], "-h")) ||
(!strcmp(argv[i], "-help")) || (!strcmp(argv[i], "-help")) ||
(!strcmp(argv[i], "--help"))) (!strcmp(argv[i], "--help")))
{ {
printf( printf(
"This is an internal tool for Enlightenment.\n" "This is an internal tool for Enlightenment.\n"
"do not use it.\n" "do not use it.\n"
); );
exit(0); exit(0);
} }
else if (!strncmp(argv[i], "--nice=", 7)) else if (!strncmp(argv[i], "--nice=", 7))
{ {
const char *val; const char *val;
val = argv[i] + 7; val = argv[i] + 7;
if (*val) if (*val)
nice(atoi(val)); nice(atoi(val));
} }
} }
ecore_init(); ecore_init();
ecore_app_args_set(argc, (const char **)argv); ecore_app_args_set(argc, (const char **)argv);
eet_init(); eet_init();
@ -97,11 +105,11 @@ main(int argc, char **argv)
ecore_file_mkpath(_thumbdir); ecore_file_mkpath(_thumbdir);
if (_e_ipc_init()) ecore_main_loop_begin(); if (_e_ipc_init()) ecore_main_loop_begin();
if (_e_ipc_server) if (_e_ipc_server)
{ {
ecore_ipc_server_del(_e_ipc_server); ecore_ipc_server_del(_e_ipc_server);
_e_ipc_server = NULL; _e_ipc_server = NULL;
} }
ecore_ipc_shutdown(); ecore_ipc_shutdown();
@ -111,7 +119,7 @@ main(int argc, char **argv)
evas_shutdown(); evas_shutdown();
eet_shutdown(); eet_shutdown();
ecore_shutdown(); ecore_shutdown();
return 0; return 0;
} }
@ -124,100 +132,109 @@ _e_ipc_init(void)
sdir = getenv("E_IPC_SOCKET"); sdir = getenv("E_IPC_SOCKET");
if (!sdir) if (!sdir)
{ {
printf("The E_IPC_SOCKET environment variable is not set. This is\n" printf("The E_IPC_SOCKET environment variable is not set. This is\n"
"exported by Enlightenment to all processes it launches.\n" "exported by Enlightenment to all processes it launches.\n"
"This environment variable must be set and must point to\n" "This environment variable must be set and must point to\n"
"Enlightenment's IPC socket file (minus port number).\n"); "Enlightenment's IPC socket file (minus port number).\n");
return 0; return 0;
} }
_e_ipc_server = ecore_ipc_server_connect(ECORE_IPC_LOCAL_SYSTEM, sdir, 0, NULL); _e_ipc_server = ecore_ipc_server_connect(ECORE_IPC_LOCAL_SYSTEM, sdir, 0, NULL);
if (!_e_ipc_server) return 0; if (!_e_ipc_server) return 0;
ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_ADD, _e_ipc_cb_server_add, NULL); ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_ADD, _e_ipc_cb_server_add, NULL);
ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_DEL, _e_ipc_cb_server_del, NULL); ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_DEL, _e_ipc_cb_server_del, NULL);
ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_DATA, _e_ipc_cb_server_data, NULL); ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_DATA, _e_ipc_cb_server_data, NULL);
return 1; return 1;
} }
static Eina_Bool static Eina_Bool
_e_ipc_cb_server_add(void *data __UNUSED__, int type __UNUSED__, void *event) _e_ipc_cb_server_add(void *data __UNUSED__,
int type __UNUSED__,
void *event)
{ {
Ecore_Ipc_Event_Server_Add *e; Ecore_Ipc_Event_Server_Add *e;
e = event; e = event;
ecore_ipc_server_send(e->server, ecore_ipc_server_send(e->server,
5/*E_IPC_DOMAIN_THUMB*/, 5 /*E_IPC_DOMAIN_THUMB*/,
1/*hello*/, 1 /*hello*/,
0, 0, 0, NULL, 0); /* send hello */ 0, 0, 0, NULL, 0); /* send hello */
return ECORE_CALLBACK_PASS_ON; return ECORE_CALLBACK_PASS_ON;
} }
static Eina_Bool static Eina_Bool
_e_ipc_cb_server_del(void *data __UNUSED__, int type __UNUSED__, void *event __UNUSED__) _e_ipc_cb_server_del(void *data __UNUSED__,
int type __UNUSED__,
void *event __UNUSED__)
{ {
/* quit now */ /* quit now */
ecore_main_loop_quit(); ecore_main_loop_quit();
return ECORE_CALLBACK_PASS_ON; return ECORE_CALLBACK_PASS_ON;
} }
static Eina_Bool static Eina_Bool
_e_ipc_cb_server_data(void *data __UNUSED__, int type __UNUSED__, void *event) _e_ipc_cb_server_data(void *data __UNUSED__,
int type __UNUSED__,
void *event)
{ {
Ecore_Ipc_Event_Server_Data *e; Ecore_Ipc_Event_Server_Data *e;
E_Thumb *eth; E_Thumb *eth;
Eina_List *l; Eina_List *l;
char *file = NULL; char *file = NULL;
char *key = NULL; char *key = NULL;
e = event; e = event;
if (e->major != 5/*E_IPC_DOMAIN_THUMB*/) return ECORE_CALLBACK_PASS_ON; if (e->major != 5 /*E_IPC_DOMAIN_THUMB*/) return ECORE_CALLBACK_PASS_ON;
switch (e->minor) switch (e->minor)
{ {
case 1: case 1:
if (e->data) if (e->data)
{ {
/* begin thumb */ /* begin thumb */
/* don't check stuff. since this connects TO e17 it is connecting */ /* don't check stuff. since this connects TO e17 it is connecting */
/* TO a trusted process that WILL send this message properly */ /* TO a trusted process that WILL send this message properly */
/* formatted. if the thumbnailer dies anyway - it's not a big loss */ /* formatted. if the thumbnailer dies anyway - it's not a big loss */
/* but it is a sign of a bug in e formattign messages maybe */ /* but it is a sign of a bug in e formattign messages maybe */
file = e->data; file = e->data;
key = file + strlen(file) + 1; key = file + strlen(file) + 1;
if (!key[0]) key = NULL; if (!key[0]) key = NULL;
eth = calloc(1, sizeof(E_Thumb)); eth = calloc(1, sizeof(E_Thumb));
if (eth) if (eth)
{ {
eth->objid = e->ref; eth->objid = e->ref;
eth->w = e->ref_to; eth->w = e->ref_to;
eth->h = e->response; eth->h = e->response;
eth->file = strdup(file); eth->file = strdup(file);
if (key) eth->key = strdup(key); if (key) eth->key = strdup(key);
_thumblist = eina_list_append(_thumblist, eth); _thumblist = eina_list_append(_thumblist, eth);
if (!_timer) _timer = ecore_timer_add(0.001, _e_cb_timer, NULL); if (!_timer) _timer = ecore_timer_add(0.001, _e_cb_timer, NULL);
} }
} }
break; break;
case 2: case 2:
/* end thumb */ /* end thumb */
EINA_LIST_FOREACH(_thumblist, l, eth) EINA_LIST_FOREACH(_thumblist, l, eth)
{ {
if (eth->objid == e->ref) if (eth->objid == e->ref)
{ {
_thumblist = eina_list_remove_list(_thumblist, l); _thumblist = eina_list_remove_list(_thumblist, l);
if (eth->file) free(eth->file); if (eth->file) free(eth->file);
if (eth->key) free(eth->key); if (eth->key) free(eth->key);
free(eth); free(eth);
break; break;
} }
} }
break; break;
case 3: case 3:
/* quit now */ /* quit now */
ecore_main_loop_quit(); ecore_main_loop_quit();
break; break;
default: default:
break; break;
} }
return ECORE_CALLBACK_PASS_ON; return ECORE_CALLBACK_PASS_ON;
} }
@ -227,21 +244,21 @@ _e_cb_timer(void *data __UNUSED__)
{ {
E_Thumb *eth; E_Thumb *eth;
/* /*
Eina_List *del_list = NULL, *l; Eina_List *del_list = NULL, *l;
*/ */
/* take thumb at head of list */ /* take thumb at head of list */
if (_thumblist) if (_thumblist)
{ {
eth = eina_list_data_get(_thumblist); eth = eina_list_data_get(_thumblist);
_thumblist = eina_list_remove_list(_thumblist, _thumblist); _thumblist = eina_list_remove_list(_thumblist, _thumblist);
_e_thumb_generate(eth); _e_thumb_generate(eth);
if (eth->file) free(eth->file); if (eth->file) free(eth->file);
if (eth->key) free(eth->key); if (eth->key) free(eth->key);
free(eth); free(eth);
if (_thumblist) _timer = ecore_timer_add(0.01, _e_cb_timer, NULL); if (_thumblist) _timer = ecore_timer_add(0.01, _e_cb_timer, NULL);
else _timer = NULL; else _timer = NULL;
} }
else else
_timer = NULL; _timer = NULL;
@ -252,9 +269,9 @@ typedef struct _Color Color;
struct _Color struct _Color
{ {
Color *closest; Color *closest;
int closest_dist; int closest_dist;
int use; int use;
unsigned char r, g, b; unsigned char r, g, b;
}; };
@ -269,106 +286,106 @@ _e_thumb_generate(E_Thumb *eth)
int iw, ih, alpha, ww, hh; int iw, ih, alpha, ww, hh;
const unsigned int *data = NULL; const unsigned int *data = NULL;
time_t mtime_orig, mtime_thumb; time_t mtime_orig, mtime_thumb;
id = _e_thumb_file_id(eth->file, eth->key); id = _e_thumb_file_id(eth->file, eth->key);
if (!id) return; if (!id) return;
td = strdup(id); td = strdup(id);
if (!td) if (!td)
{ {
free(id); free(id);
return; return;
} }
td[2] = 0; td[2] = 0;
snprintf(dbuf, sizeof(dbuf), "%s/%s", _thumbdir, td); snprintf(dbuf, sizeof(dbuf), "%s/%s", _thumbdir, td);
snprintf(buf, sizeof(buf), "%s/%s/%s-%ix%i.thm", snprintf(buf, sizeof(buf), "%s/%s/%s-%ix%i.thm",
_thumbdir, td, id + 2, eth->w, eth->h); _thumbdir, td, id + 2, eth->w, eth->h);
free(id); free(id);
free(td); free(td);
mtime_orig = ecore_file_mod_time(eth->file); mtime_orig = ecore_file_mod_time(eth->file);
mtime_thumb = ecore_file_mod_time(buf); mtime_thumb = ecore_file_mod_time(buf);
if (mtime_thumb <= mtime_orig) if (mtime_thumb <= mtime_orig)
{ {
ecore_file_mkdir(dbuf); ecore_file_mkdir(dbuf);
edje_file_cache_set(0);
edje_collection_cache_set(0);
ee = ecore_evas_buffer_new(1, 1);
evas = ecore_evas_get(ee);
evas_image_cache_set(evas, 0);
evas_font_cache_set(evas, 0);
ww = 0;
hh = 0;
alpha = 1;
ext = strrchr(eth->file, '.');
if ((ext) && (eth->key) && edje_file_cache_set(0);
((!strcasecmp(ext, ".edj")) || edje_collection_cache_set(0);
(!strcasecmp(ext, ".eap")))) ee = ecore_evas_buffer_new(1, 1);
{ evas = ecore_evas_get(ee);
ww = eth->w; evas_image_cache_set(evas, 0);
hh = eth->h; evas_font_cache_set(evas, 0);
im = ecore_evas_object_image_new(ee); ww = 0;
ee_im = evas_object_data_get(im, "Ecore_Evas"); hh = 0;
evas_im = ecore_evas_get(ee_im); alpha = 1;
evas_image_cache_set(evas_im, 0); ext = strrchr(eth->file, '.');
evas_font_cache_set(evas_im, 0);
evas_object_image_size_set(im, ww * 4, hh * 4); if ((ext) && (eth->key) &&
evas_object_image_fill_set(im, 0, 0, ww, hh); ((!strcasecmp(ext, ".edj")) ||
edje = edje_object_add(evas_im); (!strcasecmp(ext, ".eap"))))
if ((eth->key) && {
( (!strcmp(eth->key, "e/desktop/background")) || ww = eth->w;
(!strcmp(eth->key, "e/init/splash")) )) hh = eth->h;
alpha = 0; im = ecore_evas_object_image_new(ee);
if (edje_object_file_set(edje, eth->file, eth->key)) ee_im = evas_object_data_get(im, "Ecore_Evas");
{ evas_im = ecore_evas_get(ee_im);
evas_object_move(edje, 0, 0); evas_image_cache_set(evas_im, 0);
evas_object_resize(edje, ww * 4, hh * 4); evas_font_cache_set(evas_im, 0);
evas_object_show(edje); evas_object_image_size_set(im, ww * 4, hh * 4);
} evas_object_image_fill_set(im, 0, 0, ww, hh);
} edje = edje_object_add(evas_im);
else if ((eth->key) &&
{ ((!strcmp(eth->key, "e/desktop/background")) ||
im = evas_object_image_add(evas); (!strcmp(eth->key, "e/init/splash"))))
evas_object_image_load_size_set(im, eth->w, eth->h); alpha = 0;
evas_object_image_file_set(im, eth->file, NULL); if (edje_object_file_set(edje, eth->file, eth->key))
iw = 0; ih = 0; {
evas_object_image_size_get(im, &iw, &ih); evas_object_move(edje, 0, 0);
alpha = evas_object_image_alpha_get(im); evas_object_resize(edje, ww * 4, hh * 4);
if ((iw > 0) && (ih > 0)) evas_object_show(edje);
{ }
ww = eth->w; }
hh = (eth->w * ih) / iw; else
if (hh > eth->h) {
{ im = evas_object_image_add(evas);
hh = eth->h; evas_object_image_load_size_set(im, eth->w, eth->h);
ww = (eth->h * iw) / ih; evas_object_image_file_set(im, eth->file, NULL);
} iw = 0; ih = 0;
evas_object_image_fill_set(im, 0, 0, ww, hh); evas_object_image_size_get(im, &iw, &ih);
} alpha = evas_object_image_alpha_get(im);
} if ((iw > 0) && (ih > 0))
evas_object_move(im, 0, 0); {
evas_object_resize(im, ww, hh); ww = eth->w;
ecore_evas_resize(ee, ww, hh); hh = (eth->w * ih) / iw;
evas_object_show(im); if (hh > eth->h)
if (ww > 0) {
{ hh = eth->h;
data = ecore_evas_buffer_pixels_get(ee); ww = (eth->h * iw) / ih;
if (data) }
{ evas_object_image_fill_set(im, 0, 0, ww, hh);
ef = eet_open(buf, EET_FILE_MODE_WRITE); }
if (ef) }
{ evas_object_move(im, 0, 0);
eet_write(ef, "/thumbnail/orig_file", evas_object_resize(im, ww, hh);
eth->file, strlen(eth->file), 1); ecore_evas_resize(ee, ww, hh);
if (eth->key) evas_object_show(im);
eet_write(ef, "/thumbnail/orig_key", if (ww > 0)
eth->key, strlen(eth->key), 1); {
eet_data_image_write(ef, "/thumbnail/data", data = ecore_evas_buffer_pixels_get(ee);
(void *)data, ww, hh, alpha, if (data)
0, 91, 1); {
ef = eet_open(buf, EET_FILE_MODE_WRITE);
if (ef)
{
eet_write(ef, "/thumbnail/orig_file",
eth->file, strlen(eth->file), 1);
if (eth->key)
eet_write(ef, "/thumbnail/orig_key",
eth->key, strlen(eth->key), 1);
eet_data_image_write(ef, "/thumbnail/data",
(void *)data, ww, hh, alpha,
0, 91, 1);
ww = 4; hh = 4; ww = 4; hh = 4;
evas_object_image_fill_set(im, 0, 0, ww, hh); evas_object_image_fill_set(im, 0, 0, ww, hh);
evas_object_resize(im, ww, hh); evas_object_resize(im, ww, hh);
@ -377,7 +394,7 @@ _e_thumb_generate(E_Thumb *eth)
if (data) if (data)
{ {
unsigned int *data1; unsigned int *data1;
data1 = malloc(ww * hh * sizeof(unsigned int)); data1 = malloc(ww * hh * sizeof(unsigned int));
memcpy(data1, data, ww * hh * sizeof(unsigned int)); memcpy(data1, data, ww * hh * sizeof(unsigned int));
ww = 2; hh = 2; ww = 2; hh = 2;
@ -388,7 +405,7 @@ _e_thumb_generate(E_Thumb *eth)
if (data) if (data)
{ {
unsigned int *data2; unsigned int *data2;
data2 = malloc(ww * hh * sizeof(unsigned int)); data2 = malloc(ww * hh * sizeof(unsigned int));
memcpy(data2, data, ww * hh * sizeof(unsigned int)); memcpy(data2, data, ww * hh * sizeof(unsigned int));
ww = 1; hh = 1; ww = 1; hh = 1;
@ -404,38 +421,38 @@ _e_thumb_generate(E_Thumb *eth)
int hi, si, vi; int hi, si, vi;
float h, s, v; float h, s, v;
const int pat2[4] = const int pat2[4] =
{ {
0, 3, 1, 2 0, 3, 1, 2
}; };
const int pat1[16] = const int pat1[16] =
{ {
5, 10, 6, 9, 5, 10, 6, 9,
0, 15, 3, 12, 0, 15, 3, 12,
1, 14, 7, 8, 1, 14, 7, 8,
4, 11, 2, 13 4, 11, 2, 13
}; };
data3 = malloc(ww * hh * sizeof(unsigned int)); data3 = malloc(ww * hh * sizeof(unsigned int));
memcpy(data3, data, ww * hh * sizeof(unsigned int)); memcpy(data3, data, ww * hh * sizeof(unsigned int));
// sort_id // sort_id
n = 0; n = 0;
#define A(v) (((v) >> 24) & 0xff) #define A(v) (((v) >> 24) & 0xff)
#define R(v) (((v) >> 16) & 0xff) #define R(v) (((v) >> 16) & 0xff)
#define G(v) (((v) >> 8 ) & 0xff) #define G(v) (((v) >> 8) & 0xff)
#define B(v) (((v) ) & 0xff) #define B(v) (((v)) & 0xff)
#define HSV(p) \ #define HSV(p) \
evas_color_rgb_to_hsv(R(p), G(p), B(p), &h, &s, &v); \ evas_color_rgb_to_hsv(R(p), G(p), B(p), &h, &s, &v); \
hi = 20 * (h / 360.0); \ hi = 20 * (h / 360.0); \
si = 20 * s; \ si = 20 * s; \
vi = 20 * v; \ vi = 20 * v; \
if (si < 2) hi = 25; if (si < 2) hi = 25;
#define SAVEHSV(h, s, v) \ #define SAVEHSV(h, s, v) \
id[n++] = 'a' + h; \ id[n++] = 'a' + h; \
id[n++] = 'a' + v; \ id[n++] = 'a' + v; \
id[n++] = 'a' + s; id[n++] = 'a' + s;
#define SAVEX(x) \ #define SAVEX(x) \
id[n++] = 'a' + x; id[n++] = 'a' + x;
#if 0 #if 0
HSV(data3[0]); HSV(data3[0]);
SAVEHSV(hi, si, vi); SAVEHSV(hi, si, vi);
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
@ -448,7 +465,7 @@ _e_thumb_generate(E_Thumb *eth)
HSV(data1[pat1[i]]); HSV(data1[pat1[i]]);
SAVEHSV(hi, si, vi); SAVEHSV(hi, si, vi);
} }
#else #else
HSV(data3[0]); HSV(data3[0]);
SAVEX(hi); SAVEX(hi);
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
@ -485,7 +502,7 @@ _e_thumb_generate(E_Thumb *eth)
HSV(data1[pat1[i]]); HSV(data1[pat1[i]]);
SAVEX(si); SAVEX(si);
} }
#endif #endif
id[n++] = 0; id[n++] = 0;
eet_write(ef, "/thumbnail/sort_id", id, n, 1); eet_write(ef, "/thumbnail/sort_id", id, n, 1);
free(data3); free(data3);
@ -494,24 +511,26 @@ _e_thumb_generate(E_Thumb *eth)
} }
free(data1); free(data1);
} }
eet_close(ef); eet_close(ef);
} }
} }
} }
/* will free all */ /* will free all */
if (edje) evas_object_del(edje); if (edje) evas_object_del(edje);
if (ee_im) ecore_evas_free(ee_im); if (ee_im) ecore_evas_free(ee_im);
else if (im) evas_object_del(im); else if (im)
ecore_evas_free(ee); evas_object_del(im);
eet_clearcache(); ecore_evas_free(ee);
eet_clearcache();
} }
/* send back path to thumb */ /* send back path to thumb */
ecore_ipc_server_send(_e_ipc_server, 5, 2, eth->objid, 0, 0, buf, strlen(buf) + 1); ecore_ipc_server_send(_e_ipc_server, 5, 2, eth->objid, 0, 0, buf, strlen(buf) + 1);
} }
static char * static char *
_e_thumb_file_id(char *file, char *key) _e_thumb_file_id(char *file,
char *key)
{ {
char s[64]; char s[64];
const char *chmap = "0123456789abcdef"; const char *chmap = "0123456789abcdef";
@ -524,8 +543,8 @@ _e_thumb_file_id(char *file, char *key)
len++; len++;
if (key) if (key)
{ {
key += strlen(key); key += strlen(key);
len++; len++;
} }
buf = alloca(len); buf = alloca(len);
@ -533,12 +552,13 @@ _e_thumb_file_id(char *file, char *key)
if (key) strcpy((char *)(buf + lenf + 1), key); if (key) strcpy((char *)(buf + lenf + 1), key);
e_sha1_sum(buf, len, id); e_sha1_sum(buf, len, id);
for (i = 0; i < 20; i++) for (i = 0; i < 20; i++)
{ {
s[(i * 2) + 0] = chmap[(id[i] >> 4) & 0xf]; s[(i * 2) + 0] = chmap[(id[i] >> 4) & 0xf];
s[(i * 2) + 1] = chmap[(id[i] ) & 0xf]; s[(i * 2) + 1] = chmap[(id[i]) & 0xf];
} }
s[(i * 2)] = 0; s[(i * 2)] = 0;
return strdup(s); return strdup(s);
} }