
    `gj                    z   d 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	m
Z
mZmZmZ ddlmZ ddlmZ ddlmZ dd	lmZmZ  ej.                  e      Z	 	 	 	 	 	 	 	 dd
ZddZddZddZddZddZddZ 	 	 	 	 	 	 	 	 	 	 ddZ!	 	 	 	 	 	 	 	 	 	 d dZ"e G d d             Z#	 d!dd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d"dZ$y)#u?  Per-turn setup for ``run_conversation`` (the turn prologue).

``run_conversation`` opened with ~470 lines of straight-line setup before the
tool-calling loop ever started: stdio guarding, runtime-main wiring, retry-counter
resets, user-message sanitization, todo/nudge-counter hydration, system-prompt
restore-or-build, session-row creation (before compression, whose DB writes
reference the row), preflight context compression, the ``pre_llm_call`` plugin
hook, external-memory prefetch, and crash-resilience persistence (last, so the
user row is written once with its final ``api_content`` sidecar).

All of that is *prologue* — it runs once per turn, has no back-references into the
loop, and produces a fixed set of values the loop then consumes. ``TurnContext``
captures those produced values; ``build_turn_context`` performs the setup work and
returns one. ``run_conversation`` is left to unpack the context and run the loop,
shrinking the orchestrator by the full prologue.

The builder still mutates ``agent`` heavily (counters, thread id, cached prompt,
session DB) exactly as the inline code did — those side effects are the point. The
``TurnContext`` it returns carries only the *locals* the loop reads back.

Behavior is identical to the original inline prologue; this is a pure
move-and-name refactor with no semantic change.
    )annotationsN)	dataclass)AnyDictListMappingOptional)&conversation_history_after_compression)IterationBudget)build_memory_context_block)estimate_messages_tokens_roughestimate_request_tokens_roughc                    t        | t              syg }|rt        |      }|r|j                  |       |r|j                  |       |sy| dz   dj	                  |      z   S )ue  Compose the API-bound content of the current turn's user message.

    Sources: memory-manager prefetch + ``pre_llm_call`` plugin context with
    target="user_message" (the default). Both are appended to the *API copy*
    of the user message only — the stored content stays clean.

    This is the single source of that composition. The prologue stamps the
    result onto the live message as ``api_content`` (persisted alongside the
    clean content) and the ``api_messages`` build in ``conversation_loop``
    sends the same helper's output, so the persisted sidecar can never drift
    from the bytes on the wire — which is the whole prompt-cache invariant:
    what turn N sends must be what turn N+1 replays.

    Returns ``None`` when nothing is injected (multimodal/non-string content,
    or no ephemeral context), meaning the message is sent as-is.
    N

)
isinstancestrr   appendjoin)contentext_prefetch_cacheplugin_user_context
injectionsfenceds        E/root/.hermes/venv/lib/python3.12/site-packages/agent/turn_context.pycompose_user_api_contentr   ,   sf    * gs#J+,>?f%-.Vfkk*555    c                ~    | j                  dd      }t        |t              r|r| j                  d      dv r|| d<   |S )a}  Pop the ``api_content`` sidecar and substitute it into ``content``.

    Used at every API-bound message-build site (the ``api_messages`` build in
    ``conversation_loop``, the max-iterations summary in
    ``chat_completion_helpers``, the chat-completions transport). The sidecar
    carries the exact bytes previously sent to the API for this message when
    they differ from the clean stored content; substituting it here keeps the
    provider prompt-cache prefix byte-stable across turns.

    Returns the popped sidecar string (for callers that need the value for
    current-turn composition logic) or ``None`` when absent.
    api_contentNrole)user	assistantr   )popr   r   get)api_msgsidecars     r   substitute_api_contentr&   O   sB     kk-.G7C KK#88$	Nr   c                (    | j                  dd       y)u  Drop the ``api_content`` sidecar from a message whose content was rewritten.

    Called from every content-rewrite path (historical image strip,
    merge-summary-into-tail, consecutive-user repair merge, stale-confirmation
    redaction). Replaying the pre-rewrite sidecar would resend exactly what
    the rewrite removed, so it must be dropped — the cost is one cache
    boundary miss, never wrong content.
    r   N)r"   )msgs    r   drop_stale_api_contentr)   f   s     GGM4 r   c                L    | j                  d      }t        |t              r|S dS )zExtract the ``api_content`` sidecar from a message dict for persistence.

    Shared by the gateway/branch forwarding sites that copy the sidecar into a
    new row. Returns the string sidecar or ``None`` when absent/non-string.
    r   N)r#   r   r   )r(   vs     r   extract_api_content_sidecarr,   r   s&     	A1c"1,,r   c                    t        | dd      xs d}t        | d      r	 d| _        t	        |t
              r|S dS # t        $ r Y w xY w)aM  Pop the gateway's per-turn must-deliver notes off the agent (one-shot).

    The gateway relocates volatile per-turn facts OUT of the ephemeral system
    prompt (auto-reset notes, the first-contact intro, voice-channel changes)
    and delivers them on the current user message via the api_content sidecar
    instead, so the composed system prompt stays byte-stable turn-over-turn.
    It stages the rendered notes on ``agent._gateway_turn_context_notes``
    right before ``run_conversation``; this consumes them so a cached agent
    can never replay a stale note on a later turn.
    _gateway_turn_context_notes )getattrhasattrr.   	Exceptionr   r   )agentnotess     r   "consume_gateway_turn_context_notesr5   |   sZ     E8"=CEu34	02E- uc*522  		s   : 	AAc                r    |rt        | t              sy	 | j                  d|d       y# t        $ r Y yw xY w)u  Deliver must-deliver notes on a multimodal (list) user message.

    ``compose_user_api_content`` returns ``None`` for non-string content, so
    sidecar-borne facts would silently drop on image/attachment turns.  For
    gateway must-deliver notes we instead append a text part to the content
    list in place — the part becomes durable message content (persisted and
    replayed as-is), which keeps the wire and the transcript byte-identical.

    Returns ``True`` when a part was appended.
    Ftext)typer7   T)r   listr   r2   )r   r4   s     r   "append_notes_to_multimodal_contentr:      s>     
7D167 s   * 	66c                    d}t        t        |       dz
  dd      D ]K  }| |   }t        |t              r|j	                  d      dk(  s-|dk  r|}|j	                  d      |k(  sI|c S  |S )u  Locate this turn's user message after compaction rebuilt ``messages``.

    Compression replaces list entries with fresh copies (and may append a
    todo-snapshot user message or a restored user turn AFTER the surviving
    copy of the current turn's message), so a pre-compression index is
    meaningless. Prefer the LAST user message whose content exactly matches
    this turn's text — the surviving copy in the common case — so the
    injection stamp and the #48677 persist override can't land on a
    todo-snapshot or historical row. Fall back to the last user message when
    no exact match survives (merge-summary-into-tail rewrites the content but
    the trackers still need a live anchor). Returns -1 when the list has no
    user message at all.
       r   r    r   r   )rangelenr   dictr#   )messagesuser_messagefallbackir(   s        r   reanchor_current_turn_user_idxrE      sx     H3x=1$b"- qk3%#''&/V*Ca<H779-H Or   c                ,    || k  ry|dkD  xr ||dz  k  S )uF  Return ``True`` if a compression pass materially reduced the request.

    Compression can succeed by summarising message contents — reducing the
    estimated request token count — without reducing the message row
    count.  Treating row count as the sole progress signal false-positives
    on size-only wins and surfaces a misleading "Cannot compress further"
    failure even when post-compression tokens are well below the model
    context window.  See issue #39548 for an observed case: 220 → 220
    messages, ~288k → ~183k tokens on a 1M-context model still triggered
    auto-reset.

    The token reduction must be *material* (>5%) to count as progress — the
    same floor the overflow-handler retry path uses (conversation_loop.py,
    #39550) — so a sub-5% wobble doesn't keep the multi-pass loop spinning.
    Tr   gffffff? )orig_lennew_lenorig_tokens
new_tokenss       r   _compression_made_progressrL      s(    $ ?>zK$,>>>r   c                H    t        |       ||z   dz   kD  ryt        |       |k\  S )u  Cheap gate for the (expensive) full preflight token estimate.

    Returns ``True`` when either:
      (a) message count exceeds the protected ranges (the historical gate), or
      (b) a cheap char-based estimate already crosses the configured threshold
          — the few-but-huge case from issue #27405 that the count-only gate
          would silently skip (a handful of very large messages never trips
          the count condition, so compression was never attempted and the
          turn hit a hard context-overflow error).

    Branch (b) uses ``estimate_messages_tokens_rough`` (the shared char-based
    estimator) so a single large base64 image isn't mistaken for ~250K tokens.
    It intentionally undercounts vs. the full request estimate — it omits the
    system prompt and tool schemas — because it is only a *hint* deciding
    whether to pay for the authoritative ``estimate_request_tokens_rough``,
    which (together with ``should_compress``) makes the real decision.
    r=   T)r?   r   )rA   protect_first_nprotect_last_nthreshold_tokenss       r   _should_run_preflight_estimaterQ      s.    . 8}7!;;)(37GGGr   c                      e Zd ZU dZded<   ded<   ded<   ded	<   d
ed<   ded<   ded<   ded<   dZded<   dZded<   dZded<   y)TurnContextzCValues produced by the turn prologue and consumed by the turn loop.r   rB   r   original_user_messageList[Dict[str, Any]]rA   Optional[List[Dict[str, Any]]]conversation_historyOptional[str]active_system_prompteffective_task_idturn_idintcurrent_turn_user_idxFboolshould_review_memoryr/   r   r   N)__name__
__module____qualname____doc____annotations__r_   r   r   rG   r   r   rS   rS      sW    M ""88''L!&$&!!  r   rS   F)
moa_activec                  H  |	         | j                           |t         dd              j                          	 ddlm}  |t         dd      xs dt         dd      xs dt         dd      xs dt         d	d      xs dt         d
d      xs dt         dd      xs d       	 t         dd      s+ddl}d|j                  v rddlm	}m
}  |       r
 | d       t        |t              r |
|      }t        |t              r |
|      }| _        d _        | _        | _        |xs t        t'        j(                               }| _         j                   xs d d| dt'        j(                         j,                  dd  }| _        d _        ddlm}  | |       d _        d _        d _        d _        d _        d _         d _!        d _"        d _#        d _$        d _%         jL                  jO                          d _(        t         jR                  dd      }tU        |      r |        d _+         jX                  dk7  r"	  j[                         r j]                  d        j^                  r ja                          d _/        tc         jd                         _3         ||      }ti        |      dkD  r|dd dz   n|}|jk                  dd       }t        jm                  d! j                   xs d" jn                   jp                  xs d# jr                  xs d#ti        xs g       |       rtu              ng Ht         d$d      }||n|}t        |tv              r|jy                  d%      |k(  r|}||d%<   nd&|d'}t        |tv              rd _=        r+ j|                  j                         s j                         r_ j                  dk(  rPt        d( D              }|dkD  r9| _A         j                  dkD  r# j                  dk(  r| j                  z   _D        Hj                  |       ti        H      d)z
  }| _         xj                  d)z  c_A        d _F        t         d*d      }||j                          t         d+d      } | | j                          ||n|}!d}" j                  dkD  rQd, j                  v rC jR                  r7 xj                  d)z  c_D         j                   j                  k\  r	d}"d _D        t         d-d      }#|#	 dd.lImJ}$  |$|!      }%|%r |#|%        j                  s2 ||      }& j                  d/|&dd0  ti        |&      d0kD  rdnd d1        j                  
 | |        j                  }'t         d2d      }(	 |( j                          n|(5   j                          ddd       t        |tv              r|jy                  d4      rd _=        	 d}) j                  rt        H j                  j                   j                  j                   j                  j                        rrt        H|'xs d j                  xs d5      }* j                  }+t        |+d6d7       }, |,|*      }-t         d
d      d8k(  xr* t        t         d9d:      xs d:      j                         d;v }.|-s|+j                  }/|/dk\  r|*|/kD  r|*|+_Y         t        |+d<d=              }0|-r4t        jm                  d>|*d?|+j                  d?|+j                  d?       n|0r@t        jm                  d@t        |0jy                  dAdB             j                   xs d"       nJ|.r#t        jm                  dCt         d9d:             n%|+j                  |*      rd})t        jm                  dD|*d?|+j                  d? jn                  |+j                  d?        j]                  dE|*d?dF|+j                  d?dG       t        dH      D ]  }1ti        H      }2|*}3 j                  H||*|I      \  H}'t        H|'xs d j                  xs d5      }*t        |2ti        H      |3|*      s nDt         H      d _        d _         d _"        d _#        d _$        |+j                  |*      r n |)rt        H|      }| _        d}4	 ddJlcmd}5  |5dK j                   |||!tu        H      t                jn                  t         dLd      xs dt         dMd      xs dN
      }6g }7	 ddOlfmg}8mh}9  |8       }:|6D ]  };d}<t        |;tv              r |;jy                  dP      rt        |;dP         }<n$t        |;t              r|;j                         r|;}<nY|9	  |9|< j                   dQ|:R      }<|7j                  |<        |7rdTj                  |7      }4t               }?|?rid|cxk  rti        H      k  r*n n't        H|   tv              rH|   jy                  d%      nd}@t        |@tt              rt        @|?       n|4r|4dTz   |?z   n|?}4i  _m        t                _o        d _p        d _q        t        j                         j                   _u         |       j                  d j                          j                  r) |       j                  d j                         d _x        nd _y        d _x         j                  r;	 t        |!t              r|!nd}A j                  j                   j                  |A       d}B j                  r4	 t        |!t              r|!nd}C j                  j                  |C      xs d}B|st         d
d      d8k7  rd|cxk  rti        H      k  rn nH|   jy                  dV      d&k(  rH|   }Dt        |Djy                  d%d      B|4      }E|EmEDjy                  d%      k7  rYEDdW<   |)rRt        t         dXd            r<t         dYd      }F|F-	 Fj                   j                   Djy                  d%      E       d^ Hfd[}G	 |( G        n|(5   G        ddd       t        |tv              r|jy                  d4      rd _=        	 t        ||!H|'||||"|4B]      S # t
        $ r Y @w xY w# t
        $ r t        j                  dd       Y .w xY w# t
        $ r Y 
w xY w# t
        $ r Y w xY w# 1 sw Y   VxY w# t
        $ r* t        j                  d3 j                   xs d"d       Y w xY w# t        |tv              r|jy                  d4      rd _=        w w xY w# t
        $ r d}9d}:Y Qw xY w# t
        $ r!}=t        j                  dS|=       Y d}=~=d}=~=ww xY w# t
        $ r!}>t        j                  dU|>       Y d}>~>d}>~>ww xY w# t
        $ r Y w xY w# t
        $ r Y w xY w# t
        $ r* t        j                  dZ j                   xs d"d       Y w xY w# 1 sw Y   xY w# t
        $ r* t        j                  d\ j                   xs d"d       Y 
w xY w# t        |tv              r|jy                  d4      rd _=        w w xY w)_a  Run the once-per-turn setup and return the loop's input context.

    The callables/helpers the original prologue referenced from the
    ``conversation_loop`` module are passed in explicitly to keep this module
    free of an import cycle with ``agent.conversation_loop``.
    _memory_write_originassistant_toolr   )set_runtime_mainproviderr/   modelbase_urlapi_keyapi_mode	auth_mode)rl   rm   rn   ro   _skip_mcp_refreshFNztools.mcp_tool)has_registered_mcp_toolsrefresh_agent_mcp_toolsT)
quiet_modez&between-turns MCP tool refresh skipped)exc_infosession:   )note_turn_startreset_consolidation_failuresanthropic_messagesu~   🔌 Detected stale connections from a previous provider issue — cleaned up automatically. Proceeding with fresh connection.P   z...
 zPconversation turn: session=%s model=%s provider=%s platform=%s history=%d msg=%rnoneunknown_pending_cli_user_messager   r    )r   r   c              3  J   K   | ]  }|j                  d       dk(  sd  yw)r   r    r=   N)r#   ).0ms     r   	<genexpr>z%build_turn_context.<locals>.<genexpr>  s$      
quuV}/FA
s   ##r=   _stream_context_scrubber_stream_think_scrubbermemoryreaction_callback)detect_reactionu   💬 Starting conversation: '<   '_session_persist_lockz5Turn-start session row creation failed for session=%s_db_persisted)system_prompttools$should_defer_preflight_to_real_usagec                     y)NFrG   )_tokenss    r   <lambda>z$build_turn_context.<locals>.<lambda>G      r   codex_app_server codex_app_server_auto_compactionnative>   offr   'get_active_compression_failure_cooldownc                      y NrG   rG   r   r   r   z$build_turn_context.<locals>.<lambda>b  r   r   zpSkipping preflight compression: rough estimate ~%s >= %s, but last real provider prompt was %s after compression,z`Skipping preflight compression: same-session cooldown active (~%s seconds remaining, session %s)remaining_secondsg        zsSkipping Hermes preflight compression for codex app-server (mode=%s); Hermes will not start thread compaction here.zDPreflight compression: ~%s tokens >= %s threshold (model %s, ctx %s)u   📦 Preflight compression: ~z tokens >= z# threshold. This may take a moment.   )approx_tokenstask_id)invoke_hookpre_llm_callplatform_user_id)	
session_idr   r[   rB   rW   is_first_turnrk   r   	sender_id)get_spill_configspill_if_oversizedcontextzplugin hook)r   sourceconfigzhook context spill failed: %sr   zpre_llm_call hook failed: %sr   r   _last_compaction_in_place_session_dbz>in-place compaction api_content backfill failed for session=%sc                 J     j                           j                         y r   )_ensure_db_session_persist_session)r3   rW   rA   s   r   _ensure_and_persistz/build_turn_context.<locals>._ensure_and_persistc  s       "x)=>r   z:Early turn-start session persistence failed for session=%s)rB   rT   rA   rW   rY   rZ   r[   r]   r_   r   r   )returnNone)r   r0   _restore_primary_runtimeagent.auxiliary_clientri   r2   sysmodulestools.mcp_toolrq   rr   loggerdebugr   r   _stream_callback_persist_user_message_idx_persist_user_message_override_persist_user_message_timestampuuiduuid4_current_task_idhex_current_turn_id_current_api_request_idagent.agent_runtime_helpersrx   _invalid_tool_retries_invalid_json_retries_empty_content_retries_incomplete_scratchpad_retries_codex_incomplete_retries_thinking_prefill_retries_post_tool_empty_retried_last_content_with_tools$_last_content_tools_all_housekeeping_mute_post_response_unicode_sanitization_passes_tool_guardrailsreset_for_turn_tool_guardrail_halt_decision_memory_storecallable_vision_supportedrn   _cleanup_dead_connections_emit_status_compression_warning_replay_compression_warningr   max_iterationsiteration_budgetr?   replaceinfork   rj   r   r9   r@   r#   r   _todo_store	has_items_hydrate_todo_store_user_turn_countsum_memory_nudge_interval_turns_since_memoryr   _is_user_initiated_turnresetvalid_tool_namesagent.reactionsr   rs   _safe_print_cached_system_promptr   warningcompression_enabledrQ   context_compressorrN   rO   rP   r   r   lowerlast_prompt_tokenslast_real_prompt_tokensr\   should_compresscontext_lengthr>   _compress_contextrL   r
   rE   hermes_cli.pluginsr   r^   tools.hook_output_spillr   r   stripr   r5   r:   _turn_failed_file_mutationsset_turn_file_mutation_paths_verification_stop_nudges_pre_verify_nudges	threadingcurrent_threadident_execution_thread_id_set_interrupt_interrupt_requested _interrupt_thread_signal_pending_interrupt_message_memory_manageron_turn_startprefetch_allr   set_latest_user_api_contentrS   )Ir3   rB   system_messagerW   r   stream_callbackpersist_user_messagepersist_user_timestamprestore_or_build_system_promptinstall_safe_stdiosanitize_surrogatessummarize_user_message_for_logset_session_contextset_current_write_originrare   ri   _sysrq   rr   rZ   r[   rx   _reset_consol_preview_text_msg_previewpending_cli_messageexpected_persist_contentuser_msgprior_user_turnsr]   scrubberthink_scrubberrT   r_   r   r   kind_print_previewrY   persist_lock_preflight_compressed_preflight_tokens_compressor_defer_preflight_preflight_deferred_codex_native_auto_last_compression_cooldown_pass	_orig_len_orig_tokensr   _invoke_hook_pre_results
_ctx_parts
_spill_cfg_spill_if_oversized_spill_config_cachedr_piece
_spill_excexc_gateway_notes_gw_turn_content	_turn_msgr   _query_turn_user_msg_api_content_dbr   rA   sI   `  `                                                                    @r   build_turn_contextr>    s   4  (() WU,BDTUV 
""$;E:r*0bE7B'-2UJ39rE9b17RUJ39re["5;	
*Nu159 4<</\+-+EdC
 ,$*<8&,23GH -E&*E#+?E(,BE)43tzz|#4.E!!.Y/q1B0C1TZZ\EUEUVXWXEYDZ[G$E$&E! <E7# #$E"#E#$E +,E(&'E#&'E#%*E"%)E"16E. %E)*E&	))+*.E'E//1OQUVM"E ~~--	..0""" !!))+%)" -U-A-ABE 3<@M36}3E3JM#2&.P]L''c2L
KKZ"FEKK1L9#)S)=)C%D	 .Bt()rH "%)DdK 4 @l  	&-##I.2JJ& +"|<)40.2E+ E$5$5$?$?$A!!"67  6 6! ; 
+
 
 a%5E"++a/E4M4MQR4R,<u?[?[,[)
 OOHMA-&;E# 
a %)E! u8$?HU$<dCN! 5I4T0Zf !$$q(E222##!!Q&!$$(D(DD#' ()E%
  ':DA$	7"#89D!$' 7E+N3B,?+@N+b0ub9<	
 ""*&un>RS 66 5"94@L3$$& +((*+ -t48K8O8OP_8`.2E+ "  %C  00  //  11	& :.4"++%

 .."2!

 //@A E:t,0BB 	!6 
  eg ! 	 #22Ez/%71B.!
5!
 ! KKI$Q'//266q9 #KK6)--.A3GH  *F	  KKKA8L
 (():;$(!KKV$Q'//2--a0 /0A!/D E!2215 6**
 q M	0161H1Hn<M- 2I 2.. %B"6"<"++-%!
 2s8}l<M 'M8($ 01,23/15.=B:,1)"223DE;>  !?l!
 +@' 1<B#''%.!%h#$899++UJ5;eZ6<"
 !#
	( $.<   	&AF!T"quuY'7Qy\*As#	".P0#(#3#3,3	F f%%	&& "(++j"9 8>N )9CM98$9:DA *+//	: 	 	 &-./?P ' $f,~=#   )+E%&)eE#&'E# E "+!9!9!;!A!AE Du99:!!
D%"<"<=16.#' 16. 	1;<QSV1W-]_I!!//0F0F	R
 	.89NPS.T*Z\F!&!6!6!C!CF!K!Qr, E:t,0BB&6X6*+//76A!"78/y"-/ACV
 #8J8J98U(U,8N=) %:EB* e]D9?77!,,*..y9((?3! &#%& -t48K8O8OP_8`.2E+!311+31/- k  8  N=MNl  		V  		@+ + 
C& 	 	

 -t48K8O8OP_8`.2E+ 9a|  	("&#' 	(& ! PNN#BJOOP
  <5s;;<d  		  		f % -!,,6%)	 ' .& & 
H& 	 	

 -t48K8O8OP_8`.2E+ 9as_  A.s# 08s3 !t :t*  u t:&u ;Aw, v+ *Aw, v?&w, 2:x ;3x) ,x9 y< y/y< #	s0/s03 tt	t'&t'*	t76t7:u?u /u:6u= 9u::u= =+v(+v<8w, ;v<<w, ?	w)w$w, $w))w, ,	x5xx	x&%x&)	x65x69/y,+y,/y94y< </z/+z2 .z//z2 2+{)r   r   r   r   r   r   r   rX   )r$   Dict[str, Any]r   rX   )r(   r?  r   r   )r(   zMapping[str, Any]r   rX   )r3   r   r   r   )r   r   r4   r   r   r^   )rA   z	List[Any]rB   r   r   r\   )
rH   r\   rI   r\   rJ   r\   rK   r\   r   r^   )
rA   rU   rN   r\   rO   r\   rP   r\   r   r^   r   )rB   r   r
  rX   rW   rV   r   rX   r  zOptional[Any]r  zOptional[float]re   r^   r   rS   )%rc   
__future__r   loggingr   r   dataclassesr   typingr   r   r   r   r	   agent.conversation_compressionr
   agent.iteration_budgetr   agent.memory_managerr   agent.model_metadatar   r   	getLoggerr`   r   r   r&   r)   r,   r5   r:   rE   rL   rQ   rS   r>  rG   r   r   <module>rI     sw  0 #    ! 5 5 Q 2 ;
 
		8	$ 6 6 6  6 	 6F.	!-3((4???.1??B?	?.H"HH H 	H
 
H8 ! ! !D /3z	" #z	z	 "z	 9	z	
 z	 (z	 ,z	" #z	$ %z	r   