Example #1
0
void MainWindow::OnConverter(wxCommandEvent& event)
{
	int id = event.GetId();
	wxTreeItemId itemId = tree->GetSelection();
	NodeTree *itemData = itemId.IsOk() ? (NodeTree *) tree->GetItemData(itemId):NULL;
	Converter* conver;
	if(id == ID_CONVERMESH)
	{
		
		conver = new Converter(this,ID_CONVERMESH,wxT("CPP CODE"));
		conver->OnlyRead(itemData->pointer.meshpart);
		conver->ShowModal();
		wxLogStatus(wxT("See cpp code"));
		
	}
	if(id == ID_CONVER)
	{
		
		conver = new Converter(this,ID_CONVER,wxT("Converter .stl"));
		conver->ShowModal();
		wxLogStatus(wxT("Converter"));
	}

	delete conver;
}
Example #2
0
void bmx_wxlogstatus(BBString * message, wxFrame * frame) {
	if (frame) {
		wxLogStatus(frame, _("%s"), wxStringFromBBString(message).c_str());
	} else {
		wxLogStatus(_("%s"), wxStringFromBBString(message).c_str());
	}
}
Example #3
0
bool wxExViMacros::Expand(wxExEx* ex, const wxString& variable, wxString& value)
{
  std::map<wxString, wxExVariable>::iterator it = m_Variables.find(variable);
    
  bool ok;
    
  if (it == m_Variables.end())
  {
    std::pair<std::map<wxString, wxExVariable>::iterator, bool> ret = 
      m_Variables.insert(std::make_pair(variable, wxExVariable(variable)));
      
    wxLogStatus(_("Added variable") + ": "  +  variable);
    
    ok = ret.first->second.Expand(ex, value);
  
    // If we are expanding, one input is enough.    
    if (m_IsExpand)
    {
      ret.first->second.SkipInput();
    }
    
    if (ret.first->second.IsModified())
    {
      m_IsModified = true;
    }
  }
  else
  {
    ok = it->second.Expand(ex, value);

    // If we are expanding, one input is enough.    
    if (m_IsExpand)
    {
      it->second.SkipInput();
    }
  
    if (it->second.IsModified())
    {
      m_IsModified = true;
    }
  }
  
  if (!ok)
  {
    wxLogStatus(_("Could not expand variable") + ": "  +  variable);
  }
  else 
  {
    wxLogStatus(_("Variable expanded"));
  
    if (!m_IsRecording)
    {
      m_Macro = variable;
    }
  }
  
  return ok;
}
Example #4
0
void MyFrame::OnHangUp(wxCommandEvent& WXUNUSED(event))
{
    if ( wxGetApp().GetDialer()->HangUp() )
    {
        wxLogStatus(this, wxT("Connection was successfully terminated."));
    }
    else
    {
        wxLogStatus(this, wxT("Failed to hang up."));
    }
}
Example #5
0
 void DoNavigate(int flags)
 {
     if ( m_panel->NavigateIn(flags) )
     {
         wxLogStatus(this, wxT("Navigation event processed"));
     }
     else
     {
         wxLogStatus(this, wxT("Navigation event ignored"));
     }
 }
Example #6
0
bool wxExViMacros::Expand(wxExEx* ex, const wxString& variable)
{
  std::map<wxString, wxExVariable>::iterator it = m_Variables.find(variable);
  
  bool ok;
    
  if (it == m_Variables.end())
  {
    std::pair<std::map<wxString, wxExVariable>::iterator, bool> ret = 
      m_Variables.insert(std::make_pair(variable, wxExVariable(variable)));
      
    wxLogStatus(_("Added variable") + ": "  +  variable);
    
    ok = ret.first->second.Expand(ex);
  
    if (ret.first->second.IsModified())
    {
      m_IsModified = true;
    }
    
    // If ok is false, this is because expansion dialog was cancelled,
    // no need to show log status message.
  }
  else
  {
    ok = it->second.Expand(ex);
  
    if (it->second.IsModified())
    {
      m_IsModified = true;
    }

    // Now only show log status if this is no input variable,
    // as it was cancelled in that case.    
    if (!ok && !it->second.IsInput())
    {
      wxLogStatus(_("Could not expand variable") + ": "  +  variable);
    }
  }

  if (ok)
  {
    wxLogStatus(_("Variable expanded"));
  
    if (!m_IsRecording)
    {
      m_Macro = variable;
    }
  }
  
  return ok;
}  
Example #7
0
void wxExViMacros::StartRecording(const std::string& macro)
{
  if (m_IsRecording || macro.empty())
  {
    return;
  }
  
  m_IsRecording = true;
  m_IsModified = true;
  
  if (macro.size() == 1)
  {
    // We only use lower case macro's, to be able to
    // append to them using.
    m_Macro = macro;
    std::transform(m_Macro.begin(), m_Macro.end(), m_Macro.begin(), ::tolower);
  
    // Clear macro if it is lower case
    // (otherwise append to the macro).
    if (wxIslower(macro[0]))
    {
      m_Macros[m_Macro].clear();
    }
  }
  else
  {
    m_Macro = macro;
    m_Macros[m_Macro].clear();
  }
  
  wxExFrame::StatusText(m_Macro, "PaneMacro");
  
  wxLogStatus(_("Macro recording"));
}
Example #8
0
int OpenWaveFile2(const char *path)
/*********************************/
{
	// Set the length of 0x7fffffff for --stdout
	// This will be changed to the correct length for -w (write to file)
	static unsigned char wave_hdr[44] = {
		'R','I','F','F',0,0,0,0,'W','A','V','E','f','m','t',' ',
		0x10,0,0,0,1,0,1,0,  9,0x3d,0,0,0x12,0x7a,0,0,
		2,0,0x10,0,'d','a','t','a',  0xff,0xff,0xff,0x7f};

	if(path == NULL)
		return(2);

	if(strcmp(path,"stdout")==0)
		f_wave = stdout;
	else
		f_wave = fopen(path,"wb");

	if(f_wave != NULL)
	{
		fwrite(wave_hdr,1,24,f_wave);
		Write4Bytes(f_wave,samplerate);
		Write4Bytes(f_wave,samplerate * 2);
		fwrite(&wave_hdr[32],1,12,f_wave);
		return(0);
	}
	wxLogStatus(_T("Can't write to WAV file: '"+wxString(path,wxConvLocal))+_T("'"));
	return(1);
}   //  end of OpenWaveFile
Example #9
0
void RegTreeCtrl::OnItemExpanding(wxTreeEvent& event)
{
    TreeNode *pNode = GetNode(event);
    bool bExpanding = event.GetEventType() == wxEVT_TREE_ITEM_EXPANDING;

    // expansion might take some time
    wxSetCursor(*wxHOURGLASS_CURSOR);
    wxLogStatus(wxT("Working..."));
    wxYield();  // to give the status line a chance to refresh itself
    m_restoreStatus = true;   // some time later...

    if ( pNode->IsKey() )
    {
        if ( bExpanding )
        {
            // expanding: add subkeys/values
            if ( !pNode->OnExpand() )
                return;
        }
        else
        {
            // collapsing: clean up
            pNode->OnCollapse();
        }
    }
}
Example #10
0
bool wxExFile::FileSave(const wxExFileName& filename)
{
  bool save_as = false;

  if (filename.IsOk())
  {
    Assign(filename);
    MakeAbsolute();
    save_as = true;
  }

  if (!save_as && !m_IsLoaded)
  {
    wxLogStatus("File has not been loaded");
    return false;
  }

  if (m_OpenFile && !Open(m_FileName.GetFullPath(), wxFile::write))
  {
    return false;
  }

  DoFileSave(save_as);

  Close();

  ResetContentsChanged();
  
  m_FileName.m_Stat.Sync();
  m_Stat.Sync();

  return true;
}
Example #11
0
void wxExFrameWithHistory::OnCommandConfigDialog(
  wxWindowID dialogid,
  int commandid)
{
  switch (commandid)
  {
    case wxID_CANCEL:
      if (wxExDir::GetIsBusy())
      {
        wxExDir::Cancel();
        wxLogStatus(_("Cancelled"));
      }
      break;

    case wxID_OK:
      switch (dialogid)
      {
        case wxID_ADD:
          GetProject()->AddItems();
          break;

        case ID_FIND_IN_FILES:
        case ID_REPLACE_IN_FILES:
          FindInFiles(dialogid);
          break;

        default: wxFAIL;
      }
      break;

    default: wxFAIL;
  }
}
Example #12
0
void wxExFrameWithHistory::FindInFiles(wxWindowID dialogid)
{
  const bool replace = (dialogid == ID_REPLACE_IN_FILES);
  const wxExTool tool =
    (replace ?
       ID_TOOL_REPORT_REPLACE:
       ID_TOOL_REPORT_FIND);

  if (!wxExTextFileWithListView::SetupTool(tool, this))
  {
    return;
  }

  wxLogStatus(
    wxExFindReplaceData::Get()->GetFindReplaceInfoText(replace));
    
  int flags = wxDIR_FILES | wxDIR_HIDDEN;
  
  if (wxConfigBase::Get()->ReadBool(m_TextRecursive, true)) 
  {
    flags |= wxDIR_DIRS;
  }

  wxExDirTool dir(
    tool,
    wxExConfigFirstOf(m_TextInFolder),
    wxExConfigFirstOf(m_TextInFiles),
    flags);

  dir.FindFiles();

  tool.Log(&dir.GetStatistics().GetElements());
}
Example #13
0
void wxExSTCFile::DoFileLoad(bool synced)
{
  if (GetContentsChanged())
  {
    wxExFileDialog dlg(m_STC, this);
    if (dlg.ShowModalIfChanged() == wxID_CANCEL) return;
  }

  // Synchronizing by appending only new data only works for log files.
  // Other kind of files might get new data anywhere inside the file,
  // we cannot sync that by keeping pos. 
  // Also only do it for reasonably large files.
  ReadFromFile(
    synced &&
    GetFileName().GetExt().CmpNoCase("log") == 0 &&
    m_STC->GetTextLength() > 1024);

  m_STC->SetLexer(GetFileName().GetLexer().GetScintillaLexer(), true);

  if (!synced)
  {
    wxLogStatus(_("Opened") + ": " + GetFileName().GetFullPath());
  }
  
  m_STC->PropertiesMessage(synced ? STAT_SYNC: STAT_DEFAULT);

  // No edges for log files.
  if (GetFileName().GetExt() == "log")
  {
    m_STC->SetEdgeMode(wxSTC_EDGE_NONE);
  }
}
Example #14
0
void MyFrame::OnThumbnail( wxCommandEvent &WXUNUSED(event) )
{
#if wxUSE_FILEDLG
    wxString filename = wxLoadFileSelector(wxT("image"), wxEmptyString, wxEmptyString, this);
    if ( filename.empty() )
        return;

    static const int THUMBNAIL_WIDTH = 320;
    static const int THUMBNAIL_HEIGHT = 240;

    wxImage image;
    image.SetOption(wxIMAGE_OPTION_MAX_WIDTH, THUMBNAIL_WIDTH);
    image.SetOption(wxIMAGE_OPTION_MAX_HEIGHT, THUMBNAIL_HEIGHT);

    wxStopWatch sw;
    if ( !image.LoadFile(filename) )
    {
        wxLogError(wxT("Couldn't load image from '%s'."), filename.c_str());
        return;
    }

    int origWidth = image.GetOptionInt( wxIMAGE_OPTION_ORIGINAL_WIDTH );
    int origHeight = image.GetOptionInt( wxIMAGE_OPTION_ORIGINAL_HEIGHT );

    const long loadTime = sw.Time();

    MyImageFrame * const frame = new MyImageFrame(this, filename, image);
    wxLogStatus(frame, "Loaded \"%s\" in %ldms; original size was (%d, %d)",
                filename, loadTime, origWidth, origHeight);
#else
    wxLogError( wxT("Couldn't create file selector dialog") );
    return;
#endif // wxUSE_FILEDLG
}
Example #15
0
void gravUtil::logStatus( const char* str, ... )
{
    va_list args;
    va_start( args, str );
    wxLogStatus( getWXStringFromArgs( str, args ) );
    va_end( args );
}
Example #16
0
void HtMainFrame::OnJumpHexTextEnter (wxCommandEvent &event)
{
   auto *cbxPtr = dynamic_cast<wxComboBox *>(event.GetEventObject());
   wxString addressStr = cbxPtr->GetValue();

   wxLogStatus("[HtMainFrame] ::OnJumpHexTextEnter (%s)", addressStr);
}
Example #17
0
void MyFrame::OnAbout(wxCommandEvent& event)
{//=========================================
	int result;
	char buf[300];
	wxString url_docs;

	wxBoxSizer *topsizer;
	HtmlWindow *html;
	wxDialog dlg(this, wxID_ANY, wxString(_("About")));

	topsizer = new wxBoxSizer(wxVERTICAL);

	switch(event.GetId())
	{
	case MENU_ABOUT:
		{
		sprintf(buf,about_string,espeak_Info(NULL));
		html = new HtmlWindow(&dlg, wxID_ANY, wxDefaultPosition, wxSize(380, 160), wxHW_SCROLLBAR_NEVER);
		html -> SetBorders(0);
		html -> SetPage(wxString(buf,wxConvLocal));
		html -> SetSize(html -> GetInternalRepresentation() -> GetWidth(),
								html -> GetInternalRepresentation() -> GetHeight());

		topsizer -> Add(html, 1, wxALL, 10);

//#if wxUSE_STATLINE
//		topsizer -> Add(new wxStaticLine(&dlg, wxID_ANY), 0, wxEXPAND | wxLEFT | wxRIGHT, 10);
//#endif // wxUSE_STATLINE

		wxButton *bu1 = new wxButton(&dlg, wxID_OK, _("OK"));
		bu1 -> SetDefault();

		topsizer -> Add(bu1, 0, wxALL | wxALIGN_RIGHT, 15);

		dlg.SetSizer(topsizer);
		topsizer -> Fit(&dlg);

		dlg.ShowModal();
		}
		break;

	case MENU_DOCS:
		strcpy(buf,"/docs/docindex.html");
		url_docs = wxGetCwd() +  wxString(buf,wxConvLocal);  // look for "docs" in the current directory
		if(!wxFileExists(url_docs))
		{
			strcpy(buf,"http://espeak.sourceforge.net/docindex.html");
			url_docs = wxString(buf,wxConvLocal);
		}
		else
		{
			url_docs = _T("file://") + url_docs;
		}

		result = wxLaunchDefaultBrowser(url_docs);
		if(result == 0)
			wxLogStatus(_T("Failed to launch default browser: "+url_docs));
		break;
	}
}
Example #18
0
MyFrame::MyFrame()
       : wxFrame(NULL, wxID_ANY, wxT("wxWidgets OpenGL Cube Sample"))
{
    new TestGLCanvas(this);

    SetIcon(wxICON(sample));

    // Make a menubar
    wxMenu *menu = new wxMenu;
    menu->Append(wxID_NEW);
    menu->AppendSeparator();
    menu->Append(wxID_CLOSE);
    wxMenuBar *menuBar = new wxMenuBar;
    menuBar->Append(menu, wxT("&Cube"));

    SetMenuBar(menuBar);

    CreateStatusBar();

    SetClientSize(400, 400);
    Show();

    // test IsDisplaySupported() function:
    static const int attribs[] = { WX_GL_RGBA, WX_GL_DOUBLEBUFFER, 0 };
    wxLogStatus("Double-buffered display %s supported",
                wxGLCanvas::IsDisplaySupported(attribs) ? "is" : "not");
}
Example #19
0
void MyFrame::OnReloadResourceMenuCommand(wxCommandEvent& WXUNUSED(event))
{
    if ( wxXmlResource::Get()->Load(wxT("rc/basicdlg.xrc")) )
        wxLogStatus(_T("Basic dialog resource has been loaded."));
    else
        wxLogError(_T("Failed to load basic dialog resource"));
}
Example #20
0
void MyFrame::OnSetStatusField(wxCommandEvent& WXUNUSED(event))
{
    wxStatusBar *sb = GetStatusBar();
    if (!sb)
        return;

    long rc = wxGetNumberFromUser
              (
                "Configure the field index to be used by the set, push "
                "and pop text commands in the menu.\n"
                "\n"
                "0 corresponds to the first field, 1 to the second one "
                "and so on.",
                "Field &index:",
                SAMPLE_DIALOGS_TITLE,
                m_field,
                0,
                sb->GetFieldsCount() - 1,
                NULL
              );

    if ( rc == -1 )
        return;

    m_field = rc;

    wxLogStatus("Status bar text will be set for field #%d", m_field);
}
Example #21
0
void MySplitterWindow::OnPositionChanging(wxSplitterEvent& event)
{
    wxLogStatus(m_frame, wxT("Position is changing, now = %d (or %d)"),
                event.GetSashPosition(), GetSashPosition());

    event.Skip();
}
void GammaTransMI::calcMax(wxUint32 eventMax)
{
	static const wxDouble range = 8 * GAMMA_EVENT_UNIT;

	wxDouble sigma = m_eventMaxTable.size();
	wxDouble sigmaX = 0, sigmaY = 0;
	wxDouble sigmaXX = 0, sigmaXY = 0, sigmaYY = 0;

	for(wxUint32 x = 0; x < m_eventMaxTable.size(); x++)
	{
		sigmaX += x;
		sigmaY += m_eventMaxTable[x];
		sigmaXX += x * x;
		sigmaXY += x * m_eventMaxTable[x];
		sigmaYY += m_eventMaxTable[x]* m_eventMaxTable[x];
	}

	wxDouble delta = sigma * sigmaXX - sigmaX * sigmaX;
	wxDouble a = (sigma * sigmaXY - sigmaX * sigmaY ) / delta;
	wxDouble b = (sigmaXX * sigmaY - sigmaX * sigmaXY) / delta;

	//wxDouble stdDev = sqrt(sigmaYY - a * sigmaXY - b * sigmaY);
	wxDouble y = a * (m_eventMaxTable.size() - 1) + b;

	if(y - range < eventMax && eventMax < y + range)
	{
		if(64 <= m_eventMaxTable.size())
		{
			m_eventMaxTable.pop_front();
		}
		m_max = y;
		wxLogStatus("%s eventMax = %u max = %f", __FUNCTION__, 
			eventMax / GAMMA_EVENT_UNIT, m_max / GAMMA_EVENT_UNIT);
	}
	else
	{
		while(1 < m_eventMaxTable.size())
		{
			m_eventMaxTable.pop_front();
		}
		m_max = eventMax;
		wxLogStatus("%s eventMax = %u max = %f (clear)", __FUNCTION__, 
			eventMax / GAMMA_EVENT_UNIT, m_max / GAMMA_EVENT_UNIT);
	}

	m_eventMaxTable.push_back(eventMax);
}
Example #23
0
void MyFrame::OnRequestUserAttention(wxCommandEvent& WXUNUSED(event))
{
    wxLogStatus(_T("Sleeping for 3 seconds to allow you to switch to another window"));

    wxSleep(3);

    RequestUserAttention(wxUSER_ATTENTION_ERROR);
}
Example #24
0
 void UpdateStatusBar()
 {
     wxLogStatus(this, wxT("Image size: (%d, %d), zoom %.2f"),
                 m_bitmap.GetWidth(),
                 m_bitmap.GetHeight(),
                 m_zoom);
     Refresh();
 }
Example #25
0
void MyFrame::OnDial(wxCommandEvent& WXUNUSED(event))
{
    wxLogStatus(this, wxT("Preparing to dial..."));
    wxYield();
    wxBeginBusyCursor();

    if ( wxGetApp().GetDialer()->Dial() )
    {
        wxLogStatus(this, wxT("Dialing..."));
    }
    else
    {
        wxLogStatus(this, wxT("Dialing attempt failed."));
    }

    wxEndBusyCursor();
}
bool GammaBlockUSB::deviceFind()
{
#if defined(_MSC_VER) && defined(GAMMA_USB_CYAPI)
	for( m_device = 0; m_device < m_usbDevice->DeviceCount(); m_device++ ) {
		m_usbDevice->Open(m_device);
		
		if(m_usbDevice->VendorID == GAMMA_VID && m_usbDevice->ProductID == GAMMA_PID) {
			break;
		}
	}
	
	if(m_device < m_usbDevice->DeviceCount()) {
		wxLogStatus("Device found (VID_%04X&PID_%04X).", 
			m_usbDevice->VendorID, m_usbDevice->ProductID);
		return true;
	}
	else {
		wxLogStatus("No device found.");
		return false;
	}
#else
	// Before any communication can occur with a device, it needs to be found. 
	// This is accomplished by finding all of the busses and then finding all of
	// the devices on all of the busses:
	usb_init();
	usb_find_busses();
	usb_find_devices();

	// After this, the application should manually loop through all of the 
	// busess and all of the devices and matching the device by whatever 
	// criteria is needed:
	for (struct usb_bus* iBus = usb_get_busses(); iBus; iBus = iBus->next) {
		for (struct usb_device* iDev = iBus->devices; iDev; iDev = iDev->next) {
			/* Check if this device is a printer */
			if (iDev->descriptor.idVendor == GAMMA_VID && iDev->descriptor.idProduct == GAMMA_PID) {
				/* Open the device, claim the interface and do your processing */
				m_usbDevice = usb_open(iDev);
				return true;
			}
		}
	}
	return false;
#endif
}
void GammaNemaCalc::floodFill(wxPoint start, wxUint32 colour)
{
	wxUint32 threshold = m_pDataIn->eventMax() * 0;//2/4;

	std::list<wxPoint> queue;

	if(threshold < m_pDataIn->matrix[POINT(start.x,start.y)])
	{
		wxLogStatus("Wrong parameters!");
		return;
	}

	queue.push_back(start);

	while(!queue.empty())
	{
		wxPoint w(queue.back()), e(queue.back());
		queue.pop_back();

		while( (0 <= w.x-1) && (m_pDataIn->matrix[POINT(w.x-1, w.y)] < threshold) )
		{
			w.x--;
		}

		while( (e.x+1 <= 255) && (m_pDataIn->matrix[POINT(e.x+1, e.y)] < threshold) )
		{
			e.x++;
		}
		
		for(wxPoint n(w); n.x <= e.x; n.x++)
		{
			m_pDataIn->matrix[POINT(n.x, n.y)] = wxUINT32_MAX;

			if( (0 <= n.y-1) && (m_pDataIn->matrix[POINT(n.x, n.y-1)] < threshold) )
			{
				queue.push_back(wxPoint(n.x, n.y-1));
			}

			if( (n.y+1 <= 255) && (m_pDataIn->matrix[POINT(n.x, n.y+1)] < threshold) )
			{
				queue.push_back(wxPoint(n.x, n.y+1));
			}
		}
	}

	for(wxUint32 y = 0; y <= 255; y++)
	{
		for(wxUint32 x = 0; x <= 255; x++)
		{
			if(wxUINT32_MAX == m_pDataIn->matrix[POINT(x,y)])
			{
				m_pDataIn->matrix[POINT(x,y)] = colour;
			}
		}
	}
}
Example #28
0
wxDragResult MMessagesDropTarget::OnMsgDrop(wxCoord x, wxCoord y,
                                            MMessagesDataObject *data,
                                            wxDragResult def)
{
   MFolder_obj folder(m_where->GetFolder(x, y));
   if ( !folder )
   {
      wxLogStatus(GetFrame(),
                  _("No folder under cursor, messages not dropped."));

      return wxDragNone;
   }

   if ( !CanCreateMessagesInFolder(folder->GetType()) )
   {
      wxLogStatus(GetFrame(), _("Can't drop messages to this folder."));

      return wxDragNone;
   }

   UIdArray messages = data->GetMessages();

   MsgCmdProc *msgCmdProc = data->GetMsgCmdProc();

   // TODO: check here if the folder can be written to?

   // check that we are not copying to the same folder
   if ( msgCmdProc->GetFolderName() == folder->GetFullName() )
   {
      wxLogStatus(GetFrame(), _("Can't drop messages to the same folder."));

      return wxDragNone;
   }

   msgCmdProc->ProcessCommand(WXMENU_MSG_DROP_TO_FOLDER, messages, folder);

   // it's ok even if m_frame is NULL
   const unsigned long count = messages.GetCount();
   wxLogStatus(GetFrame(), _("%lu message(s) dropped."), count);
   m_where->Refresh();

   return def;
}
Example #29
0
wxDragResult
MMessagesDropTargetBase::OnEnter(wxCoord x, wxCoord y, wxDragResult def)
{
   if ( GetFrame() )
   {
      wxLogStatus(GetFrame(), _("You can drop mail messages here."));
   }

   return OnDragOver(x, y, def);
}
Example #30
0
void wxStfChildFrame::OnMenuHighlight(wxMenuEvent& event) {
    if (this->GetMenuBar()) {
        wxMenuItem *item = this->GetMenuBar()->FindItem(event.GetId());
        if(item) {
            wxLogStatus(item->GetHelp());
        }
    }
    event.Skip();

}