本文整理汇总了C++中QProcess::isRunning方法的典型用法代码示例。如果您正苦于以下问题:C++ QProcess::isRunning方法的具体用法?C++ QProcess::isRunning怎么用?C++ QProcess::isRunning使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类QProcess
的用法示例。
在下文中一共展示了QProcess::isRunning方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: launchArgonneViz
/** Special case to launch a viz on Argonne's cluster
* this will always render to multicast
*/
void Gridifier::launchArgonneViz(const LauncherConfig &config){
QProcess *launchArgonneVizProcess = new QProcess(QString("./argonneVis.sh"));
launchArgonneVizProcess->setWorkingDirectory(mScriptsDir);
launchArgonneVizProcess->addArgument(config.visualizationGSH.mEPR);
launchArgonneVizProcess->addArgument(QString::number(config.mTimeToRun));
launchArgonneVizProcess->addArgument(config.multicastAddress);
QString vizTypeStr = "";
if (config.vizType == isosurface){
vizTypeStr = "iso";
}
else if (config.vizType == volumeRender){
vizTypeStr = "vol";
}
if (config.vizType == hedgehog){
vizTypeStr = "hog";
}
else if (config.vizType == cutPlane){
vizTypeStr = "cut";
}
launchArgonneVizProcess->addArgument(vizTypeStr);
cout << launchArgonneVizProcess->arguments().join(" ") << endl;
launchArgonneVizProcess->start();
while (launchArgonneVizProcess->isRunning()){
usleep(10000);
mApplication->processEvents();
}
cout << "Stdout:" << endl << launchArgonneVizProcess->readStdout() << endl;
if (launchArgonneVizProcess->canReadLineStderr())
cout << "Stderr:" << endl << launchArgonneVizProcess->readStderr() << endl;
}
示例2: setServiceData
/** Calls setServiceData on the specified service using the
second argument as the basis for the argument to setServiceData.
(The <ogsi:setByServiceDataNames> tags are added in this
routine.) */
void Gridifier::setServiceData(const QString &nameSpace,
const QString &gsh,
const QString &sdeText){
QString arg("<ogsi:setByServiceDataNames>");
arg.append(sdeText);
arg.append("</ogsi:setByServiceDataNames>");
QProcess *setServiceDataProcess = new QProcess(QString("./setServiceData.pl"));
setServiceDataProcess->setWorkingDirectory(mScriptsDir);
setServiceDataProcess->addArgument(nameSpace);
setServiceDataProcess->addArgument(gsh);
setServiceDataProcess->addArgument(arg);
setServiceDataProcess->start();
while (setServiceDataProcess->isRunning()){
usleep(10000);
mApplication->processEvents();
}
if(setServiceDataProcess->canReadLineStdout()){
cout << "Stdout:" << endl << setServiceDataProcess->readStdout() << endl;
}
if (setServiceDataProcess->canReadLineStderr()){
cout << "Stderr:" << endl << setServiceDataProcess->readStderr() << endl;
}
}
示例3: launchVizScript
/** Method calls appropriate xxx_launch.sh script to
* actually launch the visualization job on the target machine
*/
int Gridifier::launchVizScript(const QString &scriptConfigFileName,
const LauncherConfig &config){
// Construct name of script from name of application
QProcess *launchVizScriptProcess = new QProcess(QString("./"+config.mAppToLaunch->mAppName+"_launch.sh"));
launchVizScriptProcess->setWorkingDirectory(mScriptsDir);
launchVizScriptProcess->addArgument(scriptConfigFileName);
launchVizScriptProcess->addArgument(QString::number(config.mTimeToRun));
launchVizScriptProcess->start();
while (launchVizScriptProcess->isRunning()){
usleep(10000);
mApplication->processEvents();
}
if (launchVizScriptProcess->canReadLineStdout()){
QString out(launchVizScriptProcess->readStdout());
cout << "Stdout:" << endl << out << endl;
if(out.contains("ERROR")){
return REG_FAILURE;
}
}
if (launchVizScriptProcess->canReadLineStderr()){
QString out(launchVizScriptProcess->readStderr());
cout << "Stderr:" << endl << out << endl;
if(out.contains("ERROR")){
return REG_FAILURE;
}
}
return REG_SUCCESS;
}
示例4: makeSGSFactory
//---------------------------------------------------------------
QString Gridifier::makeSGSFactory(const QString &container,
const QString &topLevelRegistry,
const QString &className){
QString result;
QProcess *makeSGSFactoryProcess = new QProcess(QString("./make_" +
className +
"_factory.pl"));
makeSGSFactoryProcess->setWorkingDirectory(mScriptsDir);
makeSGSFactoryProcess->addArgument(container);
makeSGSFactoryProcess->addArgument(topLevelRegistry);
cout << makeSGSFactoryProcess->arguments().join(" ") << endl;
makeSGSFactoryProcess->start();
while (makeSGSFactoryProcess->isRunning()){
usleep(10000);
mApplication->processEvents();
}
// this functionality is left in a seperate slot since it could be better
// to allow the standard qt events to handle it, rather than sitting in the
// above loop
result = QString(makeSGSFactoryProcess->readStdout()).stripWhiteSpace();
return result;
}
示例5: ready
void Tmpl::ready()
{
for (QValueList<TmplExpand>::iterator it = tmpls.begin(); it != tmpls.end(); ++it){
QProcess *p = (*it).process;
if (p && !p->isRunning()){
if (p->normalExit() && p->exitStatus() == 0){
(*it).bReady = true;
(*it).res += QString::fromLocal8Bit(p->readStdout());
QTimer::singleShot(0, this, SLOT(clear()));
return;
}
}
}
}
示例6: checkPointAndStop
/** Instructs the simulation associated with the specified SGS
to take a checkpoint and then stop. This call blocks until
job has stopped or a time-out occurs. */
QString Gridifier::checkPointAndStop(const QString &sgsGSH){
QProcess *checkPointAndStopProcess = new QProcess(QString("./checkpoint_and_stop.pl"));
checkPointAndStopProcess->setWorkingDirectory(mScriptsDir);
checkPointAndStopProcess->addArgument(sgsGSH);
checkPointAndStopProcess->start();
while (checkPointAndStopProcess->isRunning()){
usleep(10000);
mApplication->processEvents();
}
QString result = checkPointAndStopProcess->readStdout();
return result;
}
示例7: apply
//====================================
// apply keyboard
//------------------------------------
void SCCKeyboard::apply ( void ) {
if (mKeyboardTab->isVisible()) {
qApp->setOverrideCursor ( Qt::forbiddenCursor );
QString layoutApply = mKeyboardLayout -> getApplyString();
QString optionApply = mKeyboardOptions -> getApplyString();
QString complete = "setxkbmap " + layoutApply + " " + optionApply;
QProcess* proc = new QProcess ();
proc -> setArguments ( QStringList::split( " ",complete) );
if ( ! proc -> start() ) {
qApp->restoreOverrideCursor();
return;
}
while (proc->isRunning()) {
usleep (1000);
}
qApp->restoreOverrideCursor();
}
}
示例8: webServiceJobSubmit
/**
* Method calls lb3d_client.pl script to call web service
* to actually launch the job on the target machine
*/
void Gridifier::webServiceJobSubmit(const QString & scriptConfigFileName){
// Construct name of script from name of application
QProcess *launchSimScriptProcess = new QProcess(QString("./lb3d_client.pl"));
launchSimScriptProcess->setWorkingDirectory(mScriptsDir);
launchSimScriptProcess->addArgument(scriptConfigFileName);
launchSimScriptProcess->start();
while (launchSimScriptProcess->isRunning()){
usleep(10000);
mApplication->processEvents();
}
cout << "Stdout:" << endl << launchSimScriptProcess->readStdout() << endl;
if (launchSimScriptProcess->canReadLineStderr())
cout << "Stderr:" << endl << launchSimScriptProcess->readStderr() << endl;
}
示例9: makeMetaSGS
/** Create a MetaSGS */
QString Gridifier::makeMetaSGS(const QString &factory,
const LauncherConfig &config,
const QString &parentGSH){
QString result;
QProcess *makeSimSGSProcess = new QProcess(QString("./make_msgs.pl"));
makeSimSGSProcess->setWorkingDirectory(mScriptsDir);
makeSimSGSProcess->addArgument(factory);
// the tag is handled correctly if it contains spaces - thanks QT!
makeSimSGSProcess->addArgument(config.mJobData->toXML(QString("MetaSGS")));
makeSimSGSProcess->addArgument(config.topLevelRegistryGSH);
makeSimSGSProcess->addArgument(config.currentCheckpointGSH);
makeSimSGSProcess->addArgument(config.mInputFileName);
makeSimSGSProcess->addArgument(QString::number(config.mTimeToRun));
makeSimSGSProcess->addArgument(parentGSH);
if (config.treeTag.length() > 0){
makeSimSGSProcess->addArgument(config.treeTag);
makeSimSGSProcess->addArgument(config.checkPointTreeFactoryGSH);
}
makeSimSGSProcess->start();
while(makeSimSGSProcess->isRunning()){
usleep(10000);
mApplication->processEvents();
}
// Grab the sgs and return it
// Do some error checking here - or in the calling class?
result = QString(makeSimSGSProcess->readStdout()).stripWhiteSpace();
cout << "Stdout:" << endl << result << endl;
if (makeSimSGSProcess->canReadLineStderr())
cout << "Stderr:" << endl << makeSimSGSProcess->readStderr() << endl;
return result;
}
示例10: setPassword
//====================================
// setPassword
//------------------------------------
void SaXManipulateVNC::setPassword (const QString& pwd) {
// .../
//! restricted access can be set up by creating a
//! password file. This file is set within the rfbauth
//! option. This method is used to create the password
//! file by using the vncpasswd program
// ----
if (! setLock()) {
return;
}
QProcess* proc = new QProcess ();
proc -> addArgument ( SAX_CREATE_VNC_PWD );
proc -> addArgument ( pwd );
if ( ! proc -> start() ) {
excProcessFailed();
qError (errorString(),EXC_PROCESSFAILED);
unsetLock();
return;
}
while (proc->isRunning()) {
usleep (1000);
}
unsetLock();
}
示例11: getSGSFactories
/** The following static methods wrap around QProcess objects to
* run the reg_perl_launcher scripts. Ultimately replace with
* code that uses an API to perform the same function programatically.
*/
QString Gridifier::getSGSFactories(const QString &topLevelRegistry,
const QString &desiredContainer,
const QString &className){
QString result;
QProcess *getSGSFactoriesProcess = new QProcess(QString("./get_" +
className +
"_factories.pl"));
getSGSFactoriesProcess->setWorkingDirectory(mScriptsDir);
getSGSFactoriesProcess->addArgument(topLevelRegistry);
getSGSFactoriesProcess->start();
// At this point we need to wait for the process to complete.
// Clearly this isn't ideal - hence the desire to replace this with API calls.
// An alternative is to send the result back via a QT event....
// for the time being stick with this slightly naff approach
while (getSGSFactoriesProcess->isRunning()){
// don't sit in an exhaustive loop - waste of electricity :)
usleep(10000);
// and keep the gui updated
mApplication->processEvents();
}
// this functionality is left in a seperate slot since it could be better
// to allow the standard qt events to handle it, rather than sitting in the
// above loop
//result = getSGSFactoriesProcessEnded(desiredContainer);
QString allFactories = getSGSFactoriesProcess->readStdout();
if (allFactories.length() == 0){
// then no SGS Factories exist - so create one - actually do this elsewhere
result = "";
}
else {
QStringList factories = QStringList::split("\n", allFactories);
int numFactories = factories.size();
// prune the list - remove any factories not on the desired container
for (int i=0; i<numFactories; i++){
if (!factories[i].contains(desiredContainer)){
factories.erase(factories.at(i));
numFactories = factories.size();
// undo the increment since we've removed an element
i--;
}
}
// if there's no factories left - return the blank string
if (numFactories <= 0)
result = "";
// choose a factory at random
int randomNum = rand();
randomNum = (int)((randomNum / (float)RAND_MAX) * numFactories);
QString randomFactory = factories[randomNum];
result = randomFactory;
}
return result;
}
示例12: makeVizSGS
//---------------------------------------------------------------
QString Gridifier::makeVizSGS(const QString &factory,
const LauncherConfig &config){
QString result;
#ifndef REG_WSRF
QProcess *makeVizSGSProcess = new QProcess(QString("./make_vis_sgs.pl"));
makeVizSGSProcess->setWorkingDirectory(mScriptsDir);
makeVizSGSProcess->addArgument(factory);
makeVizSGSProcess->addArgument(config.mJobData->toXML(QString("SGS")));
makeVizSGSProcess->addArgument(config.topLevelRegistryGSH);
makeVizSGSProcess->addArgument(config.simulationGSH.mEPR);
makeVizSGSProcess->addArgument(QString::number(config.mTimeToRun));
makeVizSGSProcess->start();
while (makeVizSGSProcess->isRunning()){
usleep(10000);
mApplication->processEvents();
}
if(makeVizSGSProcess->canReadLineStdout()){
result = QString(makeVizSGSProcess->readStdout());
cout << "stdout: " << result << endl;
}
else{
cout << "Full line of stdout unavailable" << endl;
}
if(makeVizSGSProcess->canReadLineStderr()){
cout << "stderr: " << QString(makeVizSGSProcess->readStderr()) << endl;
}
else{
cout << "Full line of stderr unavailable" << endl;
}
result = QString(makeVizSGSProcess->readStdout()).stripWhiteSpace();
#else // REG_WSRF is defined
char purpose[1024];
char proxyAddress[1024];
int proxyPort;
char iodef_label[256];
char *ioTypes;
struct soap mySoap;
char *EPR;
struct msg_struct *msg;
xmlDocPtr doc;
xmlNsPtr ns;
xmlNodePtr cur;
struct io_struct *ioPtr;
int i, count;
struct reg_job_details job;
/* Obtain the IOTypes from the data source */
soap_init(&mySoap);
if( Get_resource_property (&mySoap,
config.simulationGSH.mEPR.ascii(),
config.simulationGSH.mSecurity.userDN,
config.simulationGSH.mSecurity.passphrase,
"ioTypeDefinitions",
&ioTypes) != REG_SUCCESS ){
cout << "Call to get ioTypeDefinitions ResourceProperty on "<<
config.simulationGSH.mEPR << " failed" << endl;
return result;
}
cout << "Got ioTypeDefinitions >>" << ioTypes << "<<" << endl;
if( !(doc = xmlParseMemory(ioTypes, strlen(ioTypes))) ||
!(cur = xmlDocGetRootElement(doc)) ){
fprintf(stderr, "Hit error parsing buffer\n");
xmlFreeDoc(doc);
xmlCleanupParser();
return result;
}
ns = xmlSearchNsByHref(doc, cur,
(const xmlChar *) "http://www.realitygrid.org/xml/steering");
if ( xmlStrcmp(cur->name, (const xmlChar *) "ioTypeDefinitions") ){
cout << "ioTypeDefinitions not the root element" << endl;
return result;
}
/* Step down to ReG_steer_message and then to IOType_defs */
cur = cur->xmlChildrenNode->xmlChildrenNode;
msg = New_msg_struct();
msg->msg_type = IO_DEFS;
msg->io_def = New_io_def_struct();
parseIOTypeDef(doc, ns, cur, msg->io_def);
Print_msg(msg);
if(!(ioPtr = msg->io_def->first_io) ){
fprintf(stderr, "Got no IOType definitions from data source\n");
return result;
}
i = 0;
printf("Available IOTypes:\n");
while(ioPtr){
if( !xmlStrcmp(ioPtr->direction, (const xmlChar *)"OUT") ){
//.........这里部分代码省略.........
示例13: exportData
//====================================
// exportData
//------------------------------------
bool SCCTablet::exportData ( void ) {
//====================================
// create manipulators...
//------------------------------------
SaXManipulateTablets saxTablet (
mSection["Pointers"],mSection["Layout"]
);
SaXManipulateDevices saxDevice (
mSection["Pointers"],mSection["Layout"]
);
//====================================
// search and remove tablet
//------------------------------------
int inputCount = mSection["Pointers"]->getCount();
for (int i=inputCount;i>=0;i--) {
if (saxTablet.selectPointer (i)) {
if (saxTablet.isTablet()) {
saxDevice.removeInputDevice (i);
}
if (saxTablet.isPen()) {
saxDevice.removeInputDevice (i);
}
if (saxTablet.isEraser()) {
saxDevice.removeInputDevice (i);
}
}
}
//====================================
// add tablet if enabled
//------------------------------------
if (mTabletSelection->isEnabled()) {
QString vendor = mTabletSelection->getVendor();
QString model = mTabletSelection->getModel();
if (! model.isEmpty()) {
int tabletID = saxDevice.addInputDevice (SAX_INPUT_TABLET);
saxTablet.selectPointer ( tabletID );
saxTablet.setTablet ( vendor,model );
QDict<QString> tabletDict = saxTablet.getTabletData (
vendor,model
);
//====================================
// save tablet connection port
//------------------------------------
if (! mTabletConnection->isAutoPort()) {
QString port = mTabletConnection->getPortName();
if (port.contains ("ttyS0")) {
saxTablet.setDevice ( "/dev/ttyS0" );
}
if (port.contains ("ttyS1")) {
saxTablet.setDevice ( "/dev/ttyS1" );
}
if (port.contains ("USB")) {
QProcess* proc = new QProcess ();
proc -> addArgument ( USB_PORT );
if (proc -> start()) {
while (proc->isRunning()) {
usleep (1000);
}
QByteArray data = proc->readStdout();
QStringList lines = QStringList::split ("\n",data);
saxTablet.setDevice ( lines.first() );
}
}
}
//====================================
// save tablet options
//------------------------------------
QString driver = saxTablet.getDriver();
QDict<QString> allOptions = saxTablet.getTabletOptions ( driver );
QDictIterator<QString> it (allOptions);
for (; it.current(); ++it) {
saxTablet.removeOption (it.currentKey());
}
QDict<QString> tabletOptions = mTabletConnection->getOptions();
QDictIterator<QString> io (tabletOptions);
for (; io.current(); ++io) {
saxTablet.addOption (io.currentKey(),*io.current());
}
//====================================
// save tablet mode
//------------------------------------
int mode = mTabletConnection->getTabletMode();
if (mode == 0) {
saxTablet.setMode ("Relative");
} else {
saxTablet.setMode ("Absolute");
}
int sticks[2] = {-1,-1};
//====================================
// handle Tablet Pen
//------------------------------------
if (mTabletPens->hasPen()) {
QString penLink = *tabletDict["StylusLink"];
sticks[0] = saxTablet.addPen ( vendor,penLink );
}
//====================================
// handle Tablet Eraser
//.........这里部分代码省略.........
示例14: printReportToPDF
//.........这里部分代码省略.........
proc->addArgument(QString("-r%1").arg(dpi_));
switch ((QPrinter::PageSize) report->pageSize()) {
case QPrinter::A0:
proc->addArgument("-sPAPERSIZE=a0");
break;
case QPrinter::A1:
proc->addArgument("-sPAPERSIZE=a1");
break;
case QPrinter::A2:
proc->addArgument("-sPAPERSIZE=a2");
break;
case QPrinter::A3:
proc->addArgument("-sPAPERSIZE=a3");
break;
case QPrinter::A4:
proc->addArgument("-sPAPERSIZE=a4");
break;
case QPrinter::A5:
proc->addArgument("-sPAPERSIZE=a5");
break;
case QPrinter::B0:
proc->addArgument("-sPAPERSIZE=b0");
break;
case QPrinter::B1:
proc->addArgument("-sPAPERSIZE=b1");
break;
case QPrinter::B2:
proc->addArgument("-sPAPERSIZE=b2");
break;
case QPrinter::B3:
proc->addArgument("-sPAPERSIZE=b3");
break;
case QPrinter::B4:
proc->addArgument("-sPAPERSIZE=b4");
break;
case QPrinter::B5:
proc->addArgument("-sPAPERSIZE=b5");
break;
case QPrinter::Legal:
proc->addArgument("-sPAPERSIZE=legal");
break;
case QPrinter::Letter:
proc->addArgument("-sPAPERSIZE=letter");
break;
case QPrinter::Executive:
proc->addArgument("-sPAPERSIZE=executive");
break;
default: {
QSize sz(report->pageDimensions());
proc->addArgument(QString("-dDEVICEWIDTHPOINTS=%1").arg(sz.width()));
proc->addArgument(QString("-dDEVICEHEIGHTPOINTS=%1").arg(sz.height()));
}
}
proc->addArgument("-dAutoRotatePages=/PageByPage");
proc->addArgument("-dUseCIEColor");
proc->addArgument("-sOutputFile=" + outPdfFile);
proc->addArgument("-sDEVICE=pdfwrite");
proc->addArgument(outPsFile);
if (!proc->start()) {
delete proc;
return false;
}
while (proc->isRunning())
qApp->processEvents();
delete proc;
qApp->processEvents();
/**
proc = new QProcess();
proc->addArgument(gs);
proc->addArgument("-q");
proc->addArgument("-dBATCH");
proc->addArgument("-dNOPAUSE");
proc->addArgument("-dSAFER");
proc->addArgument("-dNODISPLAY");
proc->addArgument("-dDELAYSAFER");
proc->addArgument("--");
proc->addArgument("pdfopt.ps"); //Obsoleto desde gs 9.07
proc->addArgument(outPsPdfFile);
proc->addArgument(outPdfFile);
if (!proc->start()) {
delete proc;
return false;
}
while (proc->isRunning())
qApp->processEvents();
delete proc;
qApp->processEvents();
**/
return true;
}
示例15: printGhostReport
//.........这里部分代码省略.........
stream << " (mswinpr2) finddevice" << "\n";
stream << " putdeviceprops" << "\n";
stream << "setdevice" << "\n";
if ((QPrinter::PageSize) report->pageSize() == QPrinter::Custom) {
QSize sz(report->pageDimensions());
stream << QString("<< /PageSize [%1 %2] /ImagingBBox null >> setpagedevice")
.arg(sz.width())
.arg(sz.height())
<< "\n";
}
fileSetup.close();
}
proc->addArgument(aqApp->gsExecutable());
proc->addArgument("-q");
proc->addArgument("-dBATCH");
proc->addArgument("-dNOPAUSE");
proc->addArgument("-dNODISPLAY");
proc->addArgument(QString("-r%1").arg(dpi_));
switch ((QPrinter::PageSize) report->pageSize()) {
case QPrinter::A0:
proc->addArgument("-sPAPERSIZE=a0");
break;
case QPrinter::A1:
proc->addArgument("-sPAPERSIZE=a1");
break;
case QPrinter::A2:
proc->addArgument("-sPAPERSIZE=a2");
break;
case QPrinter::A3:
proc->addArgument("-sPAPERSIZE=a3");
break;
case QPrinter::A4:
proc->addArgument("-sPAPERSIZE=a4");
break;
case QPrinter::A5:
proc->addArgument("-sPAPERSIZE=a5");
break;
case QPrinter::B0:
proc->addArgument("-sPAPERSIZE=b0");
break;
case QPrinter::B1:
proc->addArgument("-sPAPERSIZE=b1");
break;
case QPrinter::B2:
proc->addArgument("-sPAPERSIZE=b2");
break;
case QPrinter::B3:
proc->addArgument("-sPAPERSIZE=b3");
break;
case QPrinter::B4:
proc->addArgument("-sPAPERSIZE=b4");
break;
case QPrinter::B5:
proc->addArgument("-sPAPERSIZE=b5");
break;
case QPrinter::Legal:
proc->addArgument("-sPAPERSIZE=legal");
break;
case QPrinter::Letter:
proc->addArgument("-sPAPERSIZE=letter");
break;
case QPrinter::Executive:
proc->addArgument("-sPAPERSIZE=executive");
break;
default: {
QSize sz(report->pageDimensions());
proc->addArgument(QString("-dDEVICEWIDTHPOINTS=%1").arg(sz.width()));
proc->addArgument(QString("-dDEVICEHEIGHTPOINTS=%1").arg(sz.height()));
}
}
proc->addArgument(setupPsFile);
proc->addArgument(outPsFile);
}
if (!proc->start()) {
delete proc;
return false;
}
//QProgressDialog *pd = new QProgressDialog(tr("Enviando a impresora..."), QString::null, 10000, this, tr("sendprintprogress"), true );
//int step = 0;
//QApplication::setOverrideCursor(Qt::WaitCursor);
while (proc->isRunning()) {
//pd->setProgress(step++);
qApp->processEvents();
//if (step == 9999)
// step = 0;
}
//QApplication::restoreOverrideCursor();
delete proc;
//delete pd;
qApp->processEvents();
return true;
}