コード例 #1
0
ファイル: console.c プロジェクト: mingpen/OpenNT
BOOL
consolePutMouse(
    ROW     Row,
    COLUMN  Col,
    DWORD   MouseFlags
    )
/*++

Routine Description:

    Puts a mose event in the console's input buffer

Arguments:

    Row 	-   Supplies the row
    Col 	-   Supplies the column
    MouseFlags	-   Supplies the flags

Return Value:

    TRUE if key put, false otherwise

--*/
{

    INPUT_RECORD    InputRecord;
    COORD	    Position;
    DWORD	    Flags;

    InputRecord.EventType   =	MOUSE_EVENT;

    Position.Y = (WORD)(Row - 1);
    Position.X = (WORD)(Col - 1);

    Flags = 0;

    if ( MouseFlags & MOUSE_CLICK_LEFT ) {
	Flags |= FROM_LEFT_1ST_BUTTON_PRESSED;
    }
    if ( MouseFlags & MOUSE_CLICK_RIGHT ) {
	Flags |= RIGHTMOST_BUTTON_PRESSED;
    }
    if ( MouseFlags & MOUSE_DOUBLE_CLICK ) {
	Flags |= DOUBLE_CLICK;
    }

    InputRecord.Event.MouseEvent.dwMousePosition    =	Position;
    InputRecord.Event.MouseEvent.dwButtonState	    =	Flags;
    InputRecord.Event.MouseEvent.dwControlKeyState  =	0;
    InputRecord.Event.MouseEvent.dwEventFlags	    =	0;

    return PutEvent( &InputRecord );
}
コード例 #2
0
 MIDITrack::MIDITrack( const MIDITrack &t )	
 {
   buf_size=0;
   num_events=0;
   
   
   for( int i=0; i<t.GetNumEvents(); ++i )
   {
     const MIDITimedBigMessage *src;
     src = t.GetEventAddress( i );
     PutEvent(*src);
   }
 } 
コード例 #3
0
ファイル: console.c プロジェクト: mingpen/OpenNT
BOOL
consolePutKey (
    PKBDKEY     Key
    )
/*++

Routine Description:

    Puts a key in the console's input buffer

Arguments:

    Key     -	Supplies a pointer to a key structure

Return Value:

    TRUE if key put, false otherwise

--*/
{

    INPUT_RECORD    InputRecord;

    InputRecord.EventType   =	KEY_EVENT;

    InputRecord.Event.KeyEvent.bKeyDown 	  =   FALSE;
    InputRecord.Event.KeyEvent.wRepeatCount	  =   0;
    InputRecord.Event.KeyEvent.wVirtualKeyCode	  =   Key->Scancode;
    InputRecord.Event.KeyEvent.wVirtualScanCode   =   0;
    InputRecord.Event.KeyEvent.uChar.UnicodeChar  =   Key->Unicode;
    InputRecord.Event.KeyEvent.dwControlKeyState  =   Key->Flags;

    if ( PutEvent( &InputRecord )) {
	InputRecord.Event.KeyEvent.bKeyDown	  =   TRUE;
	return PutEvent( &InputRecord );
    }
    return FALSE;
}
コード例 #4
0
ファイル: webtrv.cpp プロジェクト: Accio/snap
/////////////////////////////////////////////////
// Web-Travel-Yahoo-Se
TWebTravelYahooSe::TWebTravelYahooSe(const TXWebTravelMode& Mode,
 const PXWebTravelEvent& Event):
  TXWebTravel(),
  DfFPath(TStr::GetNrFPath("Yahoo")),
  StartUrlStr("http://www.yahoo.se"){
  PXWebBs WebBs;
  switch (Mode){
    case wtmStart: WebBs=PXWebBs(new TWebMemBs(100, DfFPath, false)); break;
    case wtmCont: WebBs=PXWebBs(new TWebMemBs(DfFPath, false)); break;
    case wtmCheck: WebBs=PXWebBs(new TWebMemBs(DfFPath, true)); break;
    default: Fail;
  }
  PutWebBs(WebBs);
  PutEvent(Event);
}
コード例 #5
0
ファイル: webtrv.cpp プロジェクト: Accio/snap
/////////////////////////////////////////////////
// Web-Travel-Test
TWebTravelTest::TWebTravelTest(const TXWebTravelMode& Mode,
 const PXWebTravelEvent& Event):
  TXWebTravel(),
  DfFPath(TStr::GetNrFPath("../test")),
  StartUrlStr("http://www.mf.uni-lj.si/"){
  PXWebBs WebBs;
  switch (Mode){
    case wtmStart: WebBs=PXWebBs(new TWebMemBs(10, DfFPath, false)); break;
    case wtmCont: WebBs=PXWebBs(new TWebMemBs(DfFPath, false)); break;
    case wtmCheck: WebBs=PXWebBs(new TWebMemBs(DfFPath, true)); break;
    default: Fail;
  }
  PutWebBs(WebBs);
  PutEvent(Event);
}
コード例 #6
0
ファイル: webtrv.cpp プロジェクト: Accio/snap
TWebTravelCia::TWebTravelCia(const TXWebTravelMode& Mode,
 const PXWebTravelEvent& Event):
  TXWebTravel(),
  DfFPath(TStr::GetNrFPath("Cia")),
  StartUrlStr("http://www.odci.gov/cia/publications/nsolo/factbook/global.htm"){
  PXWebBs WebBs;
  switch (Mode){
    case wtmStart: WebBs=PXWebBs(new TWebMemBs(10, DfFPath, false)); break;
    case wtmCont: WebBs=PXWebBs(new TWebMemBs(DfFPath, false)); break;
    case wtmCheck: WebBs=PXWebBs(new TWebMemBs(DfFPath, true)); break;
    default: Fail;
  }
  PutWebBs(WebBs);
  PutEvent(Event);
}
コード例 #7
0
ファイル: webtrv.cpp プロジェクト: Accio/snap
/////////////////////////////////////////////////
// Web-Travel-ARTFL-Roget
TWebTravelRogetARTFL::TWebTravelRogetARTFL(const TXWebTravelMode& Mode,
 const PXWebTravelEvent& Event):
  TXWebTravel(),
  DfFPath(TStr::GetNrFPath("RogetARTFL")),
  StartUrlStr("http://humanities.uchicago.edu/biblio/roget_headwords.html"){
  PXWebBs WebBs;
  switch (Mode){
    case wtmStart: WebBs=PXWebBs(new TWebMemBs(3, DfFPath, false)); break;
    case wtmCont: WebBs=PXWebBs(new TWebMemBs(DfFPath, false)); break;
    case wtmCheck: WebBs=PXWebBs(new TWebMemBs(DfFPath, true)); break;
    default: Fail;
  }
  PutWebBs(WebBs);
  PutEvent(Event);
}
コード例 #8
0
ファイル: webtrv.cpp プロジェクト: Accio/snap
/////////////////////////////////////////////////
// Web-Travel-CmuPww
TWebTravelCmuPww::TWebTravelCmuPww(
 const TXWebTravelMode& Mode, const PXWebTravelEvent& Event,
 const TStr& _InFNm, const TStr& _OutFPath):
  TXWebTravel(),
  InFNm(_InFNm),
  OutFPath(TStr::GetNrFPath(_OutFPath)){
  PXWebBs WebBs;
  switch (Mode){
    case wtmStart: WebBs=PXWebBs(new TWebMemBs(10, OutFPath, false)); break;
    case wtmCont: WebBs=PXWebBs(new TWebMemBs(OutFPath, false)); break;
    case wtmCheck: WebBs=PXWebBs(new TWebMemBs(OutFPath, true)); break;
    default: Fail;
  }
  PutWebBs(WebBs);
  PutEvent(Event);
}
コード例 #9
0
ファイル: console.c プロジェクト: mingpen/OpenNT
BOOL
consoleEnterCancelEvent (
    )
{

    INPUT_RECORD    Record;
    DWORD           dw;

    Record.EventType = KEY_EVENT;
    Record.Event.KeyEvent.bKeyDown            = TRUE;
    Record.Event.KeyEvent.wRepeatCount	      = 0;
    Record.Event.KeyEvent.wVirtualKeyCode     = VK_CANCEL;
    Record.Event.KeyEvent.wVirtualScanCode    = 0;
    Record.Event.KeyEvent.uChar.AsciiChar     = 0;
    Record.Event.KeyEvent.dwControlKeyState   = 0;

    PutEvent( &Record );

    Record.Event.KeyEvent.bKeyDown = TRUE;
    WriteConsoleInput( hInput, &Record, 1, &dw );

    return TRUE;
}
コード例 #10
0
/* midiInputHandler - Low-level callback function to handle MIDI input.
 *      Installed by midiInOpen().  The input handler takes incoming
 *      MIDI events and places them in the circular input buffer.  It then
 *      notifies the application by posting a MM_MIDIINPUT message.
 *
 *      This function is accessed at interrupt time, so it should be as 
 *      fast and efficient as possible.  You can't make any
 *      Windows calls here, except PostMessage().  The only Multimedia
 *      Windows call you can make are timeGetSystemTime(), midiOutShortMsg().
 *      
 *
 * Param:   hMidiIn - Handle for the associated input device.
 *          wMsg - One of the MIM_***** messages.
 *          dwInstance - Points to CALLBACKINSTANCEDATA structure.
 *          dwParam1 - MIDI data.
 *          dwParam2 - Timestamp (in milliseconds)
 *
 * Return:  void
 */     
void FAR PASCAL midiInputHandler(
HMIDIIN hMidiIn, 
WORD wMsg, 
DWORD dwInstance, 
DWORD dwParam1, 
DWORD dwParam2)
{
    EVENT event;
    
    switch(wMsg)
    {
        case MIM_OPEN:
            break;

        /* The only error possible is invalid MIDI data, so just pass
         * the invalid data on so we'll see it.
         */
        case MIM_ERROR:
        case MIM_DATA:
            event.fdwEvent = (wMsg == MIM_ERROR) ? EVNT_F_ERROR : 0;
            event.dwDevice = ((LPCALLBACKINSTANCEDATA)dwInstance)->dwDevice;
            event.data = dwParam1;
#ifdef MIDI_TIMESTAMP
            event.timestamp = timeGetSystemTime();
#endif
            /* Put the MIDI event in the circular input buffer.
             */

            PutEvent(((LPCALLBACKINSTANCEDATA)dwInstance)->lpBuf,
                       (LPEVENT) &event); 

            break;

        default:
            break;
    }
}
コード例 #11
0
 void	MIDITrack::ClearAndMerge(
   const MIDITrack *src1,
   const MIDITrack *src2
   )
 {
   Clear();
   
   const MIDITimedBigMessage *ev1;
   int cur_trk1ev=0;
   int num_trk1ev = src1->GetNumEvents();
   
   const MIDITimedBigMessage *ev2;
   int cur_trk2ev=0;
   int num_trk2ev = src2->GetNumEvents();
   
   MIDIClockTime last_data_end_time=0;
   
   while(
     cur_trk1ev<num_trk1ev
     || cur_trk2ev<num_trk2ev
     )
   {
     // skip any NOPs on track 1
     
     ev1=src1->GetEventAddress( cur_trk1ev );
     ev2=src2->GetEventAddress( cur_trk2ev );
     
     bool has_ev1 = (cur_trk1ev<num_trk1ev) && ev1;
     bool has_ev2 = (cur_trk2ev<num_trk2ev) && ev2;
     
     if( has_ev1 && ev1->IsNoOp() )
     {
       cur_trk1ev++;
       continue;
     }
     
     // skip any NOPs on track 2
     
     if( has_ev2 && ev2->IsNoOp() )
     {
       cur_trk2ev++;
       continue;
     }
     
     // skip all data end
     
     if( has_ev1 && ev1->IsDataEnd() )
     {
       if( ev1->GetTime() > last_data_end_time )
       {
         last_data_end_time = ev1->GetTime();
       }
       cur_trk1ev++;
       continue;
     }
     
     if( has_ev2 && ev2->IsDataEnd() )
     {
       if( ev2->GetTime() > last_data_end_time )
       {
         last_data_end_time = ev2->GetTime();
       }
       cur_trk2ev++;
       continue;
     }
     
     if( (has_ev1 && !has_ev2) )
     {
       // nothing left on trk 2
       
       if( !ev1->IsNoOp())
       {
         if( ev1->GetTime() > last_data_end_time )
         {
           last_data_end_time = ev1->GetTime();
         }
         
         PutEvent( *ev1 );
         ++cur_trk1ev;
       }
     } else if( (!has_ev1 && has_ev2) )
     {
       // nothing left on trk 1
       if( !ev2->IsNoOp() )
       {
         PutEvent( *ev2 );
         ++cur_trk2ev;
       }
     } else if( has_ev1 && has_ev2 )
     {
       int trk=1;
       
       if( (ev1->GetTime() <= ev2->GetTime()) )
       {
         trk=1;
       }
       else
       {
         trk=2;
       }
       
       if( trk==1 )
       {
         if( ev1->GetTime() > last_data_end_time )
         {
           last_data_end_time = ev1->GetTime();
         }
         
         PutEvent( *ev1 );
         
         ++cur_trk1ev;
       }
       else
       {
         if( ev2->GetTime() > last_data_end_time )
         {
           last_data_end_time = ev2->GetTime();
         }
         
         PutEvent( *ev2 );
         ++cur_trk2ev;
       }
     }
   }
   
   // put single final data end event
   
   MIDITimedBigMessage dataend;
   
   dataend.SetTime( last_data_end_time );
   dataend.SetDataEnd();
   
   PutEvent( dataend );
 }
コード例 #12
0
ファイル: filelist.c プロジェクト: weihualiu/sdbc
/* file_list: server */
int filels(T_Connect *conn,T_NetHead *NetHead)
{
	char *buff,*env,*p;
	char *p1;
	char tmp[1000],dir[512],tmp1[2000];
	FILE *fd;
	int ret;
	char buffer[SDBC_BLKSZ];
	int Event_no=NetHead->PROTO_NUM;
	if(!NetHead->PKG_LEN) {
		ShowLog(1,"getlist what to list?");
		NetHead->ERRNO1=-1;
		errret:
		NetHead->PROTO_NUM=PutEvent(conn,Event_no);
		NetHead->data=0;
		NetHead->PKG_LEN=0;
		NetHead->ERRNO2=-1;
		NetHead->PKG_REC_NUM=0;
		NetHead->O_NODE=LocalAddr(conn->Socket,0);
		NetHead->D_NODE=0;
		ret=SendPack(conn,NetHead);
		return 0;
	}
	buff=malloc(NetHead->PKG_LEN+200);
	if(!buff) {
		NetHead->ERRNO1=-2;
		goto errret;
	}
	strcpy(buff,NetHead->data);
//ShowLog(5,"errno2=%d %s",NetHead->ERRNO2,buff);
	if(!strncmp(buff,"$/",2)) {
		env=getenv("SENDDIR");
		p=buff+1;
	} else if(!strncmp(buff,"@/",2)) {
		env=getenv("HOME");
		p=buff+1;
	} else if(*buff=='$') {
		p=stptok(buff+1,tmp,sizeof(tmp),"/");
		env=getenv(tmp);
	} else {
		p=buff;
	}

	if(p>buff) {
		if(!env||!*env) env=".";
		if(env[strlen(env)-1]=='/') env[strlen(env)-1]=0;
		strcpy(tmp,env);
//ShowLog(5,"%s:env=%s,buff=%s",__FUNCTION__,env,buff);
		strsubst(buff,p-buff,tmp);
	}
	ShowLog(5,"filelist:path=%s",buff);
	sprintf(tmp,"ls %s",buff);
	if(isdir(buff)>0) strcpy(dir,buff);
	else {
		p1=strrchr(buff,'/');
		if(p1) {
			*p1=0;
			strcpy(dir,buff);
		} else strcpy(dir,".");
	}
	if(dir[strlen(dir)-1]=='/') dir[strlen(dir)-1]=0;
	fd=popen(tmp,"r");
	if(!fd) {
		ShowLog(1,"%s:err=%d",tmp,errno);
		free(buff);
		NetHead->ERRNO1=errno;
		goto errret;
	}
//ShowLog(5,"tmp=%s",tmp);
	p=buffer;
	*p=0;
	while((ret=fscanf(fd,"%s",tmp))==1) {
		if(*buffer==0 && tmp[strlen(tmp)-1] == ':') {//没找到
			break;
		}
		p1=sc_basename(tmp);
		ret=sprintf(tmp1,"%s/%s",dir,p1);
		if(isrfile(tmp1)<=0) continue; //not readble reg file
/* send tmp1 to client */
		if((int)(buffer+sizeof(buffer)-2-p)>ret) {
			p=stpcpy(p,tmp1);
		} else {
//ShowLog(5,"%s",buffer);
			NetHead->PROTO_NUM=0;
			NetHead->data=buffer;
			NetHead->PKG_LEN=strlen(NetHead->data);
			NetHead->ERRNO2= PACK_CONTINUE;
			NetHead->O_NODE=LocalAddr(conn->Socket,0);
			NetHead->D_NODE=0;
			ret=SendPack(conn,NetHead);
			if(ret) break;
			p=buffer;
			p=stpcpy(p,tmp1);
			*p++ = ' ';
			*p=0;
		}
	}
	pclose(fd);
	if(*buffer) {
//ShowLog(5,"final %s",buffer);
		NetHead->PROTO_NUM=0;
		NetHead->data=buffer;
		NetHead->PKG_LEN=strlen(NetHead->data);
		NetHead->ERRNO2= PACK_CONTINUE;
		NetHead->O_NODE=LocalAddr(conn->Socket,0);
		ret=SendPack(conn,NetHead);
		*buffer=0;
	}
	NetHead->PROTO_NUM=PutEvent(conn,Event_no);
	NetHead->data=0;
	NetHead->PKG_LEN=0;
	NetHead->ERRNO2=0;
	NetHead->PKG_REC_NUM=0;
	NetHead->O_NODE=LocalAddr(conn->Socket,0);
	NetHead->D_NODE=0;
	ret=SendPack(conn,NetHead);
	free(buff);
	return 0;
}
コード例 #13
0
ファイル: load.c プロジェクト: jurchik/project6014
BOOLEAN
LoadGame (COUNT which_game, SUMMARY_DESC *SummPtr)
{
	uio_Stream *in_fp;
	char file[PATH_MAX];
	char buf[256];
	SUMMARY_DESC loc_sd;
	GAME_STATE_FILE *fp;
	DECODE_REF fh;
	COUNT num_links;
	STAR_DESC SD;
	ACTIVITY Activity;

	sprintf (file, "starcon2.%02u", which_game);
	in_fp = res_OpenResFile (saveDir, file, "rb");
	if (!in_fp)
		return FALSE;

	if (!LoadSummary (&loc_sd, in_fp))
	{
		log_add (log_Error, "Warning: Savegame is corrupt");
		res_CloseResFile (in_fp);
		return FALSE;
	}

	if (!SummPtr)
	{
		SummPtr = &loc_sd;
	}
	else
	{	// only need summary for displaying to user
		memcpy (SummPtr, &loc_sd, sizeof (*SummPtr));
		res_CloseResFile (in_fp);
		return TRUE;
	}

	// Crude check for big-endian/little-endian incompatibilities.
	// year_index is suitable as it's a multi-byte value within
	// a specific recognisable range.
	if (SummPtr->year_index < START_YEAR ||
			SummPtr->year_index >= START_YEAR +
			YEARS_TO_KOHRAH_VICTORY + 1 /* Utwig intervention */ +
			1 /* time to destroy all races, plenty */ +
			25 /* for cheaters */)
	{
		log_add (log_Error, "Warning: Savegame corrupt or from "
				"an incompatible platform.");
		res_CloseResFile (in_fp);
		return FALSE;
	}

	GlobData.SIS_state = SummPtr->SS;

	if ((fh = copen (in_fp, FILE_STREAM, STREAM_READ)) == 0)
	{
		res_CloseResFile (in_fp);
		return FALSE;
	}

	ReinitQueue (&GLOBAL (GameClock.event_q));
	ReinitQueue (&GLOBAL (encounter_q));
	ReinitQueue (&GLOBAL (ip_group_q));
	ReinitQueue (&GLOBAL (npc_built_ship_q));
	ReinitQueue (&GLOBAL (built_ship_q));

	memset (&GLOBAL (GameState[0]), 0, sizeof (GLOBAL (GameState)));
	Activity = GLOBAL (CurrentActivity);
	LoadGameState (&GlobData.Game_state, fh);
	NextActivity = GLOBAL (CurrentActivity);
	GLOBAL (CurrentActivity) = Activity;

	LoadRaceQueue (fh, &GLOBAL (avail_race_q));
	// START_INTERPLANETARY is only set when saving from Homeworld
	//   encounter screen. When the game is loaded, the
	//   GenerateOrbitalFunction for the current star system will
	//   create the encounter anew and populate the npc queue.
	if (!(NextActivity & START_INTERPLANETARY))
	{
		if (NextActivity & START_ENCOUNTER)
			LoadShipQueue (fh, &GLOBAL (npc_built_ship_q));
		else if (LOBYTE (NextActivity) == IN_INTERPLANETARY)
			// XXX: Technically, this queue does not need to be
			//   saved/loaded at all. IP groups will be reloaded
			//   from group state files. But the original code did,
			//   and so will we until we can prove we do not need to.
			LoadGroupQueue (fh, &GLOBAL (ip_group_q));
		else
			// XXX: The empty queue read is only needed to maintain
			//   the savegame compatibility
			LoadEmptyQueue (fh);
	}
	LoadShipQueue (fh, &GLOBAL (built_ship_q));

	// Load the game events (compressed)
	cread_16 (fh, &num_links);
	{
#ifdef DEBUG_LOAD
		log_add (log_Debug, "EVENTS:");
#endif /* DEBUG_LOAD */
		while (num_links--)
		{
			HEVENT hEvent;
			EVENT *EventPtr;

			hEvent = AllocEvent ();
			LockEvent (hEvent, &EventPtr);

			LoadEvent (EventPtr, fh);

#ifdef DEBUG_LOAD
		log_add (log_Debug, "\t%u/%u/%u -- %u",
				EventPtr->month_index,
				EventPtr->day_index,
				EventPtr->year_index,
				EventPtr->func_index);
#endif /* DEBUG_LOAD */
			UnlockEvent (hEvent);
			PutEvent (hEvent);
		}
	}

	// Load the encounters (black globes in HS/QS (compressed))
	cread_16 (fh, &num_links);
	{
		while (num_links--)
		{
			HENCOUNTER hEncounter;
			ENCOUNTER *EncounterPtr;

			hEncounter = AllocEncounter ();
			LockEncounter (hEncounter, &EncounterPtr);

			LoadEncounter (EncounterPtr, fh);

			UnlockEncounter (hEncounter);
			PutEncounter (hEncounter);
		}
	}

	// Copy the star info file from the compressed stream
	fp = OpenStateFile (STARINFO_FILE, "wb");
	if (fp)
	{
		DWORD flen;

		cread_32 (fh, &flen);
		while (flen)
		{
			COUNT num_bytes;

			num_bytes = flen >= sizeof (buf) ? sizeof (buf) : (COUNT)flen;
			cread (buf, num_bytes, 1, fh);
			WriteStateFile (buf, num_bytes, 1, fp);

			flen -= num_bytes;
		}
		CloseStateFile (fp);
	}

	// Copy the defined groupinfo file from the compressed stream
	fp = OpenStateFile (DEFGRPINFO_FILE, "wb");
	if (fp)
	{
		DWORD flen;

		cread_32 (fh, &flen);
		while (flen)
		{
			COUNT num_bytes;

			num_bytes = flen >= sizeof (buf) ? sizeof (buf) : (COUNT)flen;
			cread (buf, num_bytes, 1, fh);
			WriteStateFile (buf, num_bytes, 1, fp);

			flen -= num_bytes;
		}
		CloseStateFile (fp);
	}

	// Copy the random groupinfo file from the compressed stream
	fp = OpenStateFile (RANDGRPINFO_FILE, "wb");
	if (fp)
	{
		DWORD flen;

		cread_32 (fh, &flen);
		while (flen)
		{
			COUNT num_bytes;

			num_bytes = flen >= sizeof (buf) ? sizeof (buf) : (COUNT)flen;
			cread (buf, num_bytes, 1, fh);
			WriteStateFile (buf, num_bytes, 1, fp);

			flen -= num_bytes;
		}
		CloseStateFile (fp);
	}

	LoadStarDesc (&SD, fh);

	cclose (fh);
	res_CloseResFile (in_fp);

	EncounterGroup = 0;
	EncounterRace = -1;

	ReinitQueue (&race_q[0]);
	ReinitQueue (&race_q[1]);
	CurStarDescPtr = FindStar (NULL, &SD.star_pt, 0, 0);
	if (!(NextActivity & START_ENCOUNTER)
			&& LOBYTE (NextActivity) == IN_INTERPLANETARY)
		NextActivity |= START_INTERPLANETARY;

	return TRUE;
}