QCString Definition::briefDescriptionAsTooltip() const { makeResident(); if (m_impl->brief) { if (m_impl->brief->tooltip.isEmpty() && !m_impl->brief->doc.isEmpty()) { static bool reentering=FALSE; if (!reentering) { MemberDef *md = definitionType()==TypeMember ? (MemberDef*)this : 0; const Definition *scope = definitionType()==TypeMember ? getOuterScope() : this; reentering=TRUE; // prevent requests for tooltips while parsing a tooltip m_impl->brief->tooltip = parseCommentAsText( scope,md, m_impl->brief->doc, m_impl->brief->file, m_impl->brief->line); reentering=FALSE; } } return m_impl->brief->tooltip; } return QCString(""); }
/*! Returns the string used in the footer for $navpath when * GENERATE_TREEVIEW is enabled */ QCString Definition::navigationPathAsString() const { QCString result; Definition *outerScope = getOuterScope(); QCString locName = localName(); /* if (outerScope && outerScope!=Doxygen::globalScope) { result+=outerScope->navigationPathAsString(); } else if (definitionType()==Definition::TypeFile && ((const FileDef*)this)->getDirDef()) { result+=((const FileDef*)this)->getDirDef()->navigationPathAsString(); } result+="<li class=\"navelem\">"; if (isLinkable()) { if (definitionType()==Definition::TypeGroup && ((const GroupDef*)this)->groupTitle()) { result+="<a class=\"el\" href=\"$relpath^"+getOutputFileBase()+Doxygen::htmlFileExtension+"\">"+ convertToHtml(((const GroupDef*)this)->groupTitle())+"</a>"; } else if (definitionType()==Definition::TypePage && !((const PageDef*)this)->title().isEmpty()) { result+="<a class=\"el\" href=\"$relpath^"+getOutputFileBase()+Doxygen::htmlFileExtension+"\">"+ convertToHtml(((const PageDef*)this)->title())+"</a>"; } else if (definitionType()==Definition::TypeClass) { QCString name = locName; if (name.right(2)=="-p") { name = name.left(name.length()-2); } result+="<a class=\"el\" href=\"$relpath^"+getOutputFileBase()+Doxygen::htmlFileExtension; if (!anchor().isEmpty()) result+="#"+anchor(); result+="\">"+convertToHtml(name)+"</a>"; } else { result+="<a class=\"el\" href=\"$relpath^"+getOutputFileBase()+Doxygen::htmlFileExtension+"\">"+ convertToHtml(locName)+"</a>"; } } else { result+="<b>"+convertToHtml(locName)+"</b>"; } result+="</li>"; */ return result; }
void ClosureExpression::processLambda(AnalysisResultConstRawPtr ar) { if (m_captureState == CaptureState::Unknown) { assert(m_type == ClosureType::Short); auto const closureFuncScope = m_func->getFunctionScope(); auto const paramNames = collectParamNames(); auto const& mentioned = closureFuncScope->getLocals(); std::set<std::string> toCapture; for (auto& m : mentioned) { if (paramNames.count(m)) continue; if (m == "this") { toCapture.insert("this"); continue; } auto scope = closureFuncScope; do { auto const prev = scope; scope = prev->getOuterScope()->getContainingFunction(); always_assert(scope); always_assert(!FileScope::getCurrent() || scope->getContainingFile() == FileScope::getCurrent()); if (scope->hasLocal(m)) { toCapture.insert(m); break; } } while (scope->isLambdaClosure()); } if (closureFuncScope->containsThis()) { toCapture.insert("this"); } setCaptureList(ar, toCapture); } }
void NamespaceDef::writeDocumentation(OutputList &ol) { static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW"); //static bool outputJava = Config_getBool("OPTIMIZE_OUTPUT_JAVA"); //static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN"); QCString pageTitle = title(); startFile(ol,getOutputFileBase(),name(),pageTitle,HLI_NamespaceVisible,!generateTreeView); if (!generateTreeView) { if (getOuterScope()!=Doxygen::globalScope) { writeNavigationPath(ol); } ol.endQuickIndices(); } startTitle(ol,getOutputFileBase(),this); ol.parseText(pageTitle); addGroupListToTitle(ol,this); addNamespaceAttributes(ol); endTitle(ol,getOutputFileBase(),displayName()); ol.startContents(); if (Doxygen::searchIndex) { Doxygen::searchIndex->setCurrentDoc(this,anchor(),FALSE); Doxygen::searchIndex->addWord(localName(),TRUE); } Doxygen::indexList->addIndexItem(this,0); //---------------------------------------- start flexible part ------------------------------- SrcLangExt lang = getLanguage(); QListIterator<LayoutDocEntry> eli( LayoutDocManager::instance().docEntries(LayoutDocManager::Namespace)); LayoutDocEntry *lde; for (eli.toFirst(); (lde=eli.current()); ++eli) { switch (lde->kind()) { case LayoutDocEntry::BriefDesc: writeBriefDescription(ol); break; case LayoutDocEntry::MemberDeclStart: startMemberDeclarations(ol); break; case LayoutDocEntry::NamespaceClasses: { LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; writeClassDeclarations(ol,ls->title(lang)); } break; case LayoutDocEntry::NamespaceNestedNamespaces: { LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; writeNamespaceDeclarations(ol,ls->title(lang),false); } break; case LayoutDocEntry::NamespaceNestedConstantGroups: { LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; writeNamespaceDeclarations(ol,ls->title(lang),true); } break; case LayoutDocEntry::MemberGroups: writeMemberGroups(ol); break; case LayoutDocEntry::MemberDecl: { LayoutDocEntryMemberDecl *lmd = (LayoutDocEntryMemberDecl*)lde; writeMemberDeclarations(ol,lmd->type,lmd->title(lang)); } break; case LayoutDocEntry::MemberDeclEnd: endMemberDeclarations(ol); break; case LayoutDocEntry::DetailedDesc: { LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; writeDetailedDescription(ol,ls->title(lang)); } break; case LayoutDocEntry::MemberDefStart: startMemberDocumentation(ol); break; case LayoutDocEntry::NamespaceInlineClasses: writeInlineClasses(ol); break; case LayoutDocEntry::MemberDef: { LayoutDocEntryMemberDef *lmd = (LayoutDocEntryMemberDef*)lde; writeMemberDocumentation(ol,lmd->type,lmd->title(lang)); } break; case LayoutDocEntry::MemberDefEnd: endMemberDocumentation(ol); break; case LayoutDocEntry::AuthorSection: writeAuthorSection(ol); break; case LayoutDocEntry::ClassIncludes: case LayoutDocEntry::ClassInheritanceGraph: case LayoutDocEntry::ClassNestedClasses: case LayoutDocEntry::ClassCollaborationGraph: case LayoutDocEntry::ClassAllMembersLink: case LayoutDocEntry::ClassUsedFiles: case LayoutDocEntry::ClassInlineClasses: case LayoutDocEntry::FileClasses: case LayoutDocEntry::FileNamespaces: case LayoutDocEntry::FileConstantGroups: case LayoutDocEntry::FileIncludes: case LayoutDocEntry::FileIncludeGraph: case LayoutDocEntry::FileIncludedByGraph: case LayoutDocEntry::FileSourceLink: case LayoutDocEntry::FileInlineClasses: case LayoutDocEntry::GroupClasses: case LayoutDocEntry::GroupInlineClasses: case LayoutDocEntry::GroupNamespaces: case LayoutDocEntry::GroupDirs: case LayoutDocEntry::GroupNestedGroups: case LayoutDocEntry::GroupFiles: case LayoutDocEntry::GroupGraph: case LayoutDocEntry::GroupPageDocs: case LayoutDocEntry::DirSubDirs: case LayoutDocEntry::DirFiles: case LayoutDocEntry::DirGraph: err("Internal inconsistency: member %d should not be part of " "LayoutDocManager::Namespace entry list\n",lde->kind()); break; } } //---------------------------------------- end flexible part ------------------------------- ol.endContents(); endFileWithNavPath(this,ol); if (Config_getBool("SEPARATE_MEMBER_PAGES")) { MemberList *allMemberList = getMemberList(MemberListType_allMembersList); if (allMemberList) allMemberList->sort(); writeMemberPages(ol); } }
void PageDef::writeDocumentation(OutputList &ol) { static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW"); //outputList->disable(OutputGenerator::Man); QCString pageName,manPageName; pageName = escapeCharsInString(name(),FALSE,TRUE); manPageName = escapeCharsInString(name(),TRUE,TRUE); //printf("PageDef::writeDocumentation: %s\n",getOutputFileBase().data()); ol.pushGeneratorState(); //1.{ if (m_nestingLevel>0 //&& // a sub page //(Doxygen::mainPage==0 || getOuterScope()!=Doxygen::mainPage) // and not a subpage of the mainpage ) { // do not generate sub page output for RTF and LaTeX, as these are // part of their parent page ol.disableAll(); ol.enable(OutputGenerator::Man); ol.enable(OutputGenerator::Html); } ol.pushGeneratorState(); //2.{ ol.disableAllBut(OutputGenerator::Man); startFile(ol,getOutputFileBase(),manPageName,title(),HLI_Pages,!generateTreeView); ol.enableAll(); ol.disable(OutputGenerator::Man); startFile(ol,getOutputFileBase(),pageName,title(),HLI_Pages,!generateTreeView); ol.popGeneratorState(); //2.} if (!generateTreeView) { if (getOuterScope()!=Doxygen::globalScope && !Config_getBool("DISABLE_INDEX")) { getOuterScope()->writeNavigationPath(ol); } ol.endQuickIndices(); } SectionInfo *si=Doxygen::sectionDict->find(name()); // save old generator state and write title only to Man generator ol.pushGeneratorState(); //2.{ ol.disableAllBut(OutputGenerator::Man); ol.startTitleHead(manPageName); ol.endTitleHead(manPageName, manPageName); if (si) { ol.generateDoc(docFile(),docLine(),this,0,si->title,TRUE,FALSE,0,TRUE,FALSE); ol.endSection(si->label,si->type); } ol.popGeneratorState(); //2.} // for Latex the section is already generated as a chapter in the index! ol.pushGeneratorState(); //2.{ ol.disable(OutputGenerator::Latex); ol.disable(OutputGenerator::RTF); ol.disable(OutputGenerator::Man); if (!title().isEmpty() && !name().isEmpty() && si!=0) { //ol.startSection(si->label,si->title,si->type); startTitle(ol,getOutputFileBase(),this); ol.generateDoc(docFile(),docLine(),this,0,si->title,TRUE,FALSE,0,TRUE,FALSE); //stringToSearchIndex(getOutputFileBase(), // theTranslator->trPage(TRUE,TRUE)+" "+si->title, // si->title); //ol.endSection(si->label,si->type); endTitle(ol,getOutputFileBase(),name()); } ol.startContents(); ol.popGeneratorState(); //2.} if (m_showToc && hasSections()) { writeToc(ol); } writePageDocumentation(ol); if (generateTreeView && getOuterScope()!=Doxygen::globalScope && !Config_getBool("DISABLE_INDEX")) { ol.endContents(); endFileWithNavPath(getOuterScope(),ol); } else { endFile(ol); } ol.popGeneratorState(); //1.} if (!Config_getString("GENERATE_TAGFILE").isEmpty()) { bool found = name()=="citelist"; QDictIterator<RefList> rli(*Doxygen::xrefLists); RefList *rl; for (rli.toFirst();(rl=rli.current()) && !found;++rli) { if (rl->listName()==name()) { found=TRUE; break; } } if (!found) // not one of the generated related pages { Doxygen::tagFile << " <compound kind=\"page\">" << endl; Doxygen::tagFile << " <name>" << name() << "</name>" << endl; Doxygen::tagFile << " <title>" << convertToXML(title()) << "</title>" << endl; Doxygen::tagFile << " <filename>" << getOutputFileBase() << "</filename>" << endl; writeDocAnchorsToTagFile(); Doxygen::tagFile << " </compound>" << endl; } } Doxygen::indexList->addIndexItem(this,0,0,filterTitle(title())); }
bool PageDef::hasParentPage() const { return getOuterScope() && getOuterScope()->definitionType()==Definition::TypePage; }
void PageDef::writeDocumentation(OutputList &ol) { static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW); //outputList->disable(OutputGenerator::Man); QCString pageName,manPageName; pageName = escapeCharsInString(name(),FALSE,TRUE); manPageName = escapeCharsInString(name(),TRUE,TRUE); //printf("PageDef::writeDocumentation: %s\n",getOutputFileBase().data()); ol.pushGeneratorState(); //1.{ if (m_nestingLevel>0 //&& // a sub page //(Doxygen::mainPage==0 || getOuterScope()!=Doxygen::mainPage) // and not a subpage of the mainpage ) { // do not generate sub page output for RTF and LaTeX, as these are // part of their parent page ol.disableAll(); ol.enable(OutputGenerator::Man); ol.enable(OutputGenerator::Html); } ol.pushGeneratorState(); //2.{ ol.disableAllBut(OutputGenerator::Man); startFile(ol,getOutputFileBase(),manPageName,title(),HLI_Pages,!generateTreeView); ol.enableAll(); ol.disable(OutputGenerator::Man); startFile(ol,getOutputFileBase(),pageName,title(),HLI_Pages,!generateTreeView); ol.popGeneratorState(); //2.} if (!generateTreeView) { if (getOuterScope()!=Doxygen::globalScope && !Config_getBool(DISABLE_INDEX)) { getOuterScope()->writeNavigationPath(ol); } ol.endQuickIndices(); } SectionInfo *si=Doxygen::sectionDict->find(name()); // save old generator state and write title only to Man generator ol.pushGeneratorState(); //2.{ ol.disableAllBut(OutputGenerator::Man); ol.startTitleHead(manPageName); ol.endTitleHead(manPageName, manPageName); if (si) { ol.generateDoc(docFile(),docLine(),this,0,si->title,TRUE,FALSE,0,TRUE,FALSE); ol.endSection(si->label,si->type); } ol.popGeneratorState(); //2.} // for Latex the section is already generated as a chapter in the index! ol.pushGeneratorState(); //2.{ ol.disable(OutputGenerator::Latex); ol.disable(OutputGenerator::RTF); ol.disable(OutputGenerator::Man); if (!title().isEmpty() && !name().isEmpty() && si!=0) { //ol.startSection(si->label,si->title,si->type); startTitle(ol,getOutputFileBase(),this); ol.generateDoc(docFile(),docLine(),this,0,si->title,TRUE,FALSE,0,TRUE,FALSE); //stringToSearchIndex(getOutputFileBase(), // theTranslator->trPage(TRUE,TRUE)+" "+si->title, // si->title); //ol.endSection(si->label,si->type); endTitle(ol,getOutputFileBase(),name()); } ol.startContents(); ol.popGeneratorState(); //2.} if (m_showToc && hasSections()) { writeToc(ol); } writeGeneratedFromFile(ol, this->getDefFileName()); writePageDocumentation(ol); if (generateTreeView && getOuterScope()!=Doxygen::globalScope && !Config_getBool(DISABLE_INDEX)) { ol.endContents(); endFileWithNavPath(getOuterScope(),ol); } else { endFile(ol); } ol.popGeneratorState(); //1.} Doxygen::indexList->addIndexItem(this,0,0,filterTitle(title())); }
void NamespaceDef::writeDocumentation(OutputList &ol) { QCString pageTitle; if (Config_getBool("OPTIMIZE_OUTPUT_JAVA")) { pageTitle = theTranslator->trPackage(displayName()); } else { pageTitle = theTranslator->trNamespaceReference(displayName()); } startFile(ol,getOutputFileBase(),name(),pageTitle,HLI_NamespaceVisible); if (getOuterScope()!=Doxygen::globalScope) { writeNavigationPath(ol); } startTitle(ol,getOutputFileBase()); ol.parseText(pageTitle); addGroupListToTitle(ol,this); endTitle(ol,getOutputFileBase(),displayName()); if (Config_getBool("SEARCHENGINE")) { Doxygen::searchIndex->setCurrentDoc(pageTitle,getOutputFileBase()); Doxygen::searchIndex->addWord(localName(),TRUE); } if (!Config_getString("GENERATE_TAGFILE").isEmpty()) { Doxygen::tagFile << " <compound kind=\"namespace\">" << endl; Doxygen::tagFile << " <name>" << convertToXML(name()) << "</name>" << endl; Doxygen::tagFile << " <filename>" << convertToXML(getOutputFileBase()) << Doxygen::htmlFileExtension << "</filename>" << endl; } ol.startTextBlock(); if (Config_getBool("DETAILS_AT_TOP")) { writeDetailedDocumentation(ol); ol.newParagraph(); } else if (!briefDescription().isEmpty()) { ol.parseDoc(briefFile(),briefLine(),this,0,briefDescription(),TRUE,FALSE); ol.writeString(" \n"); ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::Html); ol.startTextLink(0,"_details"); ol.parseText(theTranslator->trMore()); ol.endTextLink(); ol.enableAll(); ol.disableAllBut(OutputGenerator::Man); ol.newParagraph(); ol.popGeneratorState(); } ol.disable(OutputGenerator::Man); ol.newParagraph(); ol.enable(OutputGenerator::Man); ol.writeSynopsis(); ol.endTextBlock(); ol.startMemberSections(); classSDict->writeDeclaration(ol,0,0,TRUE); namespaceSDict->writeDeclaration(ol,TRUE); /* write user defined member groups */ MemberGroupSDict::Iterator mgli(*memberGroupSDict); MemberGroup *mg; for (;(mg=mgli.current());++mgli) { mg->writeDeclarations(ol,0,this,0,0); } //allMemberList.writeDeclarations(ol,0,this,0,0,0,0); decDefineMembers.writeDeclarations(ol,0,this,0,0,theTranslator->trDefines(),0); decProtoMembers.writeDeclarations(ol,0,this,0,0,theTranslator->trFuncProtos(),0); decTypedefMembers.writeDeclarations(ol,0,this,0,0,theTranslator->trTypedefs(),0); decEnumMembers.writeDeclarations(ol,0,this,0,0,theTranslator->trEnumerations(),0); decFuncMembers.writeDeclarations(ol,0,this,0,0,theTranslator->trFunctions(),0); decVarMembers.writeDeclarations(ol,0,this,0,0,theTranslator->trVariables(),0); ol.endMemberSections(); if (!Config_getBool("DETAILS_AT_TOP")) { writeDetailedDocumentation(ol); } writeMemberDocumentation(ol); // write Author section (Man only) ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::Man); ol.startGroupHeader(); ol.parseText(theTranslator->trAuthor(TRUE,TRUE)); ol.endGroupHeader(); ol.parseText(theTranslator->trGeneratedAutomatically(Config_getString("PROJECT_NAME"))); if (!Config_getString("GENERATE_TAGFILE").isEmpty()) { writeDocAnchorsToTagFile(); Doxygen::tagFile << " </compound>" << endl; } ol.popGeneratorState(); endFile(ol); if (Config_getBool("SEPARATE_MEMBER_PAGES")) { allMemberList.sort(); writeMemberPages(ol); } }
void NamespaceDef::writeDocumentation(OutputList &ol) { static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN"); static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW"); static bool outputJava = Config_getBool("OPTIMIZE_OUTPUT_JAVA"); QCString pageTitle; if (outputJava) { pageTitle = theTranslator->trPackage(displayName()); } else if (fortranOpt) { pageTitle = theTranslator->trModuleReference(displayName()); } else { pageTitle = theTranslator->trNamespaceReference(displayName()); } startFile(ol,getOutputFileBase(),name(),pageTitle,HLI_NamespaceVisible,!generateTreeView); if (!generateTreeView) { if (getOuterScope()!=Doxygen::globalScope) { writeNavigationPath(ol); } ol.endQuickIndices(); } startTitle(ol,getOutputFileBase(),this); ol.parseText(pageTitle,TRUE); addGroupListToTitle(ol,this); endTitle(ol,getOutputFileBase(),displayName()); ol.startContents(); if (Doxygen::searchIndex) { Doxygen::searchIndex->setCurrentDoc(pageTitle,getOutputFileBase()); Doxygen::searchIndex->addWord(localName(),TRUE); } bool generateTagFile = !Config_getString("GENERATE_TAGFILE").isEmpty(); if (generateTagFile) { Doxygen::tagFile << " <compound kind=\"namespace\">" << endl; Doxygen::tagFile << " <name>" << convertToXML(name()) << "</name>" << endl; Doxygen::tagFile << " <filename>" << convertToXML(getOutputFileBase()) << Doxygen::htmlFileExtension << "</filename>" << endl; } Doxygen::indexList.addIndexItem(this,0); //---------------------------------------- start flexible part ------------------------------- QListIterator<LayoutDocEntry> eli( LayoutDocManager::instance().docEntries(LayoutDocManager::Namespace)); LayoutDocEntry *lde; for (eli.toFirst();(lde=eli.current());++eli) { switch (lde->kind()) { case LayoutDocEntry::BriefDesc: writeBriefDescription(ol); break; case LayoutDocEntry::MemberDeclStart: startMemberDeclarations(ol); break; case LayoutDocEntry::NamespaceClasses: { LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; writeClassDeclarations(ol,ls->title); } break; case LayoutDocEntry::NamespaceNestedNamespaces: { LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; writeNamespaceDeclarations(ol,ls->title); } break; case LayoutDocEntry::MemberGroups: writeMemberGroups(ol); break; case LayoutDocEntry::MemberDecl: { LayoutDocEntryMemberDecl *lmd = (LayoutDocEntryMemberDecl*)lde; writeMemberDeclarations(ol,lmd->type,lmd->title); } break; case LayoutDocEntry::MemberDeclEnd: endMemberDeclarations(ol); break; case LayoutDocEntry::DetailedDesc: { LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; writeDetailedDescription(ol,ls->title); } break; case LayoutDocEntry::MemberDefStart: startMemberDocumentation(ol); break; case LayoutDocEntry::MemberDef: { LayoutDocEntryMemberDef *lmd = (LayoutDocEntryMemberDef*)lde; writeMemberDocumentation(ol,lmd->type,lmd->title); } break; case LayoutDocEntry::MemberDefEnd: endMemberDocumentation(ol); break; case LayoutDocEntry::AuthorSection: writeAuthorSection(ol); break; case LayoutDocEntry::ClassIncludes: case LayoutDocEntry::ClassInheritanceGraph: case LayoutDocEntry::ClassNestedClasses: case LayoutDocEntry::ClassCollaborationGraph: case LayoutDocEntry::ClassAllMembersLink: case LayoutDocEntry::ClassUsedFiles: case LayoutDocEntry::FileClasses: case LayoutDocEntry::FileNamespaces: case LayoutDocEntry::FileIncludes: case LayoutDocEntry::FileIncludeGraph: case LayoutDocEntry::FileIncludedByGraph: case LayoutDocEntry::FileSourceLink: case LayoutDocEntry::GroupClasses: case LayoutDocEntry::GroupInlineClasses: case LayoutDocEntry::GroupNamespaces: case LayoutDocEntry::GroupDirs: case LayoutDocEntry::GroupNestedGroups: case LayoutDocEntry::GroupFiles: case LayoutDocEntry::GroupGraph: case LayoutDocEntry::GroupPageDocs: case LayoutDocEntry::DirSubDirs: case LayoutDocEntry::DirFiles: case LayoutDocEntry::DirGraph: err("Internal inconsistency: member %d should not be part of " "LayoutDocManager::Namespace entry list\n",lde->kind()); break; } } //---------------------------------------- end flexible part ------------------------------- ol.endContents(); if (generateTreeView) { writeNavigationPath(ol); } endFile(ol,TRUE); if (generateTagFile) { writeDocAnchorsToTagFile(); Doxygen::tagFile << " </compound>" << endl; } if (Config_getBool("SEPARATE_MEMBER_PAGES")) { MemberList *allMemberList = getMemberList(MemberList::allMembersList); if (allMemberList) allMemberList->sort(); writeMemberPages(ol); } }