
    P                        d Z ddlmZ ddlmZ ddlmZ ddlZddlZddlZddlm	Z	 ddl
mZ ddlmZ dd	lmZ dd
lmZ d Zd Zd8dZd Zd Zd Zd Zd Zd Zd Zd Z ej8                  d       G d d             ZdefdZd Zd Z d Z!d Z"d  Z#d! Z$d" Z%d# Z&d$ Z'd8d%Z(d8d&Z)d' Z*d( Z+d) Z,d* Z-d+ Z.d, Z/d- Z0d. Z1d/ Z2d0 Z3d1 Z4d2ejj                  d3ejl                  d4ejn                  dejp                  fd5Z9d2ejj                  d3ejl                  d4ejn                  dejp                  fd6Z:d2ejj                  d3ejl                  d4ejn                  dejp                  fd7Z;y)9zJHelper functions for constructing and validating AlloyDB cluster requests.    )absolute_import)division)unicode_literalsN)Any)messages)flags)
properties)	resourcesc                    | j                         }|j                  r	d|_        |S |j                  r#d|_        | j	                  |j                  |j
                        |_        |j                  r"| j                  |j                        |_	        n<|j                  r0| j                  dj                  |j                              |_        |j                  r dj                  |j                        |_        t!        j"                  |t!        j$                               }|r| j'                         }||_        ||_        |j,                  |_        |S )2Returns the automated backup policy based on args.FT
daysOfWeek
startTimescount{}sretentionPeriodflag_overrides)AutomatedBackupPolicydisable_automated_backupenabledautomated_backup_days_of_weekWeeklyScheduleautomated_backup_start_timesweeklySchedule automated_backup_retention_countQuantityBasedRetentionquantityBasedRetention!automated_backup_retention_periodTimeBasedRetentionformattimeBasedRetentionautomated_backup_windowbackupWindowr   GetAndValidateKmsKeyName"GetAutomatedBackupKmsFlagOverridesEncryptionConfig
kmsKeyNameencryptionConfigregionlocation)alloydb_messagesargsbackup_policykms_keyencryption_configs        8lib/googlecloudsdk/command_lib/alloydb/cluster_helper.py_ConstructAutomatedBackupPolicyr4       sC   "88:-	""!M6 
5 )) M#3#B#B5544 $C $M  ,,

1
199 2  *
 
	/	/)9)L)L,,t'M'MN *M *m& ###(<<0L0L#Mm ,,UEEGG *;;=%,"'8m$![[M	    c                    | j                         }|j                  rd|_        n|j                  du r	d|_        |S |j                  r dj	                  |j                        |_        |j                  r8|j                  r,| j                  |j                  |j                        |_	        |j                  r"| j                  |j                        |_        n<|j                  r0| j                  dj	                  |j                              |_        t!        j"                  |t!        j$                               }|r| j'                         }||_        ||_        |j,                  |_        |S )r   TFr   r   r   r   r   )r   enable_automated_backupr   r%   r#   r&   r   r   r   r   r   r   r    r!   r"   r$   r   r'   r(   r)   r*   r+   r,   r-   )r.   r/   automated_backup_policyr1   r2   s        r3   1_ConstructAutomatedBackupPolicyForCreateSecondaryr9   B   sc   ,BBD	!!&*###u,&+#""	!!+0<<$$,( 
''D,M,M-=-L-L5544 .M .*
 
**//77 	0 	
 2
 --++!LL)O)OP 	, 	
 . **
5CCE' (99;#* /@,%)[["	  r5   c                 t   | j                         }t        j                  ||       |j                  rd|_        n|j                  du r	d|_        |S |j
                  r|j
                  |_        t        j                  |t        j                               }|r| j                         }||_
        ||_        |S )z3Returns the continuous backup config based on args.TFr   )ContinuousBackupConfigr   ValidateContinuousBackupFlagsenable_continuous_backupr   &continuous_backup_recovery_window_daysrecoveryWindowDaysr'   #GetContinuousBackupKmsFlagOverridesr)   r*   r+   )r.   r/   updatecontinuous_backup_configr1   r2   s         r3    _ConstructContinuousBackupConfigrC   p   s    -DDF%%dF3	""'+$$$-',$##	0033 / **
5DDF' (99;#* 0A-	!!r5   c                 4   | j                         }|j                  |_        | j                  |j                  d      |_        t        j                  |      }|r| j                         }||_        ||_	        |j                  s|j                  rt        | |      |_        |j                  |j                  s|j                   rt#        | |      |_        |j&                  r,| j)                  |j                  |j&                        |_        |j,                  r| j/                  d      |_        |j2                  |_        |j6                  xs |j8                  }|j:                  xs |j<                  xs |j>                  }|s|r| jA                         |_!        |rtE        | |      |jB                  _#        |rtI        | |      |jB                  _%        |jL                  |_'        t        jP                  || j                   jR                        |_*        |S )z8Returns the cluster for GA create request based on args.postgres)passworduser)networkallocatedIpRangeT
pscEnabled)+ClusterrH   UserPasswordrF   initialUserr   r'   r)   r*   r+   r   r   r4   automatedBackupPolicyr=   r>    continuous_backup_encryption_keyrC   continuousBackupConfigallocated_ip_range_nameNetworkConfignetworkConfigenable_private_service_connect	PscConfig	pscConfigdatabase_versiondatabaseVersionmaintenance_window_daymaintenance_window_hour"deny_maintenance_period_start_date deny_maintenance_period_end_datedeny_maintenance_period_timeMaintenanceUpdatePolicymaintenanceUpdatePolicy_ConstructMaintenanceWindowsmaintenanceWindows_ConstructDenyPeriodsdenyMaintenancePeriodssubscription_typesubscriptionTypeGetTagsFromArgs	TagsValuetags)r.   r/   clusterr1   r2   configure_maintenance_windowconfigure_deny_periods          r3   #_ConstructClusterForCreateRequestGArm      s   $$&'LL'/(55}}: 6 ' **40'(99;#* 0G	""d&H&H$C$%G!
 ##/		4	4		.	.%E$&G" 
!!,::t/K/K ; G 
(((22d2CG 11' !!AT%A%A  -- +		.	.+		*	* 
 "%:&6&N&N&PG#!$%5t< ##6 .5 ##: "33'&&t-=-E-E-O-OP',	.r5   c                 @    |j                   |j                   | _        | S N)#automated_backup_enforced_retentionenforcedRetention)r0   r/   s     r3   ,_AddEnforcedRetentionToAutomatedBackupPolicyrr      s"    	--9&*&N&NM#	r5   c                 @    |j                   |j                   | _        | S ro   )$continuous_backup_enforced_retentionrq   )rB   r/   s     r3   -_AddEnforcedRetentionToContinuousBackupConfigru      s)     
..:11 . 
"!r5   c                     t        | |      }t        |j                  |      |_        t        |j                  |      |_        |S )z:Returns the cluster for beta create request based on args.)rm   rr   rO   ru   rQ   r.   r/   rj   s      r3   %_ConstructClusterForCreateRequestBetarx      sK    /0@$G'"N##T#' 4

(
($ 
  
.r5   c                 H    t        j                  |       t        | |      }|S )z;Returns the cluster for alpha create request based on args.)r   ValidateConnectivityFlagsrx   rw   s      r3   &_ConstructClusterForCreateRequestAlphar{      s"    !!$'12BDI'	.r5   c                 r    t        | |      }| j                  ||j                  |j                               S )z>Returns the cluster create request for GA track based on args.rj   	clusterIdparent)rm   -AlloydbProjectsLocationsClustersCreateRequestrj   RelativeNamer.   location_refr/   rj   s       r3    ConstructCreateRequestFromArgsGAr      s>    /0@$G'		G	G&&( 
H 
 r5   c                 r    t        | |      }| j                  ||j                  |j                               S )z@Returns the cluster create request for beta track based on args.r}   )rx   r   rj   r   r   s       r3   "ConstructCreateRequestFromArgsBetar      s>    12BDI'		G	G&&( 
H 
 r5   c                 r    t        | |      }| j                  ||j                  |j                               S )zAReturns the cluster create request for alpha track based on args.r}   )r{   r   rj   r   r   s       r3   #ConstructCreateRequestFromArgsAlphar     s>    23CTJ'		G	G&&( 
H 
 r5   T)frozenc                   J    e Zd ZU dZdZeed<   dZeed<   dZeed<   dZ	eed<   y)RestoreSourcezRestore source for a cluster.Nbackupbackup_dr_backupbackup_dr_pitrcontinuous_backup)
__name__
__module____qualname____doc__r   r   __annotations__r   r   r    r5   r3   r   r     s/    %&#C.#Sr5   r   returnc                 ~   |j                   r|j                  d|j                   t        j                  j                  j
                  j                  |j                  d      }t        | j                  |j                                     S t        |d      r2|j                  r&t        | j                  |j                              S t        |d      rL|j                  r@t        | j                  |j                  |j                   j#                  d	      
            S |j                  d|j$                  t        j                  j                  j
                  j                  |j                  d      }t        | j'                  |j                         |j                   j#                  d	                  S )zDReturns the backup and continuous backup source for restore request.z"alloydb.projects.locations.backups)
projectsIdlocationsId)
collectionlineparams)
backupName)r   backupdr_backup)r   backupdr_data_sourcez%Y-%m-%dT%H:%M:%S.%fZ)
dataSourcepointInTime)r   z#alloydb.projects.locations.clusters)rj   r   )r   )r   Parser	   VALUEScoreproject	GetOrFailr,   r   BackupSourcer   hasattrr   BackupDrBackupSourcer   BackupDrPitrSourcepoint_in_timestrftimesource_clusterContinuousBackupSource)r.   resource_parserr/   
backup_refcluster_refs        r3   _ConstructRestoreSourcer     s    
[[ &&7[[$++0088BB;;
 ' J ,,!..0 - 
  T$%$*>*>)>>'' ? 
  T)*t/H/H'::00**334KL ; 
   %%6"))..66@@ & + 
(??**,((112IJ @ 
 r5   c                    | j                         }|j                  |_        t        j                  |      }|r| j	                         }||_        ||_        |j                  r!| j                  |j                        |_	        |j                  r| j                  d      |_        |j                  r/t        j                  || j                   j                        |_        |S )1Returns the cluster resource for restore request.rI   TrJ   )rL   rH   r   r'   r)   r*   r+   rR   rS   rT   rU   rV   rW   ri   rg   rh   )r.   r/   cluster_resourcer1   r2   s        r3   *_ConstructClusterResourceForRestoreRequestr   R  s    %--/!\\**40'(99;#* (9%	!!%5%C%C55 &D &" 
((!1!;!;t!;!L	YY!11&&00 
r5   c           	          t        | |      }t        | ||      }| j                  |j                         | j	                  |j
                  |j                  |j                  |            S )z?Returns the cluster restore request for GA track based on args.)backupSourcecontinuousBackupSourcer~   rj   r   restoreClusterRequest)r   r   .AlloydbProjectsLocationsClustersRestoreRequestr   RestoreClusterRequestr   r   rj   r.   r   r   r/   r   restore_sources         r3   !ConstructRestoreRequestFromArgsGAr   l  s     @ +
. 
	H	H&&(,BB%,,!/!A!ALL" C  
I 	
 	r5   c                     t        | |      }|S r   r   r.   r/   r   s      r3   /_ConstructClusterResourceForRestoreRequestAlphar         ? 
r5   c                 b   t        | |      }t        | ||      }t        j                  || j                  j
                        |_        | j                  |j                         | j                  |j                  |j                  |j                  |j                  |j                  |            S )zBReturns the cluster restore request for Alpha track based on args.r   r   backupdrBackupSourcebackupdrPitrSourcer~   rj   r   )r   r   r   rg   rL   rh   ri   r   r   r   r   r   r   r   rj   r   s         r3   $ConstructRestoreRequestFromArgsAlphar     s     E +
.
  //
$$.. 
	H	H&&(,BB%,,!/!A!A->>+::LL" C  
I 

 
r5   c                     t        | |      }|S r   r   r   s      r3   ._ConstructClusterResourceForRestoreRequestBetar     r   r5   c                    t        | |      }t        | ||      }| j                  |j                         | j	                  |j
                  |j                  |j                  |j                  |j                  |            S )zAReturns the cluster restore request for Beta track based on args.r   r   )
r   r   r   r   r   r   r   r   r   rj   r   s         r3   #ConstructRestoreRequestFromArgsBetar     s     D +
. 
	H	H&&(,BB%,,!/!A!A->>+::LL" C  
I 

 
r5   c                 H   | j                         }g }g }|j                  s|j                  s|j                  r"t	        | |      |_        |j                  d       |j                  r|j                  d       n6|j                  du r(|j                  d       t        | |d      |_	        ||fS |j                  r|j                  d       |j                  s|j                  r|j                  d       |j                  |       |rt        | |d      |_	        |j                  xs |j                  xs |j                   }|j"                  xs( |j$                  xs |j&                  xs |j(                  }|s|r| j+                         |_        |r.t/        | |d      |j,                  _        |j                  d	       |r.t3        | |d      |j,                  _        |j                  d
       |j6                  "|j6                  |_        |j                  d       ||fS )/Returns the cluster resource for patch request.r8   z continuous_backup_config.enabledFrB   T)rA   z-continuous_backup_config.recovery_window_daysz*continuous_backup_config.encryption_configz-maintenance_update_policy.maintenance_windowsz2maintenance_update_policy.deny_maintenance_periodsre   )rL   r   r   clear_automated_backupr4   rO   appendr=   rC   rQ   r>   rP   &clear_continuous_backup_encryption_keyextendmaintenance_window_anyrZ   r[   remove_deny_maintenance_periodr\   r]   r^   r_   r`   ra   rb   rc   rd   re   rf   )r.   r/   rj   update_maskscontinuous_backup_update_masksupdate_maintenance_windowupdate_deny_periods          r3   )_ConstructClusterAndMaskForPatchRequestGAr     s-   $$&',#%  ##		+	+		$	$$C$%G! 12	"""))*LM$$- 23%E$t&G" L  	00"))7 ++		4	4"))4 45#%E$t&G"
 !! &		$	$&		%	%  )) +		0	0+		.	.+ 
	*	*	  "4&6&N&N&PG#$%5tDI ##6 GH.TB ##: LM	'#55G+,	,	r5   c                    t        | |      \  }}|j                  I|j                  t        | |      |_        |j	                  d       t        |j                  |      |_        |j                  I|j                  t        | |      |_        |j	                  d       t        |j                  |      |_        |j                  r,t        j                  ||       |_        |j	                  d       ||fS )r   z*automated_backup_policy.enforced_retentionz+continuous_backup_config.enforced_retention$maintenance_version_selection_policy)r   rp   rO   r4   r   rr   rt   rQ   rC   ru   maintenance_versionr   GetValidatedMaintenanceVersion!maintenanceVersionSelectionPolicyr.   r/   rj   r   s       r3   +_ConstructClusterAndMaskForPatchRequestBetar     s   C'< 
--9$$,&E
D'g# DE4))4	
 !
 
..:%%-'G
D(g$ EF5**D	
 "
 
,,T3CD - >?	,	r5   c                 (    t        | |      \  }}||fS )r   )r   r   s       r3   ,_ConstructClusterAndMaskForPatchRequestAlphar   @  s#    E'< 
,	r5   c                     |r|j                   rg S | j                         }|j                  |_        | j	                  |j
                        |_        |gS )z.Returns the maintenance windows based on args.)hours)r   MaintenanceWindowrZ   dayGoogleTypeTimeOfDayr[   	startTime)r.   r/   rA   maintenance_windows       r3   ra   ra   H  s^    ++I'99;66!1!E!E(( "F " 	r5   c                     |r|j                   rg S | j                         }|j                  |_        |j                  |_        |j                  |_        |gS )z'Returns the deny periods based on args.)r   DenyMaintenancePeriodr\   	startDater]   endDater^   time)r.   r/   rA   deny_periods       r3   rc   rc   U  sR    33I 668+AA+==+66+
r5   c                     t        | |      \  }}| j                  |j                         |dj                  |            S )zEReturns the cluster patch request for GA release track based on args.,namerj   
updateMask)r   ,AlloydbProjectsLocationsClustersPatchRequestr   joinr.   r   r/   rj   r   s        r3   ConstructPatchRequestFromArgsGAr   a  sL    C'< 
	F	F##%,' 
G 
 r5   c                     t        | |      \  }}| j                  |j                         |dj                  |            S )zGReturns the cluster patch request for Beta release track based on args.r   r   )r   r   r   r   r   s        r3   !ConstructPatchRequestFromArgsBetar   m  sL    E'< 
	F	F##%,' 
G 
 r5   c                     | j                         }|j                  |_        | j                  |j                         |      S )zJReturns the cluster upgrade request for Alpha release track based on args.)r   upgradeClusterRequest)UpgradeClusterRequestversion.AlloydbProjectsLocationsClustersUpgradeRequestr   )r.   r   r/   upgrade_cluster_requests       r3   ConstructUpgradeRequestFromArgsr  y  sF    ,BBD$(LL!		H	H##%3 
I 
 r5   c                    | j                         }| j                  |j                        |_        t	        j
                  |      }|r| j                         }||_        ||_        |j                  |j                  s|j                  rt        | |      |_        |j                  $|j                  s|j                   s|j"                  rt%        | |      |_        |j(                  r!| j+                  |j(                        |_        |j.                  r/t	        j0                  || j                   j2                        |_        |S )zBReturns the cluster for GA create-secondary request based on args.)primaryClusterNamer   )rL   SecondaryConfigprimary_clustersecondaryConfigr   r'   r)   r*   r+   r=   r>   rP   rC   rQ   r7   r   r%   r   r9   rO   rR   rS   rT   ri   rg   rh   )r.   r/   rj   r1   r2   s        r3   ,_ConstructClusterForCreateSecondaryRequestGAr    s8   $$&',<<-- = ' **40'(99;#* 0G ##/		4	4		.	.%E$&G"
 "".		+	+		%	%		*	* 	:d	
 ! 
!!,::55 ; G 
YY((&&00GL 
.r5   c                     t        | |      }|S ro   )r  rw   s      r3   ._ConstructClusterForCreateSecondaryRequestBetar    s    89I4P'	.r5   c                     t        | |      }|S ro   )r  rw   s      r3   /_ConstructClusterForCreateSecondaryRequestAlphar    s    :' 
.r5   c                 r    t        | |      }| j                  ||j                  |j                               S )zPReturns the cluster create-secondary request For GA release track based on args.r}   )r  6AlloydbProjectsLocationsClustersCreatesecondaryRequestrj   r   r.   r   r/   rj   s       r3   )ConstructCreatesecondaryRequestFromArgsGAr    s@     99I4P'MMLL))+ N r5   c                 r    t        | |      }| j                  ||j                  |j                               S )zRReturns the cluster create-secondary request for Beta release track based on args.r}   )r  r  rj   r   r  s       r3   +ConstructCreatesecondaryRequestFromArgsBetar    sD    
 ;'
 MMLL))+ N r5   c                 r    t        | |      }| j                  ||j                  |j                               S )zSReturns the cluster create-secondary request for Alpha release track based on args.r}   )r  r  rj   r   r  s       r3   ,ConstructCreatesecondaryRequestFromArgsAlphar    sD    
 <'
 MMLL))+ N r5   c                 R   | j                         }|j                  |_        |j                  r| j                         |_        |j
                  |j                  _        |j                  |j                  _        |j                  |j                  _
        |j                  |j                  _        n|j                  r| j                         |_        |j                   |j                  _        |j$                  r*|j$                  j'                  d      |j                  _        |j(                  |j                  _        |j,                  |j                  _        | j1                         |_        |j4                  |j2                  _        | j9                  |j;                         |      S )z1Returns the cluster export request based on args.r   )r   exportClusterRequest)ExportClusterRequestdatabasecsvCsvExportOptionscsvExportOptionsselect_queryselectQueryfield_delimiterfieldDelimiterescape_characterescapeCharacterquote_characterquoteCharactersqlSqlExportOptionssqlExportOptionsschema_only
schemaOnlytablessplitclean_target_objectscleanTargetObjectsif_exist_target_objectsifExistTargetObjectsGcsDestinationgcsDestinationgcs_uriuri-AlloydbProjectsLocationsClustersExportRequestr   )r.   r   r/   export_cluster_requests       r3   ConstructExportRequestFromArgsr8    sq   +@@B$(MM!	XX))+ + ;?:K:K++7 ++: 	 ++; 	 ++: xx))+ + :>9I9I++6{{7;{{7H7H7M--4!! ++> 	$$ ++@ +;*I*I*K'.2ll''+		G	G##%1 
H 
 r5   c                    | j                         }|j                  |_        |j                  |_        |j                  |_        |j
                  r| j                         |_        |j                  |j                  _        |j                  r*|j                  j                  d      |j                  _	        |j                  |j                  _        |j                  |j                  _        |j                  |j                  _        n!|j"                  r| j%                         |_        | j)                  |j+                         |      S )z1Returns the cluster import request based on args.r   )r   importClusterRequest)ImportClusterRequestr  rG   r4  gcsUrir  CsvImportOptionscsvImportOptionstablecolumnsr-  r!  r"  r#  r$  r%  r&  r'  SqlImportOptionssqlImportOptions-AlloydbProjectsLocationsClustersImportRequestr   )r.   r   r/   import_cluster_requests       r3   ConstructImportRequestFromArgsrE    s   +@@B$(MM! $		"&,,	XX))+ + 59JJ++1||8<8J8J38O--5 ++: 	 ++; 	 ++: xx))+ + 
	G	G##%1 
H 
 r5   r.   r   r/   c                 t   | j                         }t        | |      |_        |j                  |_        | j	                         |_        |j                  |j
                  _        |j                  |j
                  _	        |j                  |j
                  _        | j                  |j                         |      S )au  Constructs the Migrate Cloud Sql request for Alpha release track.

  Args:
    alloydb_messages: The AlloyDB messages module.
    location_ref: The location reference for the request.
    args: An object that contains the values for the arguments specified in the
      .Args() method.

  Returns:
    The Migrate Cloud Sql request based on args for Alpha release track.
  r   restoreFromCloudSQLRequest)RestoreFromCloudSQLRequestr{   rj   r~   CloudSQLBackupRunSourcecloudsqlBackupRunSourcecloud_sql_backup_idbackupRunIdcloud_sql_instance_id
instanceIdcloud_sql_project_idr   :AlloydbProjectsLocationsClustersRestoreFromCloudSQLRequestr   r.   r   r/   migrate_cloud_sql_requests       r3   ,ConstructMigrateCloudSqlRequestFromArgsAlpharT  6  s      /IIK&L'# )-%..0 3  33?    33>  33; 
	T	T&&(!: 
U 
 r5   c                 t   | j                         }t        | |      |_        |j                  |_        | j	                         |_        |j                  |j
                  _        |j                  |j
                  _	        |j                  |j
                  _        | j                  |j                         |      S )as  Constructs the Migrate Cloud Sql request for Beta release track.

  Args:
    alloydb_messages: The AlloyDB messages module.
    location_ref: The location reference for the request.
    args: An object that contains the values for the arguments specified in the
      .Args() method.

  Returns:
    The Migrate Cloud Sql request based on args for Beta release track.
  rG  )rI  rx   rj   r~   rJ  rK  rL  rM  rN  rO  rP  r   rQ  r   rR  s       r3   +ConstructMigrateCloudSqlRequestFromArgsBetarV  ^  s      /IIK&K'# )-%..0 3  33?    33>  33; 
	T	T&&(!: 
U 
 r5   c                 t   | j                         }t        | |      |_        |j                  |_        | j	                         |_        |j                  |j
                  _        |j                  |j
                  _	        |j                  |j
                  _        | j                  |j                         |      S )ao  Constructs the Migrate Cloud Sql request for GA release track.

  Args:
    alloydb_messages: The AlloyDB messages module.
    location_ref: The location reference for the request.
    args: An object that contains the values for the arguments specified in the
      .Args() method.

  Returns:
    The Migrate Cloud Sql request based on args for GA release track.
  rG  )rI  rm   rj   r~   rJ  rK  rL  rM  rN  rO  rP  r   rQ  r   rR  s       r3   )ConstructMigrateCloudSqlRequestFromArgsGArX    s      /IIK&I'# )-%..0 3  33?    33>  33; 
	T	T&&(!: 
U 
 r5   )F)<r   
__future__r   r   r   argparsedataclassestypestypingr   apitools.base.protorpcliter   "googlecloudsdk.command_lib.alloydbr   googlecloudsdk.corer	   r
   r4   r9   rC   rm   rr   ru   rx   r{   r   r   r   	dataclassr   r   r   r   r   r   r   r   r   r   r   ra   rc   r   r   r  r  r  r  r  r  r  r8  rE  
ModuleTypeResource	NamespaceMessagerT  rV  rX  r   r5   r3   <module>rf     s   Q &  '     / 4 * )D+!\"4:z" d#    $ 7 	7t44:6IX!H
			*Z$$$N@%&&%$$% 

% 	%P%&&%$$% 

% 	%P%&&%$$% 

% 	%r5   