[sword-cvs] sword/src/modules/filters gbffootnotes.cpp,1.25,1.26 gbfplain.cpp,1.17,1.18 osisfootnotes.cpp,1.15,1.16 osisheadings.cpp,1.13,1.14 osislemma.cpp,1.6,1.7 osismorph.cpp,1.11,1.12 osisplain.cpp,1.15,1.16 osisredletterwords.cpp,1.8,1.9 osisscripref.cpp,1.7,1.8 osisstrongs.cpp,1.15,1.16
sword@www.crosswire.org
sword@www.crosswire.org
Thu, 8 Apr 2004 13:57:34 -0700
Update of /cvs/core/sword/src/modules/filters
In directory www:/tmp/cvs-serv32427/src/modules/filters
Modified Files:
gbffootnotes.cpp gbfplain.cpp osisfootnotes.cpp
osisheadings.cpp osislemma.cpp osismorph.cpp osisplain.cpp
osisredletterwords.cpp osisscripref.cpp osisstrongs.cpp
Log Message:
speed fixes for the search (joachim)
Index: gbffootnotes.cpp
===================================================================
RCS file: /cvs/core/sword/src/modules/filters/gbffootnotes.cpp,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -d -r1.25 -r1.26
--- gbffootnotes.cpp 24 Jan 2004 18:42:40 -0000 1.25
+++ gbffootnotes.cpp 8 Apr 2004 20:57:32 -0000 1.26
@@ -49,6 +49,8 @@
SWBuf orig = text;
const char *from = orig.c_str();
+
+ XMLTag tag;
for (text = ""; *from; from++) {
if (*from == '<') {
@@ -59,21 +61,25 @@
if (*from == '>') { // process tokens
intoken = false;
- XMLTag tag(token);
- if (!strcmp(tag.getName(), "RF")) {
+ //XMLTag tag(token);
+ if (!strncmp(token, "RF",2)) {
+ tag = token;
+
refs = "";
startTag = tag;
hide = true;
tagText = "";
continue;
}
- else if (!strcmp(tag.getName(), "Rf")) {
+ else if (!strncmp(token, "Rf",2)) {
+ tag = token;
+
if (module->isProcessEntryAttributes()) {
- if(tagText.length() == 1 || !strcmp(module->Name(), "IGNT")) {
+ if((tagText.length() == 1) || !strcmp(module->Name(), "IGNT")) {
if (option) { // for ASV marks text in verse then put explanation at end of verse
- text += " <FA>(";
+ text.append(" <FA>(");
text.append(tagText);
- text += ")<Fr>";
+ text.append(")<Fr>");
hide = false;
continue;
}
@@ -83,7 +89,7 @@
sprintf(buf, "%i", ++footnoteNum);
module->getEntryAttributes()["Footnote"]["count"]["value"] = buf;
StringList attributes = startTag.getAttributeNames();
- for (StringList::iterator it = attributes.begin(); it != attributes.end(); it++) {
+ for (StringList::const_iterator it = attributes.begin(); it != attributes.end(); it++) {
module->getEntryAttributes()["Footnote"][buf][it->c_str()] = startTag.getAttribute(it->c_str());
}
module->getEntryAttributes()["Footnote"][buf]["body"] = tagText;
@@ -91,39 +97,32 @@
}
hide = false;
if (option) {
- text += startTag;
+ text.append(startTag);
text.append(tagText);
}
else continue;
}
if (!hide) {
- text += '<';
+ text.append('<');
text.append(token);
- text += '>';
+ text.append('>');
}
else {
- tagText += '<';
+ tagText.append('<');
tagText.append(token);
- tagText += '>';
+ tagText.append('>');
}
continue;
}
if (intoken) { //copy token
- token += *from;
+ token.append(*from);
}
else if (!hide) { //copy text which is not inside a token
- text += *from;
+ text.append(*from);
}
- else tagText += *from;
+ else tagText.append(*from);
}
return 0;
-
-
-
-
-
-
-
/*
if (!option) { // if we don't want footnotes
Index: gbfplain.cpp
===================================================================
RCS file: /cvs/core/sword/src/modules/filters/gbfplain.cpp,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- gbfplain.cpp 27 Jun 2003 06:13:16 -0000 1.17
+++ gbfplain.cpp 8 Apr 2004 20:57:32 -0000 1.18
@@ -19,10 +19,9 @@
char token[2048];
int tokpos = 0;
bool intoken = false;
- const char *from;
SWBuf orig = text;
- from = orig.c_str();
- for (text = ""; *from; from++) {
+ const char* from = orig.c_str();
+ for (text = ""; *from; ++from) {
if (*from == '<') {
intoken = true;
tokpos = 0;
@@ -40,30 +39,31 @@
case 'G': // Greek
case 'H': // Hebrew
case 'T': // Tense
- text += " <";
- for (char *tok = token + 2; *tok; tok++)
- text += *tok;
- text += "> ";
+ text.append(" <");
+ //for (char *tok = token + 2; *tok; tok++)
+ // text += *tok;
+ text.append(token+2);
+ text.append("> ");
continue;
}
break;
case 'R':
switch(token[1]) {
case 'F': // footnote begin
- text += " [";
+ text.append(" [");
continue;
case 'f': // footnote end
- text += "] ";
+ text.append("] ");
continue;
}
break;
case 'C':
switch(token[1]) {
case 'A': // ASCII value
- text += (char)atoi(&token[2]);
+ text.append((char)atoi(&token[2]));
continue;
case 'G':
- text += ">";
+ text.append(">");
continue;
/* Bug in WEB
case 'L':
@@ -72,10 +72,10 @@
*/
case 'L': // Bug in WEB. Use above entry when fixed
case 'N': // new line
- text += '\n';
+ text.append('\n');
continue;
case 'M': // new paragraph
- text += "\n\n";
+ text.append("\n\n");
continue;
}
break;
@@ -87,7 +87,7 @@
token[tokpos++] = *from;
token[tokpos+2] = 0;
}
- else text += *from;
+ else text.append(*from);
}
return 0;
}
Index: osisfootnotes.cpp
===================================================================
RCS file: /cvs/core/sword/src/modules/filters/osisfootnotes.cpp,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -d -r1.15 -r1.16
--- osisfootnotes.cpp 24 Jan 2004 18:42:40 -0000 1.15
+++ osisfootnotes.cpp 8 Apr 2004 20:57:32 -0000 1.16
@@ -46,13 +46,15 @@
SWBuf orig = text;
const char *from = orig.c_str();
+
+ XMLTag tag;
for (text = ""; *from; from++) {
// remove all newlines temporarily to fix kjv2003 module
if ((*from == 10) || (*from == 13)) {
if ((text.length()>1) && (text[text.length()-2] != ' ') && (*(from+1) != ' '))
- text += ' ';
+ text.append(' ');
continue;
}
@@ -63,12 +65,12 @@
continue;
}
if (*from == '>') { // process tokens
- intoken = false;
-
- XMLTag tag(token);
- if (!strcmp(tag.getName(), "note")) {
+ intoken = false;
+// if (!strcmp(tag.getName(), "note")) {
+ if (!strncmp(token, "note", 4)) {
+ tag = token;
if (!tag.isEndTag()) {
- if (SWBuf("strongsMarkup") == tag.getAttribute("type")) { // handle bug in KJV2003 module where some note open tags were <note ... />
+ if (!strcmp("strongsMarkup", tag.getAttribute("type"))) { // handle bug in KJV2003 module where some note open tags were <note ... />
tag.setEmpty(false);
}
if (!tag.isEmpty()) {
@@ -84,7 +86,7 @@
if (module->isProcessEntryAttributes()) {
sprintf(buf, "%i", footnoteNum++);
StringList attributes = startTag.getAttributeNames();
- for (StringList::iterator it = attributes.begin(); it != attributes.end(); it++) {
+ for (StringList::const_iterator it = attributes.begin(); it != attributes.end(); it++) {
module->getEntryAttributes()["Footnote"][buf][it->c_str()] = startTag.getAttribute(it->c_str());
}
module->getEntryAttributes()["Footnote"][buf]["body"] = tagText;
@@ -97,7 +99,7 @@
}
hide = false;
if ((option) || ((startTag.getAttribute("type") && (!strcmp(startTag.getAttribute("type"), "crossReference"))))) { // we want the tag in the text; crossReferences are handled by another filter
- text += startTag;
+ text.append(startTag);
text.append(tagText);
}
else continue;
@@ -105,31 +107,39 @@
}
// if not a heading token, keep token in text
- if ((!strcmp(tag.getName(), "reference")) && (!tag.isEndTag())) {
- SWBuf osisRef = tag.getAttribute("osisRef");
- if (refs.length())
- refs += "; ";
- refs += osisRef;
+ //if ((!strcmp(tag.getName(), "reference")) && (!tag.isEndTag())) {
+ // SWBuf osisRef = tag.getAttribute("osisRef");
+ if (!strncmp(token, "reference", 9)) {
+ if (refs.length()) {
+ refs.append("; ");
+ }
+
+ char* attr = strstr(token.c_str() + 9, "osisRef=\"");
+ char* end = attr ? strchr(attr+10, '"') : 0;
+
+ if (attr && end) {
+ refs.append(attr+9, end-(attr+9));
+ }
}
if (!hide) {
- text += '<';
+ text.append('<');
text.append(token);
- text += '>';
+ text.append('>');
}
else {
- tagText += '<';
+ tagText.append('<');
tagText.append(token);
- tagText += '>';
+ tagText.append('>');
}
continue;
}
if (intoken) { //copy token
- token += *from;
+ token.append(*from);
}
else if (!hide) { //copy text which is not inside a token
- text += *from;
+ text.append(*from);
}
- else tagText += *from;
+ else tagText.append(*from);
}
return 0;
}
Index: osisheadings.cpp
===================================================================
RCS file: /cvs/core/sword/src/modules/filters/osisheadings.cpp,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- osisheadings.cpp 28 Feb 2004 20:14:29 -0000 1.13
+++ osisheadings.cpp 8 Apr 2004 20:57:32 -0000 1.14
@@ -44,6 +44,8 @@
SWBuf orig = text;
const char *from = orig.c_str();
+
+ XMLTag tag;
for (text = ""; *from; from++) {
if (*from == '<') {
@@ -54,8 +56,10 @@
if (*from == '>') { // process tokens
intoken = false;
- XMLTag tag(token);
- if (!stricmp(tag.getName(), "title")) {
+ //if (!stricmp(tag.getName(), "title")) {
+ if (!strncmp(token, "title", 5)) {
+ tag = token;
+
if ((tag.getAttribute("subtype")) && (!stricmp(tag.getAttribute("subtype"), "x-preverse"))) {
hide = true;
preverse = true;
@@ -69,9 +73,9 @@
hide = true;
header = "";
if (option) { // we want the tag in the text
- text += '<';
+ text.append('<');
text.append(token);
- text += '>';
+ text.append('>');
}
continue;
}
@@ -91,7 +95,7 @@
}
}
StringList attributes = startTag.getAttributeNames();
- for (StringList::iterator it = attributes.begin(); it != attributes.end(); it++) {
+ for (StringList::const_iterator it = attributes.begin(); it != attributes.end(); it++) {
module->getEntryAttributes()["Heading"][buf][it->c_str()] = startTag.getAttribute(it->c_str());
}
}
@@ -106,19 +110,19 @@
// if not a heading token, keep token in text
if (!hide) {
- text += '<';
+ text.append('<');
text.append(token);
- text += '>';
+ text.append('>');
}
continue;
}
if (intoken) { //copy token
- token += *from;
+ token.append(*from);
}
else if (!hide) { //copy text which is not inside a token
- text += *from;
+ text.append(*from);
}
- else header += *from;
+ else header.append(*from);
}
return 0;
}
Index: osislemma.cpp
===================================================================
RCS file: /cvs/core/sword/src/modules/filters/osislemma.cpp,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- osislemma.cpp 24 Jan 2004 18:42:40 -0000 1.6
+++ osislemma.cpp 8 Apr 2004 20:57:32 -0000 1.7
@@ -49,7 +49,8 @@
}
if (*from == '>') { // process tokens
intoken = false;
- XMLTag tag(token);
+
+ /*XMLTag tag(token);
if ((!strcmp(tag.getName(), "w")) && (!tag.isEndTag())) { // Lemma
SWBuf lemma = tag.getAttribute("lemma");
if (lemma.length()) {
@@ -57,8 +58,25 @@
tag.setAttribute("savlm", lemma.c_str());
}
}
+ */
+
+ if (*token == 'w') {
+ const int len = strlen(token);
+
+ const char* start = strstr(token, "lemma=\"");
+ const char* end = start ? strchr(start+6, '"') : 0;
+ if (start && end) { //we wan to leave out the moprh attribute
+ text.append(token, start-token); //the text before the morph attr
+ text.append(end, len-(end - token)); //text after the morph attr
+ }
+ }
+ else {
+ text.append(token);
+ }
+
// keep tag, possibly with the lemma removed
- text += tag;
+ //text += tag;
+
continue;
}
if (intoken) {
@@ -67,7 +85,7 @@
token[tokpos] = 0;
}
else {
- text += *from;
+ text.append(*from);
lastspace = (*from == ' ');
}
}
Index: osismorph.cpp
===================================================================
RCS file: /cvs/core/sword/src/modules/filters/osismorph.cpp,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- osismorph.cpp 24 Jan 2004 18:42:40 -0000 1.11
+++ osismorph.cpp 8 Apr 2004 20:57:32 -0000 1.12
@@ -32,13 +32,12 @@
char OSISMorph::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
if (!option) { // if we don't want morph tags
- const char *from;
char token[2048]; // cheese. Fix.
int tokpos = 0;
bool intoken = false;
bool lastspace = false;
SWBuf orig = text;
- from = orig.c_str();
+ const char *from = orig.c_str();
for (text = ""; *from; from++) {
if (*from == '<') {
@@ -49,13 +48,30 @@
}
if (*from == '>') { // process tokens
intoken = false;
- XMLTag tag(token);
+
+ /*XMLTag tag(token);
if ((!strcmp(tag.getName(), "w")) && (!tag.isEndTag())) { // Morph
if (tag.getAttribute("morph"))
tag.setAttribute("morph", 0);
+ }*/
+
+ if (*token == 'w') {
+ char* start = strstr(token, "morph=\"");
+ const int len = strlen(token);
+ if (start && (len>8)) {
+ char* end = strchr(start+8, '"');
+ if (end) { //remove the morph value
+ text.append(token, start-token); //the text before the morph attr
+ text.append(end, len-(end - token)); //text after the morph attr
+ }
+ }
}
+ else {
+ text.append(token);
+ }
+
// keep tag, possibly with the morph removed
- text += tag;
+ //text.append(tag);
continue;
}
if (intoken) {
@@ -64,7 +80,7 @@
token[tokpos] = 0;
}
else {
- text += *from;
+ text.append(*from);
lastspace = (*from == ' ');
}
}
Index: osisplain.cpp
===================================================================
RCS file: /cvs/core/sword/src/modules/filters/osisplain.cpp,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -d -r1.15 -r1.16
--- osisplain.cpp 24 Jan 2004 18:42:40 -0000 1.15
+++ osisplain.cpp 8 Apr 2004 20:57:32 -0000 1.16
@@ -36,24 +36,26 @@
addEscapeStringSubstitute("gt", ">");
addEscapeStringSubstitute("quot", "\"");
+ setTokenCaseSensitive(true);
addTokenSubstitute("title", "\n");
addTokenSubstitute("/title", "\n");
addTokenSubstitute("/l", "\n");
addTokenSubstitute("lg", "\n");
addTokenSubstitute("/lg", "\n");
-
- setTokenCaseSensitive(true);
}
bool OSISPlain::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
// manually process if it wasn't a simple substitution
+ XMLTag tag;
+
if (!substituteToken(buf, token)) {
MyUserData *u = (MyUserData *)userData;
- XMLTag tag(token);
if (((*token == 'w') && (token[1] == ' ')) ||
((*token == '/') && (token[1] == 'w') && (!token[2]))) {
+ tag = token;
+
bool start = false;
if (*token == 'w') {
if (token[strlen(token)-1] != '/') {
@@ -72,12 +74,20 @@
if (attrib = tag.getAttribute("xlit")) {
val = strchr(attrib, ':');
val = (val) ? (val + 1) : attrib;
- buf.appendFormatted(" <%s>", val);
+ buf.append(" <");
+ buf.append(val);
+ buf.append(">");
+
+ //buf.appendFormatted(" <%s>", val);
}
if (attrib = tag.getAttribute("gloss")) {
val = strchr(attrib, ':');
val = (val) ? (val + 1) : attrib;
- buf.appendFormatted(" <%s>", val);
+ buf.append(" <");
+ buf.append(val);
+ buf.append(">");
+
+// buf.appendFormatted(" <%s>", val);
}
if (attrib = tag.getAttribute("lemma")) {
int count = tag.getAttributePartCount("lemma");
@@ -91,7 +101,13 @@
val++;
if ((!strcmp(val, "3588")) && (lastText.length() < 1))
show = false;
- else buf.appendFormatted(" <%s>}", val);
+ else {
+ buf.append(" <");
+ buf.append(val);
+ buf.append(">}");
+
+// buf.appendFormatted(" <%s>}", val);
+ }
} while (++i < count);
}
if ((attrib = tag.getAttribute("morph")) && (show)) {
@@ -104,26 +120,33 @@
val = (val) ? (val + 1) : attrib;
if ((*val == 'T') && (strchr("GH", val[1])) && (isdigit(val[2])))
val+=2;
- buf.appendFormatted(" (%s)", val);
+ buf.append(" (");
+ buf.append(val);
+ buf.append(')');
+// buf.appendFormatted(" (%s)", val);
} while (++i < count);
}
if (attrib = tag.getAttribute("POS")) {
val = strchr(attrib, ':');
val = (val) ? (val + 1) : attrib;
- buf.appendFormatted(" <%s>", val);
+
+ buf.append(" <");
+ buf.append(val);
+ buf.append(">");
+// buf.appendFormatted(" <%s>", val);
}
}
// <note> tag
else if (!strncmp(token, "note", 4)) {
if (!strstr(token, "strongsMarkup")) { // leave strong's markup notes out, in the future we'll probably have different option filters to turn different note types on or off
- buf += " (";
+ buf.append(" (");
}
else u->suspendTextPassThru = true;
}
else if (!strncmp(token, "/note", 5)) {
if (!u->suspendTextPassThru)
- buf += ")";
+ buf.append(")");
else u->suspendTextPassThru = false;
}
@@ -131,13 +154,18 @@
else if (((*token == 'p') && ((token[1] == ' ') || (!token[1]))) ||
((*token == '/') && (token[1] == 'p') && (!token[2]))) {
userData->supressAdjacentWhitespace = true;
- buf += "\n";
+ buf.append("\n");
}
// <milestone type="line"/>
- else if ((!strcmp(tag.getName(), "milestone")) && (tag.getAttribute("type")) && (!strcmp(tag.getAttribute("type"), "line"))) {
- userData->supressAdjacentWhitespace = true;
- buf += "\n";
+ else if (!strncmp(token, "milestone", 9)) {
+ const char* type = strstr(token+9, "type=\"");
+ if (type && strncmp(type, "line", 4)) { //we check for type != line
+
+ // && (tag.getAttribute("type")) && (!strcmp(tag.getAttribute("type"), "line"))) {
+ userData->supressAdjacentWhitespace = true;
+ buf.append("\n");
+ }
}
else {
Index: osisredletterwords.cpp
===================================================================
RCS file: /cvs/core/sword/src/modules/filters/osisredletterwords.cpp,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- osisredletterwords.cpp 24 Jan 2004 18:42:40 -0000 1.8
+++ osisredletterwords.cpp 8 Apr 2004 20:57:32 -0000 1.9
@@ -49,18 +49,32 @@
if (*from == '>') { // process tokens
intoken = false;
- XMLTag tag(token);
- if (!stricmp(tag.getName(), "q")) {
+ //XMLTag tag(token);
+ /*if (!stricmp(tag.getName(), "q")) {
if ((tag.getAttribute("who")) && (!stricmp(tag.getAttribute("who"), "Jesus"))) {
tag.setAttribute("who", 0);
text += tag; // tag toString already has < and >
continue;
}
+ }*/
+ if (*token == 'q') {
+ char* start = strstr(token, "who=\"Jesus\"");
+ const int len = strlen(token);
+ if (start && (len>11)) {
+ char* end = start+11;
+ text.append(token, start-token); //the text before the who attr
+ text.append(end, len-(end - token)); //text after the who attr
+ }
+ }
+ else {
+ text.append(token);
}
+
+
// if we haven't modified, still use original token instead of tag, so we don't reorder attribs and stuff. It doesn't really matter, but this is less intrusive to the original markup.
- text += '<';
+ text.append('<');
text.append(token);
- text += '>';
+ text.append('>');
continue;
}
if (intoken) { //copy token
Index: osisscripref.cpp
===================================================================
RCS file: /cvs/core/sword/src/modules/filters/osisscripref.cpp,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- osisscripref.cpp 24 Jan 2004 18:42:40 -0000 1.7
+++ osisscripref.cpp 8 Apr 2004 20:57:32 -0000 1.8
@@ -43,6 +43,8 @@
SWBuf orig = text;
const char *from = orig.c_str();
+
+ XMLTag tag;
for (text = ""; *from; from++) {
if (*from == '<') {
@@ -53,11 +55,13 @@
if (*from == '>') { // process tokens
intoken = false;
- XMLTag tag(token);
- if (!strcmp(tag.getName(), "note")) {
+
+ //if (!strcmp(tag.getName(), "note")) {
+ if (!strncmp(token, "note", 4)) {
+ tag = token;
if (!tag.isEndTag() && (!tag.isEmpty())) {
startTag = tag;
- if ((tag.getAttribute("type")) && (!strcmp(tag.getAttribute("type"), "crossReference"))) {
+ if (tag.getAttribute("type") && !strcmp(tag.getAttribute("type"), "crossReference")) {
hide = true;
tagText = "";
if (option) { // we want the tag in the text
@@ -79,24 +83,24 @@
// if not a heading token, keep token in text
if (!hide) {
- text += '<';
+ text.append('<');
text.append(token);
- text += '>';
+ text.append('>');
}
else {
- tagText += '<';
+ tagText.append('<');
tagText.append(token);
- tagText += '>';
+ tagText.append('>');
}
continue;
}
if (intoken) { //copy token
- token += *from;
+ token.append(*from);
}
else if (!hide) { //copy text which is not inside a token
- text += *from;
+ text.append(*from);
}
- else tagText += *from;
+ else tagText.append(*from);
}
return 0;
}
Index: osisstrongs.cpp
===================================================================
RCS file: /cvs/core/sword/src/modules/filters/osisstrongs.cpp,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -d -r1.15 -r1.16
--- osisstrongs.cpp 4 Apr 2004 09:23:57 -0000 1.15
+++ osisstrongs.cpp 8 Apr 2004 20:57:32 -0000 1.16
@@ -33,7 +33,6 @@
char OSISStrongs::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
- const char *from;
char token[2048]; // cheese. Fix.
int tokpos = 0;
bool intoken = false;
@@ -46,7 +45,7 @@
char *ch;
SWBuf orig = text;
- from = orig.c_str();
+ const char *from = orig.c_str();
len = strlen(text) + 1; // shift string to right of buffer
@@ -124,11 +123,12 @@
}
}
// if not a strongs token, keep token in text
- text += '<';
- for (char *tok = token; *tok; tok++) {
- text += *tok;
- }
- text += '>';
+ text.append('<');
+ //for (char *tok = token; *tok; tok++) {
+ // text += *tok;
+ //}
+ text.append(token);
+ text.append('>');
continue;
}
@@ -138,7 +138,7 @@
token[tokpos+2] = 0;
}
else {
- text += *from;
+ text.append(*from);
lastspace = (*from == ' ');
}
}