
    hZ'f                      d 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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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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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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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d&l,m.Z. dd'l,m/Z/ dd(lm0Z0 dd)l1m2Z2 e
rHdd*l3m4Z4 dd+l3m5Z5 dd,l3m6Z6 dd-l7m8Z8 dd.l9m:Z: dd/l9m;Z; dd0l9m<Z< dd1l9m=Z= dd2l>m?Z? dd3lm@Z@ dd4lmAZA dd5lBmCZC  ed6eD7      ZEe		 	 dN	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dOd8       ZFe		 	 dN	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dPd9       ZF	 	 dQ	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dRd;ZFe		 	 dS	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dTd<       ZGe		 	 dS	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dUd=       ZG	 	 dV	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dWd>ZGd? ZH G d@ dAe      ZI G dB dCeI      ZJ e*j                  dDdE       G dF dGeIe.             ZL e*j                  dDdH       G dI dJeJe/             ZM e*j                  dDdK       G dL dMeJe-             ZNy:)Xzoadditional ORM persistence classes related to "bulk" operations,
specifically outside of the flush() process.

    )annotations)Any)cast)Dict)Iterable)Optional)overload)TYPE_CHECKING)TypeVar)Union   )
attributes)context)	evaluator)exc)loading)persistence)NO_VALUE)AbstractORMCompileState)FromStatement)ORMFromStatementCompileState)QueryContext   )util)Dialect)result)	coercions)dml)
expression)roles)select)sqltypes)_entity_namespace_key)CompileState)Options)DeleteDMLState)InsertDMLState)UpdateDMLState)
EMPTY_DICT)Literal)DMLStrategyArgument)OrmExecuteOptionsParameter)SynchronizeSessionArgument)Mapper)_BindArguments)ORMExecuteState)Session)SessionTransaction)InstanceState)
Connection)cursor)_CoreAnyExecuteParams_O)boundc                     y N mappermappingssession_transactionisstatesreturn_defaultsrender_nullsuse_orm_insert_stmtexecution_optionss           n/var/www/html/tulostaulu.pesapallolive.fi/venv/lib/python3.12/site-packages/sqlalchemy/orm/bulk_persistence.py_bulk_insertrF   J   s         c                     y r:   r;   r<   s           rE   rF   rF   W   s      #rG   Nc                     j                   }|j                  j                  rt        d      |rL|r0|D 	cg c]  }	|	|	j                  f }
}	|
D 	cg c]  \  }	}|	 }}	}n>|D 	cg c]  }	|	j                   }}	n$|D cg c]  }t	        |       }}t         |       |j                  |      d }|j                  j                         D cg c]  \  }}| j                  v r||f }}}|rd}nt        |      dkD  rd}nd}|D ]  \  }}|9|j                         D cg c]  }|j                  |d   v r|j                  ! c}nd} fdt        j                  | fd|D        d|||	      D        }t        j                  |d ||||||
      }||j                   r||}|j"                  s|sJ |j%                  |      } |r^|r\ j&                  } j(                  D cg c]  }|j                   }}
D ](  \  }	}|t+        |D cg c]  }||   	 c}      f|	_        * ||J |S y c c}	w c c}}	w c c}	w c c}w c c}}w c c}w c c}w c c}w )NzJconnection_callable / per-instance sharding not supported in bulk_insert()Tr   Fr   r;   c           	   3  D   K   | ]  \  }}}}}}}}d ||
	|||f  y wr:   r;   ).0state
state_dictparamsmpconnvalue_paramshas_all_pkshas_all_defaults
connectionr=   s            rE   	<genexpr>z_bulk_insert.<locals>.<genexpr>   sM      
	 #  	
s    c              3  *   K   | ]
  }d |f  y wr:   r;   rK   mappingrT   r=   s     rE   rU   z_bulk_insert.<locals>.<genexpr>   s     M$4Ms   )bulkrA   rB   include_bulk_keys)bookkeepingrC   rD   )base_mappersessionconnection_callableNotImplementedErrordict_expand_compositesrT   _sorted_tablesitems_pks_by_tablelen_get_embedded_bindparamskeyr   _collect_insert_commands_emit_insert_statements
_returningreturns_rowssplice_horizontally_identity_class_identity_key_propstuple)r=   r>   r?   r@   rA   rB   rC   rD   r\   rL   statesdict_mreturn_resulttablerO   mappers_to_runr[   super_mapperbextra_bp_namesrecordsr   identity_clspidentity_propsrg   rT   s   `                          @rE   rF   rF   d   s    $$K""66!-
 	

 7?@euejj)@F@4:;.5%;H;089u

9H9%-.DG..68,$//<J8<M %3399;E2F((( 
N  	^	q	  - ?J| #. -EEG55HQK'   	
( 55MHM +)"0)
< 44# 3/	
 *&11]5J &$$"" - A A& I?JB 8--)/)C)CDA!%%DD" 	LE5^<cuSz<=EI	 &(( 'O A;9.4t E =s/   H;I (III%$I0II c                     y r:   r;   r=   r>   r?   r@   update_changed_onlyuse_orm_update_stmtenable_check_rowcounts          rE   _bulk_updater      s     rG   c                     y r:   r;   r~   s          rE   r   r      s     rG   c                     j                   } j                   j                  r& j                  j                  hj	                        fd}|r3|r|D 	cg c]  }	 | |	       }}	n>|D 	cg c]  }	|	j
                   }}	n$|D 
cg c]  }
t        |
       }}
t         |       |j                  j                  rt        d      |j                  |      |9|j                         D cg c]  }|j                  |d   v r|j                  ! c}nd}|j                  j                         D ]g  \  }} j                  |      r| j                  vr&t!        j"                  d | fd|D        d||      }t!        j$                  |d |||d||	       i |t'        j(                         S y c c}	w c c}	w c c}
w c c}w )
Nc                    |j                   j                         D ci c]  \  }}||j                  v s|v r|| c}}S c c}}w r:   )r`   rc   committed_state)r=   rL   kvsearch_keyss       rE   _changed_dictz#_bulk_update.<locals>._changed_dict  sO     

((*
1E)))Q+-= qD
 	
 
s   AzJconnection_callable / per-instance sharding not supported in bulk_update()r   r;   c              3  v   K   | ]0  }d |j                   r|j                   j                     nd f 2 y wr:   )_version_id_proprg   rW   s     rE   rU   z_bulk_update.<locals>.<genexpr>6  sM         "22   7 7 ; ;<!
s   69T)rY   r   rZ   F)r[   r   r   )r\   _primary_key_propkeysr   rg   unionr`   ra   r]   r^   r_   rT   rf   rb   rc   isard   r   _collect_update_commands_emit_update_statements_resultnull_result)r=   r>   r?   r@   r   r   r   r\   r   rL   rr   rw   rx   rt   rv   ry   rT   r   s   `               @@rE   r   r      s    $$K..K..22399+F
 BJKfe4KHK089u

9H9%-.DG..68,""66!-
 	

 %//<J * )AAC	
uu# EE	
    +99??A "
|zz,'58L8L+L66  (  3,'
* 	++ 3"7		
3"
H &""$$ ' L9.	
s   F62F;G 2$Gc                    | j                   }|sy t        |j                               }|D ci c]  }|||   j                          }}|D ]#  }|j	                  |      D ]  } ||   |        % y c c}w r:   )
compositessetkeys)_populate_composite_bulk_save_mappings_fnintersection)r=   r>   composite_attrscomposite_keysrg   
populatorsrX   s          rE   ra   ra   W  s    ''O--/0N " 	_S!KKMMJ   %!..w7 	%CJsOG$	%%	s   A3c                      e Zd ZU dZdZded<   ed        Zed        Zed        Z	ed        Z
ed	        Zdd
dZed        Zy)ORMDMLStateTNz&Optional[ORMFromStatementCompileState]from_statement_ctxc              #    K   t         j                  }|D ]j  \  }}t        j                  t        j
                  |      }t        |t              rt        ||t              }|t        u rdt        j                  t        j
                  |      |r9t        j                  t        j                  |t        j                         d      n|f  |||j                  |      |      E d {    d|j                  v rA|j                  }	t        |	d   |	d         }
 |||
j                  |      |      E d {    *||s|n8t        j                  t        j                  |t        j                         d      f m y 7 7 Mw)N)defaultT)type_is_crudentity_namespace	proxy_key)r(   _get_crud_kv_pairsr   expectr    DMLColumnRole
isinstancestrr#   r   ExpressionElementRoler"   NullType_bulk_update_tuples_annotations)clsr=   	statementkv_iteratorneeds_to_be_cacheablecore_get_crud_kv_pairsr   r   desck_annoattrs              rE   _get_orm_crud_kv_pairsz"ORMDMLState._get_orm_crud_kv_pairsj  s     "0!B!B 0	DAq  !4!4a8A!S!,VQI8#!(()<)<a@  5 &,, % ; ; !&.&7&7&9(,	 "#   6!003-   
 $q~~5,-.{0C 2,,Q/)     5 &--!77"*"3"3"5$(	 I0	(s&   C(F*F+AF8F9AFFc                    |j                   d   }|r|j                  st        j                  ||      S |D cg c]7  }t	        | j                  |j                  ||j                         d            9 c}S c c}w )Nplugin_subjectF)_propagate_attrsr=   r(   _get_multi_crud_kv_pairsr`   r   rc   )r   r   r   r   
value_dicts        rE   r   z$ORMDMLState._get_multi_crud_kv_pairs  s    "334DE^%:%:!::;  *
  **"))9j6F6F6H%
 	
 
s   <A7c                    |sJ d       |j                   d   }|r|j                  st        j                  |||      S t	        | j                  |j                  |||            S )Nz0no test coverage for needs_to_be_cacheable=Falser   )r   r=   r(   r   listr   )r   r   r   r   r   s        rE   r   zORMDMLState._get_crud_kv_pairs  s|     "	>=	> #334DE^%:%:!44;(=  &&%%%	
 	
rG   c                
   |j                   j                  d   }|j                  }|j                  r|j                  }n|j
                  j                  }||j
                  |j                  |j                  |j                  dS )Nparententity)nametypeexprentityrt   )	rt   r   r=   is_aliased_classr   class___name__r   local_table)r   r   ext_infor=   _label_names        rE   get_entity_descriptionz"ORMDMLState.get_entity_description  sm    ??//?$$"--K --00K  MMOOoo''
 	
rG   c           
         d }d }|j                   D cg c]  }| ||      f c}D cg c]<  \  }}|j                  |j                   |||      |j                  |j                  d> c}}S c c}w c c}}w )Nc                :    | j                   j                  dd       S )Nr   )r   get)cs    rE   _ent_for_colzCORMDMLState.get_returning_column_descriptions.<locals>._ent_for_col  s    >>%%nd;;rG   c                x    || S | j                   j                  dd       }|s| S t        |j                  ||       S )Nr   )r   r   getattrr   )r   entr   s      rE   _attr_for_colzDORMDMLState.get_returning_column_descriptions.<locals>._attr_for_col  s=    {**;=Iszz9a88rG   )r   r   r   aliasedr   )_all_selected_columnsrg   r   r   r   )r   r   r   r   r   r   s         rE   !get_returning_column_descriptionsz-ORMDMLState.get_returning_column_descriptions  s    	<	9$ /8.M.M)*LO$
 3 %a-//**
 	

s   A1AA6)use_supplemental_colsc               ,   |j                   rt        |j                   |d      } |j                  di |j                  } |j                  |j
                   }|| _        t        j                  ||      x| _	        }|j                  |       |j                         }d|_         |j                  D cg c]  }||	 }	}|	s|	j                  |j                         |r |j                  |j                  d|	i}|S  |j                   |	 }|S c c}w )al  establish ORM column handlers for an INSERT, UPDATE, or DELETE
        which uses explicit returning().

        called within compilation level create_for_statement.

        The _return_orm_returning() method then receives the Result
        after the statement was executed, and applies ORM loading to the
        state that we first established here.

        F)_adapt_on_namesr;   supplemental_cols)rj   r   rD   _execution_optionsoptions_with_optionsselect_statementr   create_for_statementr   !setup_dml_returning_compile_state	_generateprimary_columnsextendprimary_keyrA   	returning)
selfcompilerorm_level_statementdml_level_statement
dml_mapperr   fsfscr   cols_to_returns
             rE   _setup_orm_returningz ORMDMLState._setup_orm_returning  s9   ( ))#..# %B
 &%%O(;(N(NOB0>>?B$&D!,AA"hOD#c 11*="5"?"?"A-/*),)<)<NAaNNN "%%j&<&<=$&I&9&I&I  ++' '5'#( #"	 'D&9&C&C#'# #"9 Os   5D=Dc           	     X   |j                   }|j                  j                  }|j                  r{|j                  j                  j
                  s[|j                  dt        j                        }	t        |j                  |j                  |||	||      }
t        j                  ||
      S |S )N_sa_orm_load_options)r   compiledcompile_stater   compile_options_is_starr   r   default_load_optionsr   r   	instances)r   r]   r   rN   rD   bind_argumentsr   execution_contextr   load_optionsquerycontexts              rE   _return_orm_returningz!ORMDMLState._return_orm_returning9  s     #NN)22@@ ,,!44DDMM,00&(I(IL (00..!L $$V\::MrG   )r   
__module____qualname__is_dml_returningr   __annotations__classmethodr   r   r   r   r   r   r   r;   rG   rE   r   r   f  s    AE>E5 5n 
 
" 
 
* 
 
  
 
B #A#F  rG   r   c                  
   e Zd Z G d de      Zeddddd	 	 	 	 	 	 	 	 	 	 	 	 	 dd       Zed        Zed        Zed        Z	ed	        Z
ed
        Zed        Zed        Zed        Zed        Zed        Zed        Zy)BulkUDCompileStatec                      e Zd ZU dZded<   dZded<   dZded<   dZded	<   dZded
<   dZ	ded<   dZ
ded<   eZdZdZdZy))BulkUDCompileState.default_update_optionsautor+   _dml_strategyr-   _synchronize_sessionFbool_can_use_returning_is_delete_using_is_update_fromT
_autoflushNOptional[Mapper[Any]]_subject_mapper)r   r   r   r  r   r  r
  r  r  r  r  r)   _resolved_values_eval_condition_matched_rows_identity_tokenr;   rG   rE   default_update_optionsr  ]  sc    -3*3;A8A#(D(!&$& %%
D15.5%rG   r  Fis_multitableis_update_fromis_delete_usingis_executemanyc                   t               r:   )r_   )r   dialectr=   r  r  r  r  s          rE   can_use_returningz$BulkUDCompileState.can_use_returningj  s     "##rG   c                
   t         j                  j                  dh d||j                        \  }}||d<   	 |j                  d   }|r!|j
                  |d<   |d|j
                  iz  }	 d|j                  j                  vr|d	d
iz  }nat        |t              s;|j                  dk(  r|d	diz  }n:|j                  dk(  r+t        j                  d      |j                  dk(  r|d	diz  }|j                  }	|	B|	dvrt        j                  d      |j                  dk(  r|	dk(  rt        j                  d      |s|j                   r|j!                          |j                  dk(  rr|j                  dk(  r| j#                  ||||||      }nq|j                  dk(  r| j%                  ||||||      }nK|j                  dk(  r<| j'                  ||||||      }n%|j                  dk(  r|j                  dk(  r|ddiz  }|j)                  |j                  |j*                  |j,                  |j                  |j.                  d      }|t1        j2                  |      j5                  d|i      fS # t        $ r J d       w xY w)N_sa_orm_update_options>   	autoflushdml_strategyidentity_tokenr  r  synchronize_sessionclauser   r=   r  0statement had 'orm' plugin but no plugin_subjectr   r  	core_onlyr  ormrY   HCan't use "bulk" ORM insert strategy without passing separate parameters)r  evaluatefetchFzSValid strategies for session synchronization are 'auto', 'evaluate', 'fetch', Falser)  zkThe 'fetch' synchronization strategy is not available for 'bulk' ORM updates (i.e. multiple parameter sets)r(  r  )r"  r  r  r   r  )r  r  from_execution_optionsr   r   r=   KeyErrorrt   r   r   r   r  sa_excInvalidRequestErrorr  ArgumentErrorr  _do_pre_synchronize_auto_do_pre_synchronize_evaluate_do_pre_synchronize_fetch	_annotater  r  r
  r   immutabledictr   )
r   r]   r   rN   rD   r   is_pre_eventupdate_optionsr   syncs
             rE   orm_pre_session_execz'BulkUDCompileState.orm_pre_session_execw  s    55LL$ ((
	
 $-x 	M&778HIN +9+@+@x(#4n6K6K"LL!=!==<<NFD)++v5?E"::--7002 
 ++v5?F";;22??**=  ++v5$'/00L 
 ((""$++u4!66&@%(%A%A!)&&&N $88JF%(%E%E!)&&&N $88GC%(%B%B!)&&&N  --7!66&@"'=z&JJN "+++9+N+N'5'F'F&4&D&D$2$@$@)7)J)JI 0177)>:
 	
i  	MLLL	Ms   I1 1Jc                N   |d   }|j                   dk(  rH|j                  dk(  r| j                  ||||       nX|j                  dk(  rI| j                  ||||       n4|j                   dk(  r%|j                  dk(  r| j	                  ||||       |S | j                  ||||||      S )Nr  r&  r(  r)  rY   )r  r  _do_post_synchronize_evaluate_do_post_synchronize_fetch"_do_post_synchronize_bulk_evaluater   )r   r]   r   rN   rD   r   r   r5  s           rE   orm_setup_cursor_resultz*BulkUDCompileState.orm_setup_cursor_result  s    $ ++CD''5022j@11Y  44?..Y ))V322j@66VV^ M((
 	
rG   c                :   d}j                   rj                  nddj                  f|v r&|t        fd|dj                  f   D              z  }j                  j                  |j                  j                  fz  }rt        fd|D              }|S )a  Apply extra criteria filtering.

        For all distinct single-table-inheritance mappers represented in the
        table being updated or deleted, produce additional WHERE criteria such
        that only the appropriate subtypes are selected from the total results.

        Additionally, add WHERE criteria originating from LoaderCriteriaOptions
        collected from the statement.

        r;   Nadditional_entity_criteriac              3  t   K   | ]/  }|j                   s|j                  u r|j                         1 y wr:   )include_aliasesr   _resolve_where_criteria)rK   aer   s     rE   rU   z@BulkUDCompileState._adjust_for_extra_criteria.<locals>.<genexpr>0  s:      ! %%h)>	 **84!s   58c              3  @   K   | ]  }j                  |        y wr:   )traverse)rK   critadapters     rE   rU   z@BulkUDCompileState._adjust_for_extra_criteria.<locals>.<genexpr><  s     O4 0 0 6Os   )r   _adapterr=   ro   _single_table_criterion)r   global_attributesr   return_critrF  s     ` @rE   _adjust_for_extra_criteriaz-BulkUDCompileState._adjust_for_extra_criteria  s     '/'@'@(##d )OO
  5 !+18??C!  K ??22>HOOCCEEKO;OOKrG   c                   |j                   |j                  j                   ur|S |j                   j                  D ci c]  }|| }}|j                         D ]  }|j                   n|j                   |j                  j                   u r4t        |j                  |j                  j                            }||   D ci c]  \  }}||
 }	}}|j                         D ]  \  }}
|	|
   ||<     t        |j                   j                        D ci c]  \  }}||   | }}}|j                  j                  D cg c]  }||   	 }}|D cg c]  t        fd|D               c}S c c}w c c}}w c c}}w c c}w c c}w )a  translate from local inherited table columns to base mapper
        primary key columns.

        Joined inheritance mappers always establish the primary key in terms of
        the base table.   When we UPDATE a sub-table, we can only get
        RETURNING for the sub-table's columns.

        Here, we create a lookup from the local sub table's primary key
        columns to the base table PK columns so that we can get identity
        key values from RETURNING that's against the joined inheritance
        sub-table.

        the complexity here is to support more than one level deep of
        inheritance, where we have to link columns to each other across
        the inheritance hierarchy.

        c              3  (   K   | ]	  }|     y wr:   r;   )rK   idxrows     rE   rU   z?BulkUDCompileState._interpret_returning_rows.<locals>.<genexpr>o  s     >3c#h>   )
r   r\   r   iterate_to_rootinheritsr`   _table_to_equatedrc   	enumeratero   )r   r=   rowspklocal_pk_to_base_pkrO   t_to_esuper_pksub_pk
col_to_colsuper_rN  lpklookupbpkprimary_key_convertrO  s                   `rE   _interpret_returning_rowsz,BulkUDCompileState._interpret_returning_rows@  s   ( V%7%7%C%CCK 170B0B0N0NO"r2vOO((* 		=B{{"2;;#:#::"..r{{/F/FGHFCI":N/?x&(*NJN1779 =
F*4V*<#B'=		= &f&8&8&D&DE
S  $c)
 

 $*#5#5#A#A
F3K
 
 KOO3>*=>>OO) P O

 Ps   
E2E7E=FFc                    |j                   }|j                  }|D cg c]F  }|j                  j                  |      r)|j                  s|j                         ||j                  fH }}|j                  }|)|D 	cg c]  \  }}}	|j                  |k(  r|||	f }}}}	g }
|D ]J  \  }}}	 ||      }|du s|t        j                  u s&|
j                  |||	|t        j                  u f       L |
S c c}w c c}	}}w NT)r  r  r=   r   expiredobjr`   r  r!  r   _EXPIRED_OBJECTappend)r   r5  rp   r=   eval_conditionrL   raw_datar!  re  rq   r   evaled_conditions               rE    _get_matched_objects_on_criteriaz3BulkUDCompileState._get_matched_objects_on_criteriaq  s,   //'77  
||' YY[%,
 
 (77% *2 %C''>9 eU#H  !) 	C-c2
 !D(#y'@'@@(I,E,EE		" A
s   AC4>C9c                Z   |j                   }|j                  }t        j                  |      }d}|j                  r||j                  z  }i }|j
                  D ]   }|j                  s|j                  |       " |r|| j                  ||      z  }|r |j                  | }	|	S d }
|
}	|	S )Nr;   c                     yrc  r;   )re  s    rE   r  zJBulkUDCompileState._eval_condition_from_statement.<locals>._eval_condition  s    rG   )
r  r   r   _EvaluatorCompiler_where_criteriar   _is_criteria_optionget_global_criteriarK  process)r   r5  r   r=   
target_clsevaluator_compilerrE  rI  optrh  r  s              rE   _eval_condition_from_statementz1BulkUDCompileState._eval_condition_from_statement  s    //]]
&99*E$$I---D** 	;C&&''(9:	; C223DfMMD7/77>N  -NrG   c                    	 | j                  ||      }||ddz   S # t        j                  $ r Y nw xY w|ddiz  }| j                  ||||||      S )a  setup auto sync strategy


        "auto" checks if we can use "evaluate" first, then falls back
        to "fetch"

        evaluate is vastly more efficient for the common case
        where session is empty, only has a few objects, and the UPDATE
        statement can potentially match thousands/millions of rows.

        OTOH more complex criteria that fails to work with "evaluate"
        we would hope usually correlates with fewer net rows.

        r(  )r  r  r  r)  )rv  r   UnevaluatableErrorr1  )r   r]   r   rN   rD   r   r5  rh  s           rE   r/  z+BulkUDCompileState._do_pre_synchronize_auto  s    2	 ??	N "#1(2%   ++ 		 	17;;,,
 	
s    22c                    	 | j                  ||      }|d|iz   S # t        j                  $ r}t        j                  d|z        |d }~ww xY w)Nz{Could not evaluate current criteria in Python: "%s". Specify 'fetch' or False for the synchronize_session execution option.r  )rv  r   rx  r,  r-  )	r   r]   r   rN   rD   r   r5  rh  errs	            rE   r0  z/BulkUDCompileState._do_pre_synchronize_evaluate  sr    
	 ??	N ~!
 
 	
 ++ 	,,8:=> 		s    AAAc                    |j                   rg S |j                  rt        |j                        S |j                  r#t        |j                  j	                               S g S r:   )_multi_values_ordered_valuesr   _valuesrc   )r   r=   r   s      rE   _get_resolved_valuesz'BulkUDCompileState._get_resolved_values  sR    ""I&&	1122	))//122IrG   c                   g }|D ]f  \  }}|rHt        |t        j                        r.	 |j                  |   }|j	                  |j
                  |f       Pt        j                  d|z         |S # t        j                  $ r Y w xY w)NzCAttribute name not found, can't be synchronized back to objects: %r)
r   r   ColumnElement_columntopropertyrg  rg   orm_excUnmappedColumnErrorr,  r-  )r   r=   resolved_valuesvaluesr   r   r   s          rE   _resolved_keys_as_propnamesz.BulkUDCompileState._resolved_keys_as_propnames
  s    # 	DAq*Q
(@(@A1!33A6D MM488Q-00079:; 	  22 s   A00BBc                B    j                    t        j                  j                  fz    j	                        j
                  |j                   }|j                  |_        d d fd}|j                  |||||      }	|	j                         }
|
dz   S )Nc                |    | j                   j                  di | j                  }j                  |j                  j
                  j                  | j                        }|k7  r:t        j                  d      | j                  r|st        j                  d      ||rt        j                         S y )N)r  r  r  zjFor synchronize_session='fetch', can't mix multiple backends where some support RETURNING and others don'tzFor synchronize_session='fetch', can't use multiple parameter sets in ORM mode, which this backend does not support with RETURNINGr;   )r]   get_bindr   r  r  r  r  r  r,  r-  r   r   )orm_contextbindper_bind_resultr  r   r=   r5  s      rE   skip_for_returningzHBulkUDCompileState._do_pre_synchronize_fetch.<locals>.skip_for_returning>  s    /;&&//M+2L2LMD "33-== . ? ?*99 4 O !,$7 44  
 ++O00-  %4!**,,rG   )rD   r   
_add_event)r  r
  )r  r0   returnr   )
r  r!   r   select_identity_tokenselect_fromr   r   ro  executefetchall)r   r]   r   rN   rD   r   r5  select_stmtr  r   matched_rowsr  r=   s   `     `    @@rE   r1  z,BulkUDCompileState._do_pre_synchronize_fetch  s      //FV''6+G+G*IIK[ Wi--/ 	
 '0&?&?# !	 	B /)) ! 
 ()"3!
 
 	
rG   Nr  r   r=   Mapper[Any]r  r	  r  r	  r  r	  r  r	  r  r	  )r   r   r   r%   r  r  r  r7  r<  rK  ra  rk  rv  r/  r0  r  r  r1  r;   rG   rE   r  r  \  s\      $$ %$
$
$ 
$
 
$ 
$ 
$ 
$ 

$ 
$ u
 u
n )
 )
V " "H .P .P` $ $L  8 -
 -
^ 
 
2    " N
 N
rG   r  r&  insertc                       e Zd ZU  G d de      ZdZded<   ed        Ze	 	 	 	 	 	 	 	 	 	 	 	 	 	 dd       Z	ed fd       Z
ed	        Zd
 Zd Z xZS )BulkORMInsertc                  b    e Zd ZU dZded<   dZded<   dZded<   dZd	ed
<   dZded<   dZ	ded<   y)$BulkORMInsert.default_insert_optionsr  r+   r  Fr	  _render_nulls_return_defaultsNr  r  Tr  _populate_existing)
r   r   r   r  r   r  r  r  r  r  r;   rG   rE   default_insert_optionsr  p  sB    -3*3#t#!&$&15.5
D#(D(rG   r  NzOptional[FromStatement]r   c                   t         j                  j                  dh d||j                        \  }}||d<   	 |j                  d   }|r!|j
                  |d<   |d|j
                  iz  }	 |s;|j                  dk(  r|d	d
iz  }n:|j                  dk(  r+t        j                  d      |j                  dk(  r|d	diz  }|j                  dk7  r2|st        j                  }n|j                  t        j                        }|s|j                  r|j                          |j                  d|j                  i      }|t        j                   |      j                  d|i      fS # t        $ r J d       w xY w)N_sa_orm_insert_options>   r  r   rB   populate_existingr#  r   r=   r  r$  r  r  r&  rY   r'  rawr   )r  r  r*  r   r   r=   r+  r  r,  r-  r   _orm_load_exec_optionsr   r  r2  r   r3  )	r   r]   r   rN   rD   r   r4  insert_optionsr   s	            rE   r7  z"BulkORMInsert.orm_pre_session_execz  s    00GG$N((	
	
 $-x 	M&778HIN +9+@+@x(#4n6K6K"LL++v5?E"::--7002 
 ++v5?F";;''50 %$+$B$B!$5$;$;22%!  9 9 ''^99:
	
 0177)>:
 	
O  	MLLL	Ms   E! !E2c           
     t   |j                  d| j                        }|j                  dvrt        j                  d      |j                  dk(  r|j                  ||xs i |      }|S |j                  dk(  r|j                  }	|j                  $|	j                  rt        j                  d|	       |	J |j                  J t        |	t        dt        |t              r|gn|      |j                  d	|j                  |j                   ||
      }n2|j                  dk(  r|j                  ||xs i |      }n
t#               t%        |j&                        s|S |j(                  r:|j                  dt*        j,                        }
|
ddiz  }
|j/                  d|
i      }| j1                  ||||||      S )Nr  )r  rY   r&  r  zHValid strategies for ORM insert strategy are 'raw', 'orm', 'bulk', 'autor  )rD   rY   z`bulk INSERT with a 'post values' clause (typically upsert) not supported for multi-table mapper Iterable[Dict[str, Any]]F)r@   rA   rB   rC   rD   r&  r   r  T)r   r  r  r,  r.  r  r  _post_values_clause_multiple_persistence_tablesr-  _transactionrF   r   r   r`   r  r  AssertionErrorr	  rj   r  r   r   r   r   )r   r]   r   rN   rD   r   rP   r  r   r=   r   s              rE   orm_execute_statementz#BulkORMInsert.orm_execute_statement  s    +..$c&@&@
 '' 0
 
 &&2  ''50\\6<R;L " F M''61#33F --97700$X'  %%''33!. *64 8VHf $$ . ? ?+99$-"3F ))U2\\6<R;L " F !""I(()M,,,00&(I(IL 1488L 1 7 7'6! ((
 	
rG   c                &   t        t        t        |   ||fi |      }||j                   }nd}|s|S |j
                  d   }|j                  j                  dd      }|dk(  r|j                  |       |S |dk(  r|j                  ||       |S )NTr   r   r  rY   r&  )
r   r  superr   stackr   r   r   _setup_for_bulk_insert_setup_for_orm_insert)	r   r   r   kwr   toplevelr=   r   	__class__s	           rE   r   z"BulkORMInsert.create_for_statement  s    G(HCC

 #>>)HHK++,<= --11.%H6!''1  U"&&x8rG   c                    fd|j                         D        D ci c]  \  }}}||j                  n|| c}}}S c c}}}w )Nc              3  `   K   | ]%  \  }}j                   j                  |      ||f ' y wr:   )r   r   )rK   r   r   r=   s      rE   rU   z;BulkORMInsert._resolved_keys_as_col_keys.<locals>.<genexpr>2  s-      ,0Aqa!Q's   +.)rc   rg   )r   r=   resolved_value_dictcolr   r   s    `    rE   _resolved_keys_as_col_keysz(BulkORMInsert._resolved_keys_as_col_keys.  sP    4G4M4M4O
 
Q CGGAq0
 	
 
s   A c                    t        t        j                  | j                        x}}| j	                  ||||d      }|| _        y )NFr   r   )r   r   Insertr   r   )r   r   r=   r   r   s        rE   r  z#BulkORMInsert._setup_for_orm_insert7  sI    *.szz4>>*JJ	'--"' . 
	 #rG   c                   t        t        j                  | j                        x}}|j                  }|d   |d   }}|j                         }||_        | j                  rA| j                  j                         D ci c]  \  }}|j                  |u r|| c}}| _        | j                  ||||d      }| j                  5| j                  j                  j                  rt        j                  d      || _        yc c}}w )zestablish an INSERT statement within the context of
        bulk insert.

        This method will be within the "conn.execute()" call that is invoked
        by persistence._emit_insert_statement().

        _emit_insert_table_emit_insert_mapperTr  NzCan't use RETURNING * with bulk ORM INSERT.  Please use a different INSERT form, such as INSERT..VALUES or INSERT with a Core Connection)r   r   r  r   r   _clonert   _dict_parametersrc   r   r   r   r   r,  CompileError)	r   r   r   r   anemit_insert_tableemit_insert_mapperr  vals	            rE   r  z$BulkORMInsert._setup_for_bulk_insertC  s    +/szz4>>*JJ	'## #$$% .
 $$&	+	   !% 5 5 ; ; =%C99 11 S%D! --)"& . 
	 ##/''77@@%%3  #1%s   =D )r]   r1   r   z
dml.InsertrN   r6   rD   r,   r   r/   rP   r4   r  _result.Result)r  r  )r   r   r   r%   r  r   r   r  r7  r  r   r  r  r  __classcell__r  s   @rE   r  r  n  s    ) ) 15-4A
 A
F V
V
 V
 &	V

 6V
 'V
 V
 
V
 V
p  , 
 

#,#rG   r  updatec                       e Zd Zed        Zd Zd Ze	 	 	 	 	 	 	 	 	 	 	 	 	 	 d fd       Zeddddd	 	 	 	 	 	 	 	 	 	 	 	 	 dd       Zed        Z	ed	        Z
ed
        Zed        Z xZS )BulkORMUpdatec                X   | j                  |       }|j                  j                  dd      }|j                   }|r|dk(  r|j	                  ||       |S |dk(  s|dk(  r2d|j
                  j                  vrt        j                  |||fi | |S |r|dv r|j                  ||       |S )Nr   unspecifiedrY   r%  r   )r&  r  )	__new__r   r   r  _setup_for_bulk_updatert   r(   __init___setup_for_orm_update)r   r   r   r  r   r   r  s          rE   r   z"BulkORMUpdate.create_for_statementt  s    {{3 --11M
  ~~%.''	8<  K'},ioo&B&BB##D)XDD  \-CC&&y(;rG   c                   |}|j                    }|j                  j                  d   }|j                  x| _        }| j	                  ||      | _        | j                  ||||       |j                  rt        | j
                        | _        |j                         }|j                  r| j
                  |_
        n|j                  r| j
                  |_        | j                  | j                  |      }	|	r |j                  |	 }t        j                  | ||fi | d}
|sd }n|j                  j!                  dd       }|j                  j!                  dd       }|dur/|dk(  xr( | j#                  |j$                  || j&                        }|dk(  r'|r%d}
 |j(                  |j                  j*                   }|r| j-                  |||||
	      }|| _        y )
Nr   r  process_criteria_for_toplevelFr"  r  r)  )r  Tr  )r  rt   r   r=   r  r  _init_global_attributesr~  r`   r  r}  rK  rI  wherer(   r  r   r  r  r  rA   r   r   r   )r   r   r   r  r   r  r   r=   new_stmtnew_critr   r"  r  s                rE   r  z#BulkORMUpdate._setup_for_orm_update  s   '~~%??//?'.f $ 9 9&) L$$*2	 	% 	
 $()>)>$?D!##% $$'+'<'<H$#44H22""F
 %x~~x0H 	h?B? %"&"*"7"7";";%t# %1155
 E) $w. **$$fD<N<N +   ').?$(! 0x//1K1KLH00#!&; 1 H "rG   c                   t        t        j                  |      }|j                  }|d   |d   }}|j	                         }||_        t        j                  | ||fi | | j                  rt        j                  d      | j                  rA| j                  j                         D ci c]  \  }}|j
                  |u r|| c}}| _        || _        yc c}}w )zestablish an UPDATE statement within the context of
        bulk insert.

        This method will be within the "conn.execute()" call that is invoked
        by persistence._emit_update_statement().

        _emit_update_table_emit_update_mapperzbulk ORM UPDATE does not support ordered_values() for custom UPDATE statements with bulk parameter sets.  Use a non-bulk UPDATE statement or use values().N)r   r   Updater   r  rt   r(   r  r}  r,  r-  r  rc   r   )	r   r   r   r  r  emit_update_table_r  r  s	            rE   r  z$BulkORMUpdate._setup_for_bulk_update  s     Y/	## #$$% 
 $$&	+	i@R@,,=     !% 5 5 ; ; =%C99 11 S%D!
 #%s   *Cc           
     >   |j                  d| j                        }|j                  dvrt        j                  d      |j                  dk(  r|j
                   }|j                  dk7  sJ |j
                  r$|j                  dk(  rt        j                  d      |j                  }	|	J |j                  J t        |	t        dt        |t              r|gn|      |j                  d	d	||
      }
| j                  ||||||
      S t        | A  ||||||      S )Nr  )r&  r  rY   r%  zOValid strategies for ORM UPDATE strategy are 'orm', 'auto', 'bulk', 'core_only'rY   r)  r(  zbulk synchronize of persistent objects not supported when using bulk update with additional WHERE criteria right now.  add synchronize_session=None execution option to bypass synchronize of persistent objects.r  F)r@   r   r   r   )r   r  r  r,  r.  ro  r  r-  r  r  r   r   r   r`   r<  r  r  )r   r]   r   rN   rD   r   rP   r5  r   r=   r   r  s              rE   r  z#BulkORMUpdate.orm_execute_statement  sa    +..$c&@&@
 '' 0
 
 &&9  ''61(1(A(A$A!!66'AA ))"77:E00  $33F%%''33!. *64 8VHf $$$)$-&;F ..!  70! rG   Fr  c                   |j                   xr |j                  j                  }|sy|r|j                  S |r|j                  S |r/|j                  s#t        j                  d|j                   d      y)NF	Dialect "z" does not support RETURNING with UPDATE..FROM; for synchronize_session='fetch', please add the additional execution option 'is_update_from=True' to the statement to indicate that a separate SELECT should be used for this backend.T)update_returningr   implicit_returningupdate_executemany_returningupdate_returning_multifromr,  r  r   r   r  r=   r  r  r  r  normal_answers           rE   r  zBulkORMUpdate.can_use_returningZ  s     $$N););)N)N 	 777 5557#E#E%%GLL> *E E  rG   c                   |sy |j                   }|j                  D cg c]  }|j                   }}|j                  }|D ]  |j	                  fd|D        |j
                        }	|j                  |	      }
|
s=t              j                  |      }|
j                  }|
j                  j                  |      }|D ]  }||v s|   ||<    |
j                  j                  j                  |
d |       |
j                  |t!        |             |j                  |      j                  |      }|s|
j#                  ||        y c c}w )Nc              3  (   K   | ]	  }|     y wr:   r;   )rK   rg   params     rE   rU   zCBulkORMUpdate._do_post_synchronize_bulk_evaluate.<locals>.<genexpr>  s     /s/rP  )r  rn   rg   identity_mapidentity_key_from_primary_keyr  fast_get_stater   
differencer`   
unmodifiedr   managerdispatchrefresh_commitr   _expire_attributes)r   r]   rN   r   r5  r=   proppk_keysr  identity_keyrL   evaluated_keysrq   to_evaluaterg   	to_expirer  s                   @rE   r;  z0BulkORMUpdate._do_post_synchronize_bulk_evaluate  sH    //(.(B(BC488CC++ 	;E!??/w/..L !//=E Z227;NJJE**77GK" ,%<!&sE#J, MM""**5$DMM%k!23
 '33E:EEI ((	:;	;	 Ds   Ec                    | j                  ||j                  j                               }| j                  ||||D 	cg c]  \  }}}}	|||f c}	}}}       y c c}	}}}w r:   )rk  r  
all_states#_apply_update_set_values_to_objects)
r   r]   r   r   r5  matched_objectsre  rL   rq   r  s
             rE   r9  z+BulkORMUpdate._do_post_synchronize_evaluate  si     >>  ++-

 	//=LMM%9S%c5% M		
 Ns    Ac                   |j                   }|j                  }|r9| j                  ||      }|D cg c]  }t        |      |j                  fz    }	}n|j
                  }	|	D cg c]  }|dd |d   f c}D 
cg c]<  \  }
}|j                  ||j                  k(  r|j                  t        |
      |      > c}}
D cg c]  }||j                  v r|j                  |   ! }}|sy | j                  ||||D cg c]-  }|t        j                  |      t        j                  |      f/ c}       y c c}w c c}w c c}}
w c c}w c c}w Nr   )r!  )r  returned_defaults_rowsra  ro   r  r  r  r   r  r   r   instance_stateinstance_dict)r   r]   r   r   r5  target_mapperr  pk_rowsrO  r  r   r!  r  objsre  s                  rE   r:  z(BulkORMUpdate._do_post_synchronize_fetch  s    '66!'!>!>!335G # c
n<<>>L 
 *77L 5A4-0S2YB(4
!
 0K "119!^%C%CC ;;%#1 < 
!
 w333   .
 
  //   	 --c2,,S1		
54
!
.s    D7$D<;AE$E=2Ec                   |j                   }|j                  }t        j                  |      }| j	                  ||      }| j                  ||      }	i }
|	D ]>  \  }}	 |j                  t        j                  t        j                  |            }||
|<   @ t        |
j                               }|	D ch c]  \  }}|	 }}}t               }|D ]  \  }}}|j                  j!                  |      }|D ]  }||v s |
|   |      ||<    |j"                  j$                  j'                  |d|       |j)                  |t        |             |j!                  |      j+                  |      }|r|j-                  ||       |j/                  |        |j1                  |       y# t        j                  $ r Y gw xY wc c}}w )zeapply values to objects derived from an update statement, e.g.
        UPDATE..SET <values>

        N)r  r   r   rn  r  r  rr  r   r   r    r   rx  r   r   r   r  r   r  r  r  r  r  r  add_register_altered)r   r]   r5  r   r  r=   rs  rt  r  resolved_keys_as_propnamesvalue_evaluatorsrg   value
_evaluatorr  r   r   attribrp   re  rL   rq   r  r  s                           rE   r   z1BulkORMUpdate._apply_update_set_values_to_objects  s     //]]
&99*E2269E%(%D%DO&
" 4 	3JC3/77$$U%@%@%H
 )3 %	3 .3356 :;1!;;!0 	C**77GK" <%<!6!1#!6s!;E#J<
 MM""**5$DMM%k!23
 ++E2==kJI((	:JJu'	( 	!!&); //  <s   3F'5G'F>=F>)r]   r1   r   z
dml.UpdaterN   r6   rD   r,   r   r/   rP   r4   r  r  r  )r   r   r   r  r   r  r  r  r  r;  r9  r:  r   r  r  s   @rE   r  r  r  s=    ,]"~"#H II I &	I
 6I 'I I 
I IV  $$ %$"" "
 " " " " 
" "H (; (;T 
 
 1
 1
f 1* 1*rG   r  deletec                       e Zd Zed        Ze	 	 	 	 	 	 	 	 	 	 	 	 	 	 d fd       Zeddddd	 	 	 	 	 	 	 	 	 	 	 	 	 d	d       Zed        Zed        Z xZ	S )
BulkORMDeletec           	        | j                  |       }|j                  j                  dd      }|dk(  s|dk(  r2d|j                  j                  vrt	        j
                  |||fi | |S |j                   }|}|j                  j                  d   }|j                  x|_        }	|j                  ||||       |j                         }
| j                  |j                  |	      }|r |
j                  | }
t	        j
                  ||
|fi | d}|sd }n|j                  j                  dd       }|j                  j                  dd       }|durJ|d	k(  xrC |j                  |j                  |	|j                  |j                  j                  d
d            }|r%d} |
j                   |
j                  j"                   }
|r|j%                  |||
|	|      }
|
|_        |S )Nr   r  r%  r   r  Fr"  r  r)  r  )r  r  Tr  )r  r   r   rt   r&   r  r  r=   r  r  rK  rI  r  r  r  r  rA   r   r   r   )r   r   r   r  r   r   r  r   r   r=   r  r  r   r"  r  s                  rE   r   z"BulkORMDelete.create_for_statement%  s   {{3 --11M

 K'},ioo&B&BB##D)XDDK~~%'??//?'.f$$*2	 	% 	
 ##%11""F
 %x~~x0H 	h?B? %"&"*"7"7";";%t# %1155
 E) $w. **$$"&"4"4$,$9$9$=$=)5%	 +   $(!/x//1K1KLH00#!&; 1 H "rG   c                    |j                  d| j                        }|j                  dk(  rt        j                  d      |j                  dvrt        j
                  d      t        |   ||||||      S )Nr  rY   zBulk ORM DELETE not supported right now. Statement may be invoked at the Core level using session.connection().execute(stmt, parameters))r&  r  r%  zGValid strategies for ORM DELETE strategy are 'orm', 'auto', 'core_only')r   r  r  r,  r-  r.  r  r  )	r   r]   r   rN   rD   r   rP   r5  r  s	           rE   r  z#BulkORMDelete.orm_execute_statement~  s     +..$c&@&@
 ''61,,A  ''/KK&& 
 w,Y(9>4
 	
rG   Fr  c                   |j                   xr |j                  j                  }|sy|r|j                  S |r/|j                  s#t	        j
                  d|j                   d      y)NFr  z" does not support RETURNING with DELETE..USING; for synchronize_session='fetch', please add the additional execution option 'is_delete_using=True' to the statement to indicate that a separate SELECT should be used for this backend.T)delete_returningr   r  delete_returning_multifromr,  r  r   r  s           rE   r  zBulkORMDelete.can_use_returning  sz     $$N););)N)N 	   5557#E#E %%GLL> *E E  rG   c                   | j                  ||j                  j                               }g }|D ]A  \  }}}	}
|
r'|j                  |	|j                  j                         1|j                  |       C |r|j                  |       y y r:   )rk  r  r  _expire	_modifiedrg  _remove_newly_deleted)r   r]   r   r   r5  r  	to_deleter  rL   rq   is_partially_expireds              rE   r9  z+BulkORMDelete._do_post_synchronize_evaluate  s     >>  ++-

 	5D 	(1Aue1#eW%9%9%C%CD  '		( )))4 rG   c                   |j                   }|j                  }|r9| j                  ||      }|D cg c]  }t        |      |j                  fz    }	}n|j
                  }	|	D ]i  }|dd }
|d   }|j                  t        |
      |      }||j                  v s8|j                  t        j                  |j                  |         g       k y c c}w r  )r  r  ra  ro   r  r  r  r   r  r  r   r  )r   r]   r   r   r5  r  r  r	  rO  r  r   r!  r  s                rE   r:  z(BulkORMDelete._do_post_synchronize_fetch  s     '66!'!>!>!335G # c
n<<>>L 
 *77L 	Ca)K WN )FF[!- G L w333--"11#00>	s    C)r]   r1   r   z
dml.DeleterN   r6   rD   r,   r   r/   rP   r4   r  r  r  )
r   r   r   r  r   r  r  r9  r:  r  r  s   @rE   r  r  #  s    V Vp 

 
 &	

 6
 '
 
 

 
>  $$ %$&& &
 & & & & 
& &P 5 5& $ $rG   r  )..)r=   
Mapper[_O]r>   <Union[Iterable[InstanceState[_O]], Iterable[Dict[str, Any]]]r?   r2   r@   r	  rA   r	  rB   r	  rC   Literal[None]rD   $Optional[OrmExecuteOptionsParameter]r  None)r=   r"  r>   r#  r?   r2   r@   r	  rA   r	  rB   r	  rC   Optional[dml.Insert]rD   r%  r  zcursor.CursorResult[Any])NN)r=   r"  r>   r#  r?   r2   r@   r	  rA   r	  rB   r	  rC   r'  rD   r%  r  z"Optional[cursor.CursorResult[Any]]).T)r=   r  r>   r#  r?   r2   r@   r	  r   r	  r   r$  r   r	  r  r&  )r=   r  r>   r#  r?   r2   r@   r	  r   r	  r   Optional[dml.Update]r   r	  r  z_result.Result[Any]rc  )r=   r  r>   r#  r?   r2   r@   r	  r   r	  r   r(  r   r	  r  zOptional[_result.Result[Any]])O__doc__
__future__r   typingr   r   r   r   r   r	   r
   r   r    r   r   r   r   r  r   r   baser   r   r   r   r   r,  r   enginer   r   r   sqlr   r   r   r    r!   r"   sql.baser#   r$   r%   sql.dmlr&   r'   r(   r)   util.typingr*   _typingr+   r,   r-   r=   r.   r]   r/   r0   r1   r2   rL   r3   r4   r5   engine.interfacesr6   objectr7   rF   r   ra   r   r  
plugin_forr  r  r  r;   rG   rE   <module>r7     s  
 #                  , " 1 !    &       , #  $ $ $  !,33'( +$#9T  
 *->A		J	 ,	 		
 	 	 '	 <	 
	 
	 
 14>A	#	#J	# ,	# 		#
 	# 	# .	# <	# 	# 
	#& 15>B}}J} ,} 	}
 } } .} <} (}@ 
 *-"&J , 	
  '   
 
 
 14"&J , 	
  .    
" 15"&X%X%JX% ,X% 	X%
 X% .X%  X% #X%v%s) slO
 O
d )@#K @# *@#F )m*& m* *m*` )\& \ *\rG   