@ -9,7 +9,7 @@ from cereal import car 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					from  panda  import  ALTERNATIVE_EXPERIENCE  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					from  openpilot . common . params  import  Params  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					from  openpilot . common . realtime  import  DT_CTRL  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					from  openpilot . common . realtime  import  config_realtime_process ,  Priority ,  Ratekeeper ,  DT_CTRL  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					from  openpilot . selfdrive . boardd . boardd  import  can_list_to_can_capnp  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					from  openpilot . selfdrive . car . car_helpers  import  get_car ,  get_one_can  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				 
				
					@ -21,22 +21,24 @@ REPLAY = "REPLAY" in os.environ 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					EventName  =  car . CarEvent . EventName  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					class  CarD  :  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					class  Car :  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					  CI :  CarInterfaceBase   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					  def  __init__ ( self ,  CI = None ) :   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    self . can_sock  =  messaging . sub_sock ( ' can ' ,  timeout = 20 )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    self . sm  =  messaging . SubMaster ( [ ' pandaStates ' ] )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    self . sm  =  messaging . SubMaster ( [ ' pandaStates ' ,  ' carControl ' ,  ' onroadEvents ' ] )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    self . pm  =  messaging . PubMaster ( [ ' sendcan ' ,  ' carState ' ,  ' carParams ' ,  ' carOutput ' ] )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    self . can_rcv_timeout_counter  =  0   # consecutive timeout count   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    self . can_rcv_cum_timeout_counter  =  0   # cumulative timeout count   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    self . CC_prev  =  car . CarControl . new_message ( )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    self . CS_prev  =  car . CarState . new_message ( )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    self . initialized_prev  =  False   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    self . last_actuators  =  None   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    self . last_actuators_output  =  car . CarControl . Actuators . new_message ( )    
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    self . params  =  Params ( )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    params  =  Params ( )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    if  CI  is  None :   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      # wait for one pandaState and one CAN packet   
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				 
				
					@ -44,18 +46,18 @@ class CarD: 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      get_one_can ( self . can_sock )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      num_pandas  =  len ( messaging . recv_one_retry ( self . sm . sock [ ' pandaStates ' ] ) . pandaStates )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      experimental_long_allowed  =  self . params . get_bool ( " ExperimentalLongitudinalEnabled " )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      experimental_long_allowed  =  params . get_bool ( " ExperimentalLongitudinalEnabled " )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      self . CI ,  self . CP  =  get_car ( self . can_sock ,  self . pm . sock [ ' sendcan ' ] ,  experimental_long_allowed ,  num_pandas )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    else :   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      self . CI ,  self . CP  =  CI ,  CI . CP   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    # set alternative experiences from parameters   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    self . disengage_on_accelerator  =  self . params . get_bool ( " DisengageOnAccelerator " )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    self . disengage_on_accelerator  =  params . get_bool ( " DisengageOnAccelerator " )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    self . CP . alternativeExperience  =  0   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    if  not  self . disengage_on_accelerator :   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      self . CP . alternativeExperience  | =  ALTERNATIVE_EXPERIENCE . DISABLE_DISENGAGE_ON_GAS   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    openpilot_enabled_toggle  =  self . params . get_bool ( " OpenpilotEnabledToggle " )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    openpilot_enabled_toggle  =  params . get_bool ( " OpenpilotEnabledToggle " )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    controller_available  =  self . CI . CC  is  not  None  and  openpilot_enabled_toggle  and  not  self . CP . dashcamOnly   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				 
				
					@ -66,22 +68,20 @@ class CarD: 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      self . CP . safetyConfigs  =  [ safety_config ]   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    # Write previous route's CarParams   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    prev_cp  =  self . params . get ( " CarParamsPersistent " )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    prev_cp  =  params . get ( " CarParamsPersistent " )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    if  prev_cp  is  not  None :   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      self . params . put ( " CarParamsPrevRoute " ,  prev_cp )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      params . put ( " CarParamsPrevRoute " ,  prev_cp )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    # Write CarParams for controls and radard   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    cp_bytes  =  self . CP . to_bytes ( )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    self . params . put ( " CarParams " ,  cp_bytes )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    self . params . put_nonblocking ( " CarParamsCache " ,  cp_bytes )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    self . params . put_nonblocking ( " CarParamsPersistent " ,  cp_bytes )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    params . put ( " CarParams " ,  cp_bytes )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    params . put_nonblocking ( " CarParamsCache " ,  cp_bytes )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    params . put_nonblocking ( " CarParamsPersistent " ,  cp_bytes )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    self . CS_prev  =  car . CarState . new_message ( )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    self . events  =  Events ( )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					  def  initialize ( self ) :   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    """ Initialize CarInterface, once controls are ready """   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    self . CI . init ( self . CP ,  self . can_sock ,  self . pm . sock [ ' sendcan ' ] )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    # card is driven by can recv, expected at 100Hz   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    self . rk  =  Ratekeeper ( 100 ,  print_delay_threshold = None )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					  def  state_update ( self )  - >  car . CarState :   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    """ carState update loop, driven by can """   
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				 
				
					@ -106,11 +106,6 @@ class CarD: 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    if  can_rcv_valid  and  REPLAY :   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      self . can_log_mono_time  =  messaging . log_from_bytes ( can_strs [ 0 ] ) . logMonoTime   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    self . update_events ( CS )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    self . state_publish ( CS )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    CS  =  CS . as_reader ( )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    self . CS_prev  =  CS   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    return  CS   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					  def  update_events ( self ,  CS :  car . CarState )  - >  car . CarState :   
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				 
				
					@ -129,12 +124,6 @@ class CarD: 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					  def  state_publish ( self ,  CS :  car . CarState ) :   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    """ carState and carParams publish loop """   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    # carState   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    cs_send  =  messaging . new_message ( ' carState ' )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    cs_send . valid  =  CS . canValid   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    cs_send . carState  =  CS   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    self . pm . send ( ' carState ' ,  cs_send )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    # carParams - logged every 50 seconds (> 1 per segment)   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    if  self . sm . frame  %  int ( 50.  /  DT_CTRL )  ==  0 :   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      cp_send  =  messaging . new_message ( ' carParams ' )   
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				 
				
					@ -144,17 +133,60 @@ class CarD: 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    # publish new carOutput   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    co_send  =  messaging . new_message ( ' carOutput ' )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    co_send . valid  =  True   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    if  self . last_actuators  is  not  None :   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      co_send . carOutput . actuatorsOutput  =  self . last_actuators   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    co_send . valid  =  self . sm . all_checks ( [ ' carControl ' ] )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    co_send . carOutput . actuatorsOutput  =  self . last_actuators_output   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    self . pm . send ( ' carOutput ' ,  co_send )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    # kick off controlsd step while we actuate the latest carControl packet   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    cs_send  =  messaging . new_message ( ' carState ' )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    cs_send . valid  =  CS . canValid   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    cs_send . carState  =  CS   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    cs_send . carState . canRcvTimeout  =  self . can_rcv_timeout   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    cs_send . carState . canErrorCounter  =  self . can_rcv_cum_timeout_counter   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    cs_send . carState . cumLagMs  =  - self . rk . remaining  *  1000.   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    self . pm . send ( ' carState ' ,  cs_send )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					  def  controls_update ( self ,  CS :  car . CarState ,  CC :  car . CarControl ) :   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    """ control update loop, driven by carControl """   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    # send car controls over can   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    now_nanos  =  self . can_log_mono_time  if  REPLAY  else  int ( time . monotonic ( )  *  1e9 )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    self . last_actuators ,  can_sends  =  self . CI . apply ( CC ,  now_nanos )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    self . pm . send ( ' sendcan ' ,  can_list_to_can_capnp ( can_sends ,  msgtype = ' sendcan ' ,  valid = CS . canValid ) )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    if  not  self . initialized_prev :   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      # Initialize CarInterface, once controls are ready   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      self . CI . init ( self . CP ,  self . can_sock ,  self . pm . sock [ ' sendcan ' ] )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    if  self . sm . all_alive ( [ ' carControl ' ] ) :   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      # send car controls over can   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      now_nanos  =  self . can_log_mono_time  if  REPLAY  else  int ( time . monotonic ( )  *  1e9 )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      self . last_actuators_output ,  can_sends  =  self . CI . apply ( CC ,  now_nanos )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      self . pm . send ( ' sendcan ' ,  can_list_to_can_capnp ( can_sends ,  msgtype = ' sendcan ' ,  valid = CS . canValid ) )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      self . CC_prev  =  CC   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					  def  step ( self ) :   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    CS  =  self . state_update ( )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    self . update_events ( CS )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    self . state_publish ( CS )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    initialized  =  ( not  any ( e . name  ==  EventName . controlsInitializing  for  e  in  self . sm [ ' onroadEvents ' ] )  and   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                   self . sm . seen [ ' onroadEvents ' ] )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    if  not  self . CP . passive  and  initialized :   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      self . controls_update ( CS ,  self . sm [ ' carControl ' ] )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    self . initialized_prev  =  initialized   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    self . CS_prev  =  CS . as_reader ( )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					  def  card_thread ( self ) :   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    while  True :   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      self . step ( )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      self . rk . monitor_time ( )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					def  main ( ) :  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					  config_realtime_process ( 4 ,  Priority . CTRL_HIGH )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					  car  =  Car ( )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					  car . card_thread ( )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    self . CC_prev  =  CC   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					if  __name__  ==  " __main__ " :  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					  main ( )