static gboolean reedah_feed_subscription_prepare_update_request (subscriptionPtr subscription, struct updateRequest *request) { debug0 (DEBUG_UPDATE, "preparing Reedah feed subscription for update\n"); ReedahSourcePtr source = (ReedahSourcePtr) node_source_root_from_node (subscription->node)->data; g_assert(source); if (source->root->source->loginState == NODE_SOURCE_STATE_NONE) { subscription_update (node_source_root_from_node (subscription->node)->subscription, 0) ; return FALSE; } if (!metadata_list_get (subscription->metadata, "reedah-feed-id")) { g_warning ("Skipping Reedah feed '%s' (%s) without id!", subscription->source, subscription->node->id); return FALSE; } debug0 (DEBUG_UPDATE, "Setting cookies for a Reedah subscription"); gchar* source_escaped = g_uri_escape_string(metadata_list_get (subscription->metadata, "reedah-feed-id"), NULL, TRUE); // FIXME: move to .h // FIXME: do not use 30 gchar* newUrl = g_strdup_printf ("http://www.reedah.com/reader/api/0/stream/contents/%s?client=liferea&n=30", source_escaped); update_request_set_source (request, newUrl); g_free (newUrl); g_free (source_escaped); update_request_set_auth_value (request, source->root->source->authToken); return TRUE; }
static gboolean ttrss_feed_subscription_prepare_update_request (subscriptionPtr subscription, struct updateRequest *request) { debug0 (DEBUG_UPDATE, "ttrss_feed_subscription_prepare_update_request()"); nodePtr root = node_source_root_from_node (subscription->node); ttrssSourcePtr source = (ttrssSourcePtr) root->data; const gchar *feed_id; gchar *source_name; debug0 (DEBUG_UPDATE, "preparing tt-rss feed subscription for update"); g_assert(source); if (source->loginState == TTRSS_SOURCE_STATE_NONE) { subscription_update (root->subscription, 0); return FALSE; } feed_id = metadata_list_get (subscription->metadata, "ttrss-feed-id"); if (!feed_id) { g_warning ("tt-rss feed without id! (%s)", subscription->node->title); return FALSE; } request->postdata = g_strdup_printf (TTRSS_JSON_HEADLINES, source->session_id, feed_id, 15 /* items to fetch */ ); source_name = g_strdup_printf (TTRSS_URL, metadata_list_get (root->subscription->metadata, "ttrss-url")); update_request_set_source (request, source_name); g_free (source_name); return TRUE; }
static gboolean ttrss_subscription_prepare_update_request (subscriptionPtr subscription, struct updateRequest *request) { ttrssSourcePtr source = (ttrssSourcePtr) subscription->node->data; gchar *source_uri; debug0 (DEBUG_UPDATE, "ttrss_subscription_prepare_update_request"); g_assert (source); if (source->loginState == TTRSS_SOURCE_STATE_NONE) { debug0 (DEBUG_UPDATE, "TinyTinyRSS login"); ttrss_source_login (source, 0); return FALSE; } debug1 (DEBUG_UPDATE, "TinyTinyRSS updating subscription (node id %s)", subscription->node->id); /* Updating the TinyTinyRSS subscription means updating the list of categories and the list of feeds in 2 requests and if the installation is not self-updating to run a remote update for each feed before fetching it's items */ source_uri = g_strdup_printf (TTRSS_URL, source->url); update_request_set_source (request, source_uri); g_free (source_uri); request->postdata = g_strdup_printf (TTRSS_JSON_CATEGORIES_LIST, source->session_id); return TRUE; }
static void PDF_LinkCheck() { debug0(DPF, D, "PDF_LinkCheck()"); /* still to do */ debug0(DPF, D, "PDF_LinkCheck returning."); } /* end PDF_LinkCheck */
void PDF_PrintGraphicInclude(OBJECT x, FULL_LENGTH colmark, FULL_LENGTH rowmark) { OBJECT y; debug0(DPF, D, "PDF_PrintGraphicInclude(x)"); Child(y, Down(x)); Error(50, 4, "cannot include EPS file in PDF output; EPS file %s ignored", WARN, &fpos(x), string(y)); debug0(DPF, D, "PDF_PrintGraphicInclude returning."); } /* end PDF_PrintGraphicInclude */
OBJECT StartMoment(void) { OBJECT res; debug0(DTK, D, "StartMoment()"); assert(current_moment != nilobj, "StartMoment: current_moment == nilobj!"); res = CopyObject(current_moment, no_fpos); debug0(DTK, D, "StartMoment returning"); ifdebug(DTK, D, DebugObject(res)); return res; }
void PDF_RestoreGraphicState(void) { debug0(DPF, D, "PDF_RestoreGraphicState()"); PDFPage_Pop(out_fp); currentfont = gs_stack[gs_stack_top].gs_font; currentcolour = gs_stack[gs_stack_top].gs_colour; cpexists = gs_stack[gs_stack_top].gs_cpexists; currenty = gs_stack[gs_stack_top].gs_currenty; currentxheight2 = gs_stack[gs_stack_top].gs_xheight2; gs_stack_top--; debug0(DPF, D, "PDF_RestoreGraphicState returning."); } /* end PDF_RestoreGraphicState */
void InitTime(void) { time_t raw_time; struct tm *now; FULL_CHAR buff[20]; OBJECT par, tmp, sym, env; OBJECT tag, second, minute, hour, weekday, monthday, yearday, month, year, century, dst; debug0(DTK, D, "InitTime()"); /* define @Moment symbol with its host of named parameters */ MomentSym = load(KW_MOMENT, LOCAL, StartSym); tag = load(KW_TAG, NPAR, MomentSym); second = load(KW_SECOND, NPAR, MomentSym); minute = load(KW_MINUTE, NPAR, MomentSym); hour = load(KW_HOUR, NPAR, MomentSym); monthday = load(KW_DAY, NPAR, MomentSym); month = load(KW_MONTH, NPAR, MomentSym); year = load(KW_YEAR, NPAR, MomentSym); century = load(KW_CENTURY, NPAR, MomentSym); weekday = load(KW_WEEKDAY, NPAR, MomentSym); yearday = load(KW_YEARDAY, NPAR, MomentSym); dst = load(KW_DAYLIGHTSAVING, NPAR, MomentSym); /* get current time and convert to ASCII */ if( time(&raw_time) == -1 ) Error(35, 1, "unable to obtain the current time", WARN, no_fpos); now = localtime(&raw_time); StringCopy(time_string, AsciiToFull(asctime(now))); time_string[StringLength(time_string) - 1] = '\0'; /* start of current_moment */ New(current_moment, CLOSURE); actual(current_moment) = MomentSym; /* attach its many parameters */ add_par("%s", KW_NOW, tag); add_par("%.2d", now->tm_sec, second); add_par("%.2d", now->tm_min, minute); add_par("%.2d", now->tm_hour, hour); add_par("%d", now->tm_mday, monthday); add_par("%d", now->tm_mon + 1, month); add_par("%.2d", now->tm_year % 100, year); add_par("%d", (now->tm_year+1900) / 100, century); add_par("%d", now->tm_wday + 1, weekday); add_par("%d", now->tm_yday, yearday); add_par("%d", now->tm_isdst, dst); /* add a null environment */ New(env, ENV); AttachEnv(env, current_moment); debug0(DTK, D, "InitTime() returning."); debug0(DTK, DD, "current_moment ="); ifdebug(DTK, DD, DebugObject(current_moment)); } /* end InitTime */
static void ParentFlush(BOOLEAN prnt_flush, OBJECT dest_index, BOOLEAN kill) { OBJECT prnt; debug3(DGF, DD, "ParentFlush(%s, %s, %s)", bool(prnt_flush), EchoIndex(dest_index), bool(kill)); if( prnt_flush ) { Parent(prnt, Up(dest_index)); if( kill ) DeleteNode(dest_index); debug0(DGF, DD, " calling FlushGalley from ParentFlush"); FlushGalley(prnt); } else if( kill ) DeleteNode(dest_index) debug0(DGF, DD, "ParentFlush returning."); } /* end ParentFlush */
void EnvInit(void) { int i; debug0(DET, DD, "EnvInit()"); stat_reads = 0; stat_read_hits = 0; stat_writes = 0; stat_write_hits = 0; New(env_cache, ACAT); cache_count = 0; for( i = 0; i < TAB_SIZE; i++ ) { tab[i] = nilobj; } debug0(DET, DD, "EnvInit returning"); } /* end EnvInit */
static void PDF_PrintInitialize(FILE *fp) { debug0(DPF, DD, "PDF_PrintInitialize(fp)"); out_fp = fp; prologue_done = FALSE; gs_stack_top = -1; currentfont = NO_FONT; currentcolour = NO_COLOUR; cpexists = FALSE; wordcount = pagecount = 0; New(needs, ACAT); New(supplied, ACAT); debug0(DPF, DD, "PDF_PrintInitialize returning."); } /* end PDF_PrintInitialize */
void PDF_SaveGraphicState(OBJECT x) { debug0(DPF, D, "PDF_SaveGraphicState()"); PDFPage_Push(out_fp); gs_stack_top++; if( gs_stack_top >= MAX_GS ) Error(50, 1, "rotations, graphics etc. too deeply nested (max is %d)", FATAL, &fpos(x), MAX_GS); gs_stack[gs_stack_top].gs_font = currentfont; gs_stack[gs_stack_top].gs_colour = currentcolour; gs_stack[gs_stack_top].gs_cpexists = cpexists; gs_stack[gs_stack_top].gs_currenty = currenty; gs_stack[gs_stack_top].gs_xheight2 = currentxheight2; debug0(DPF, D, "PDF_SaveGraphicState returning."); } /* end PDF_SaveGraphicState */
int rdbi_col_getW( rdbi_context_def *context, wchar_t *column_name, wchar_t *type, int *length, int *scale, int *nullable, int *is_autoincrement, int *position, int *eof) { int status; debug_on("rdbi_col_getW"); status = (*(context->dispatch.col_getW))(context->drvr, column_name, type, length, scale, nullable, is_autoincrement, position, eof); context->rdbi_last_status = status; debug_area() { if (*eof) { debug0("eof=TRUE"); } else { debug6("column='%ls', type='%ls', length=%d, scale=%d, nullable=%s, position=%d", ISNULL(column_name), ISNULL(type), *length, *scale, ISTRUE(*nullable), *position); } } debug_return(NULL, status); }
void db_search_folder_add_items (const gchar *id, GSList *items) { sqlite3_stmt *stmt; GSList *iter; gint res; debug2 (DEBUG_DB, "add %d items to search folder node \"%s\"", g_slist_length (items), id); stmt = db_get_statement ("itemUpdateSearchFoldersStmt"); iter = items; while (iter) { itemPtr item = (itemPtr)iter->data; sqlite3_reset (stmt); sqlite3_bind_text (stmt, 1, id, -1, SQLITE_TRANSIENT); sqlite3_bind_text (stmt, 2, item->nodeId, -1, SQLITE_TRANSIENT); sqlite3_bind_int (stmt, 3, item->id); res = sqlite3_step (stmt); if (SQLITE_DONE != res) g_error ("db_search_folder_add_items: sqlite3_step (error code %d)!", res); iter = g_slist_next (iter); } sqlite3_finalize (stmt); debug0 (DEBUG_DB, "adding items to search folder finished"); }
void AttachEnv(OBJECT env, OBJECT x) { debug2(DCE, DD, "AttachEnv( %s, %s )", EchoObject(env), EchoObject(x)); assert( env != nilobj && type(env) == ENV, "AttachEnv: type(env) != ENV!" ); assert( type(x) == CLOSURE || type(x) == ENV_OBJ, "AttachEnv: type(x)!" ); Link(x, env); debug0(DCE, DD, "AttachEnv returning."); } /* end AttachEnv */
void PDF_DefineGraphicNames(OBJECT x) { assert( type(x) == GRAPHIC, "PrintGraphic: type(x) != GRAPHIC!" ); debug1(DPF, D, "DefineGraphicNames( %s )", EchoObject(x)); debug1(DPF, DD, " style = %s", EchoStyle(&save_style(x))); /* if font is different to previous word then print change */ if( font(save_style(x)) != currentfont ) { currentfont = font(save_style(x)); if( currentfont > 0 ) { currentxheight2 = FontHalfXHeight(currentfont); PDFFont_Set(out_fp, FontSize(currentfont, x), FontName(currentfont)); } } /* if colour is different to previous word then print change */ if( colour(save_style(x)) != currentcolour ) { currentcolour = colour(save_style(x)); if( currentcolour > 0 ) { char str[256]; sprintf(str, "%s ", ColourCommand(currentcolour)); PDFPage_Write(out_fp, str); } } PDFPage_SetVars(size(x, COLM), size(x, ROWM), back(x, COLM), fwd(x, ROWM), currentfont <= 0 ? 12*PT : FontSize(currentfont, x), width(line_gap(save_style(x))), width(space_gap(save_style(x)))); debug0(DPF, D, "PDF_DefineGraphicNames returning."); } /* end PDF_DefineGraphicNames */
/** * This function tries to find a feed link for a given HTTP URI. It * tries to download it. If it finds a valid feed source it parses * this source instead into the given feed parsing context. It also * replaces the HTTP URI with the found feed source. */ static void feed_parser_auto_discover (feedParserCtxtPtr ctxt) { gchar *source; if (ctxt->feed->parseErrors) g_string_truncate (ctxt->feed->parseErrors, 0); else ctxt->feed->parseErrors = g_string_new(NULL); debug1 (DEBUG_UPDATE, "Starting feed auto discovery (%s)", subscription_get_source (ctxt->subscription)); source = html_auto_discover_feed (ctxt->data, subscription_get_source (ctxt->subscription)); /* FIXME: we only need the !g_str_equal as a workaround after a 404 */ if (source && !g_str_equal (source, subscription_get_source (ctxt->subscription))) { debug1 (DEBUG_UPDATE, "Discovered link: %s", source); ctxt->failed = FALSE; subscription_set_source (ctxt->subscription, source); /* The feed that was processed wasn't the correct one, we need to redownload it. * Cancel the update in case there's one in progress */ subscription_cancel_update (ctxt->subscription); subscription_update (ctxt->subscription, FEED_REQ_RESET_TITLE); g_free (source); } else { debug0 (DEBUG_UPDATE, "No feed link found!"); g_string_append (ctxt->feed->parseErrors, _("The URL you want Liferea to subscribe to points to a webpage and the auto discovery found no feeds on this page. Maybe this webpage just does not support feed auto discovery.")); } }
static UniqueResponse message_received_cb (UniqueApp *app, UniqueCommand command, UniqueMessageData *message, guint time_, gpointer user_data) { UniqueResponse res; gchar *feed; debug1(DEBUG_GUI, "libunique command received >>>%d<<<", command); switch (command) { case UNIQUE_ACTIVATE: /* Raise the liferea window */ debug0 (DEBUG_GUI, "-> raise window requested"); liferea_shell_present (); res = UNIQUE_RESPONSE_OK; break; case COMMAND_ADD_FEED: feed = unique_message_data_get_text (message); feedlist_add_subscription (feed, NULL, NULL, 0); res = UNIQUE_RESPONSE_OK; break; default: g_warning ("Received unknown libunique command: >>>%d<<<", command); res = UNIQUE_RESPONSE_OK; break; } return res; }
BOOLEAN EnvWriteRetrieve(OBJECT env, FILE_NUM fnum, int *offset, int *lnum) { unsigned int pos; OBJECT link, y, z; debug2(DET, DD, "EnvWriteRetrieve(env %d, %s)", (int) env, FileName(fnum)); debug1(DET, DDD, " %s", EchoObject(env)); stat_writes++; hash1(pos, env, fnum); if( tab[pos] != nilobj ) { for( link = Down(tab[pos]); link != tab[pos]; link = NextDown(link) ) { Child(y, link); Child(z, Down(y)); if( env_fnum(y) == fnum && z == env && !env_read(y) ) { MoveLink(LastUp(y), env_cache, PARENT); *offset = env_offset(y); *lnum = env_lnum(y); stat_write_hits++; debug2(DET, DD, "EnvWriteRetrieve returning TRUE (offset %d, lnum %d)", *offset, *lnum); return TRUE; } } } debug0(DET, DD, "EnvWriteRetrieve returning FALSE"); return FALSE; } /* end EnvWriteRetrieve */
/* do_seennick(): * takes a seen-dataset and produces the corresponding reply basically * by referencing to the lang entry with the same number as the seen-type. */ static char *do_seennick(seendat *l) { // char buf[256], *msg; int stype; Context; if (!l) { debug0("ERROR! Tryed to do a seennick on a NULL pointer!"); return "ERROR! seendat == NULL!!!"; } glob_seendat = l; // l->type is the basic language-entry-number stype = l->type + 100; // in some cases, we might need a special reply, so modify the // number if neccessary switch (l->type) { case SEEN_JOIN: if (!onchan(l->nick, l->chan)) stype += 20; break; case SEEN_PART: /* nothing to do here */ break; case SEEN_SIGN: /* nothing again */ break; case SEEN_NICK: if (!onchan(l->msg, l->chan)) stype += 20; break; case SEEN_NCKF: if (!onchan(l->nick, l->chan)) stype += 20; break; case SEEN_KICK: /* msg = buf; strncpy(buf, l->msg, 255); msg[255] = 0; sglobpunisher = newsplit(&msg); sglobreason = msg; */ break; case SEEN_SPLT: /* nothing to do here */ break; case SEEN_REJN: if (!onchan(l->nick, l->chan)) stype += 20; break; case SEEN_CHJN: case SEEN_CHPT: if (!strcmp(l->chan, "0")) stype += 20; break; default: stype = 140; } return getslang(stype); }
static void conf_proxy_reset_settings_cb (GSettings *settings, guint cnxn_id, gchar *key, gpointer user_data) { gchar *proxyname, *proxyusername, *proxypassword; gint proxyport; gint proxydetectmode; gboolean proxyuseauth; proxyname = NULL; proxyport = 0; proxyusername = NULL; proxypassword = NULL; conf_get_int_value (PROXY_DETECT_MODE, &proxydetectmode); switch (proxydetectmode) { default: case 0: debug0 (DEBUG_CONF, "proxy auto detect is configured"); /* nothing to do, all done by libproxy inside libsoup */ break; case 1: debug0 (DEBUG_CONF, "proxy is disabled by user"); /* nothing to do */ break; case 2: debug0 (DEBUG_CONF, "manual proxy is configured"); conf_get_str_value (PROXY_HOST, &proxyname); conf_get_int_value (PROXY_PORT, &proxyport); conf_get_bool_value (PROXY_USEAUTH, &proxyuseauth); if (proxyuseauth) { conf_get_str_value (PROXY_USER, &proxyusername); conf_get_str_value (PROXY_PASSWD, &proxypassword); } break; } debug4 (DEBUG_CONF, "Manual proxy settings are now %s:%d %s:%s", proxyname != NULL ? proxyname : "NULL", proxyport, proxyusername != NULL ? proxyusername : "******", proxypassword != NULL ? proxypassword : "******"); network_set_proxy (proxydetectmode, proxyname, proxyport, proxyusername, proxypassword); }
static void PDF_PrintUnderline(FONT_NUM fnum, COLOUR_NUM col, FULL_LENGTH xstart, FULL_LENGTH xstop, FULL_LENGTH ymk) { debug5(DPF, DD, "PDF_PrintUnderline(ft %d, co %d, xstrt %s, xstp %s, ymk %s)", fnum, col, EchoLength(xstart), EchoLength(xstop), EchoLength(ymk)); PDFPage_PrintUnderline(out_fp, xstart, xstop, ymk - finfo[fnum].underline_pos, finfo[fnum].underline_thick); debug0(DPF, DD, "PrintUnderline returning."); } /* end PDF_PrintUnderline */
static void PDF_CoordRotate(FULL_LENGTH amount) { int theAmount; debug1(DPF, D, "PDF_CoordRotate(%.1f degrees)", (float) amount / DG); theAmount = ((amount / DG) % 360); if( theAmount != 0 ) PDFPage_Rotate(out_fp, (double) theAmount * (double) PI / (double) 180.0); cpexists = FALSE; debug0(DPF, D, "CoordRotate returning."); } /* end PDF_CoordRotate */
void DeleteEverySym(void) { int i, j, load, cost; OBJECT p, plink, link, x, entry; debug0(DST, DD, "DeleteEverySym()"); /* dispose the bodies of all symbols */ for( i = 0; i < MAX_TAB; i++ ) { entry = (OBJECT) &symtab[i]; for( plink = Down(entry); plink != entry; plink = NextDown(plink) ) { Child(p, plink); for( link = Down(p); link != p; link = NextDown(link) ) { Child(x, link); DeleteSymBody(x); /* *** will not work now while( base_uses(x) != nilobj ) { tmp = base_uses(x); base_uses(x) = next(tmp); PutMem(tmp, USES_SIZE); } while( uses(x) != nilobj ) { tmp = uses(x); uses(x) = next(tmp); PutMem(tmp, USES_SIZE); } *** */ } } } /* dispose the symbol name strings, gather statistics, and print them */ load = cost = 0; for( i = 0; i < MAX_TAB; i++ ) { j = 1; entry = (OBJECT) &symtab[i]; while( Down(entry) != entry ) { load += 1; cost += j; j += 1; DisposeChild(Down(entry)); } } if( load > 0 ) { debug4(DST, DD, "size = %d, items = %d (%d%%), probes = %.1f", MAX_TAB, load, (100*load)/MAX_TAB, (float) cost/load); } else { debug1(DST, DD, "table size = %d, no entries in table", MAX_TAB); } debug0(DST, DD, "DeleteEverySym returning."); } /* end DeleteEverySym */
static void PDF_LinkDest(OBJECT name, FULL_LENGTH llx, FULL_LENGTH lly, FULL_LENGTH urx, FULL_LENGTH ury) { debug5(DPF, D, "PDF_LinkDest(%s, %d, %d, %d, %d)", EchoObject(name), llx, lly, urx, ury); /* still to do */ debug0(DPF, D, "PDF_LinkDest returning."); } /* end PDF_LinkDest */
void DetachGalley(OBJECT hd) { OBJECT prnt, index; assert( type(hd) == HEAD && Up(hd) != hd, "DetachGalley: precondition!" ); debug1(DGA, D, "DetachGalley( %s )", SymName(actual(hd))); Parent(prnt, Up(hd)); assert( Up(prnt) != prnt, "DetachGalley: parent!" ); New(index, UNATTACHED); pinpoint(index) = nilobj; MoveLink(Up(hd), index, PARENT); Link(NextDown(Up(prnt)), index); debug0(DGA, D, "DetachGalley returning."); } /* end DetachGalley */
void feedlist_schedule_save (void) { if (feedlist->priv->loading || feedlist->priv->saveTimer) return; debug0 (DEBUG_CONF, "Scheduling feedlist save"); /* By waiting here 5s and checking feedlist_save_time we hope to catch bulks of feed list changes and save less often */ feedlist->priv->saveTimer = g_timeout_add_seconds (5, feedlist_schedule_save_cb, NULL); }
static gboolean inoreader_feed_subscription_prepare_update_request (subscriptionPtr subscription, struct updateRequest *request) { debug0 (DEBUG_UPDATE, "preparing InoReader feed subscription for update\n"); nodePtr node = subscription->node; if (node->source->loginState == NODE_SOURCE_STATE_NONE) { subscription_update (node_source_root_from_node (node)->subscription, 0) ; return FALSE; } debug0 (DEBUG_UPDATE, "Setting cookies for a InoReader subscription"); gchar* source_escaped = g_uri_escape_string(request->source, NULL, TRUE); gchar* newUrl = g_strdup_printf ("http://www.inoreader.com/reader/atom/feed/%s", source_escaped); update_request_set_source (request, newUrl); g_free (newUrl); g_free (source_escaped); update_request_set_auth_value (request, node->source->authToken); return TRUE; }
static void inoreader_source_opml_quick_update_cb (const struct updateResult* const result, gpointer userdata, updateFlags flags) { InoreaderSourcePtr gsource = (InoreaderSourcePtr) userdata; xmlDocPtr doc; if (!result->data) { /* what do I do? */ debug0 (DEBUG_UPDATE, "InoreaderSource: Unable to get unread counts, this update is aborted."); return; } doc = xml_parse (result->data, result->size, NULL); if (!doc) { debug0 (DEBUG_UPDATE, "InoreaderSource: The XML failed to parse, maybe the session has expired. (FIXME)"); return; } xpath_foreach_match (xmlDocGetRootElement (doc), "/object/list[@name='unreadcounts']/object", inoreader_source_opml_quick_update_helper, gsource); xmlFreeDoc (doc); }
static gboolean feedlist_auto_update (void *data) { debug_enter ("feedlist_auto_update"); if (network_monitor_is_online ()) node_auto_update_subscription (ROOTNODE); else debug0 (DEBUG_UPDATE, "no update processing because we are offline!"); debug_exit ("feedlist_auto_update"); return TRUE; }