
    PL
jBy                       U d Z ddlmZ ddlZddlZddlZddlZddlmZm	Z	m
Z
 ddlmZmZ ddlmZmZmZmZmZ  ej        e          ZdZdZd	Zd
ZdZdZdZdZdZdZe G d d                      Z d6dZ!i Z"de#d<   d7dZ$d8dZ%d9dZ&d:d Z'd;d$Z( ej)        d%ej*                  Z+d<d&Z,d=d)Z-edd*d>d2Z. G d3 d4          Z/g d5Z0dS )?un  Persistent session goals — the Ralph loop for Hermes.

A goal is a free-form user objective that stays active across turns. After
each turn completes, a small judge call asks an auxiliary model "is this
goal satisfied by the assistant's last response?". If not, Hermes feeds a
continuation prompt back into the same session and keeps working until the
goal is done, turn budget is exhausted, the user pauses/clears it, or the
user sends a new message (which takes priority and pauses the goal loop).

State is persisted in SessionDB's ``state_meta`` table keyed by
``goal:<session_id>`` so ``/resume`` picks it up.

Design notes / invariants:

- The continuation prompt is just a normal user message appended to the
  session via ``run_conversation``. No system-prompt mutation, no toolset
  swap — prompt caching stays intact.
- Judge failures are fail-OPEN: ``continue``. A broken judge must not wedge
  progress; the turn budget is the backstop.
- When a real user message arrives mid-loop it preempts the continuation
  prompt and also pauses the goal loop for that turn (we still re-judge
  after, so if the user's message happens to complete the goal the judge
  will say ``done``).
- This module has zero hard dependency on ``cli.HermesCLI`` or the gateway
  runner — both wire the same ``GoalManager`` in.

Nothing in this module touches the agent's system prompt or toolset.
    )annotationsN)	dataclassfieldasdict)datetimetimezone)AnyDictListOptionalTuple   g      >@i   i     a  [Continuing toward your standing goal]
Goal: {goal}

Continue working toward this goal. Take the next concrete step. If you believe the goal is complete, state so explicitly and stop. If you are blocked and need input from the user, say so clearly and stop.a{  [Continuing toward your standing goal]
Goal: {goal}

Additional criteria the user added mid-loop:
{subgoals_block}

Continue working toward the goal AND all additional criteria. Take the next concrete step. If you believe the goal and every additional criterion are complete, state so explicitly and stop. If you are blocked and need input from the user, say so clearly and stop.u  You are a strict judge evaluating whether an autonomous agent has achieved a user's stated goal. You receive the goal text and the agent's most recent response. Your only job is to decide whether the goal is fully satisfied based on that response.

A goal is DONE only when:
- The response explicitly confirms the goal was completed, OR
- The response clearly shows the final deliverable was produced, OR
- The response explains the goal is unachievable / blocked / needs user input (treat this as DONE with reason describing the block).

Otherwise the goal is NOT done — CONTINUE.

Reply ONLY with a single JSON object on one line:
{"done": <true|false>, "reason": "<one-sentence rationale>"}zlGoal:
{goal}

Agent's most recent response:
{response}

Current time: {current_time}

Is the goal satisfied?u  Goal:
{goal}

Additional criteria the user added mid-loop (all must also be satisfied for the goal to be DONE):
{subgoals_block}

Agent's most recent response:
{response}

Current time: {current_time}

Decision: For each numbered criterion above, find concrete evidence in the agent's response that the criterion is satisfied. Do not accept generic phrases like 'all requirements met' or 'implying it was done' — require specific evidence (a file contents excerpt, an output line, a command result). If ANY criterion lacks specific evidence in the response, the goal is NOT done — return CONTINUE.

Is the goal AND every additional criterion satisfied?c                      e Zd ZU dZded<   dZded<   dZded<   e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e          Zded<   ddZedd            ZddZdS )	GoalStatez+Serializable goal state stored per session.strgoalactivestatusr   int
turns_used	max_turns        float
created_atlast_turn_atNOptional[str]last_verdictlast_reasonpaused_reasonconsecutive_parse_failures)default_factoryz	List[str]subgoalsreturnc                H    t          j        t          |           d          S )NF)ensure_ascii)jsondumpsr   selfs    4/home/kuhnn/.hermes/hermes-agent/hermes_cli/goals.pyto_jsonzGoalState.to_json   s    z&,,U;;;;    raw'GoalState'c                   t          j        |          }|                    d          pg }g }t          |t                    rd |D             } | |                    dd          |                    dd          t          |                    dd          pd          t          |                    d	t                    pt                    t          |                    d
d          pd          t          |                    dd          pd          |                    d          |                    d          |                    d          t          |                    dd          pd          |          S )Nr#   c                    g | ]D}t          |                                          #t          |                                          ES  )r   strip.0ss     r+   
<listcomp>z'GoalState.from_json.<locals>.<listcomp>   s9    OOO1AOAOOOr-   r    r   r   r   r   r   r   r   r   r   r   r    r!   )r   r   r   r   r   r   r   r   r    r!   r#   )r'   loadsget
isinstancelistr   DEFAULT_MAX_TURNSr   )clsr.   dataraw_subgoalsr#   s        r+   	from_jsonzGoalState.from_json   sV   z#xx
++1r lD)) 	POOOOOHs&"%%88Hh//488L!449::$((;0ABBWFWXXTXXlC88?C@@txx<<CDD.11//((?33'*4884PRS+T+T+YXY'Z'Z
 
 
 	
r-   c                z    | j         sdS d                    d t          | j         d          D                       S )z\Render the subgoals as a numbered ``- N. text`` block. Empty
        when no subgoals exist.r8   
c              3  ,   K   | ]\  }}d | d| V  dS z- z. Nr2   r5   itexts      r+   	<genexpr>z2GoalState.render_subgoals_block.<locals>.<genexpr>   s7      [[ga)a))4))[[[[[[r-      start)r#   join	enumerater)   s    r+   render_subgoals_blockzGoalState.render_subgoals_block   sD     } 	2yy[[4=XY9Z9Z9Z[[[[[[r-   r$   r   )r.   r   r$   r/   )__name__
__module____qualname____doc____annotations__r   r   r=   r   r   r   r   r   r    r!   r   r<   r#   r,   classmethodrA   rO   r2   r-   r+   r   r      s-        55IIIFJ&I&&&&JL"&L&&&&!%K%%%%#'M''''&'''''  %555H5555< < < < 
 
 
 [
,\ \ \ \ \ \r-   r   
session_idr   r$   c                    d|  S )Nzgoal:r2   )rW   s    r+   	_meta_keyrY      s    :r-   Dict[str, Any]	_DB_CACHEOptional[Any]c                    	 ddl m}  ddlm} t	           |                       }n3# t
          $ r&}t                              d|           Y d}~dS d}~ww xY wt          	                    |          }||S 	  |            }n3# t
          $ r&}t                              d|           Y d}~dS d}~ww xY w|t          |<   |S )a  Return a SessionDB instance for the current HERMES_HOME.

    SessionDB has no built-in singleton, but opening a new connection per
    /goal call would thrash the file. We cache one instance per
    ``hermes_home`` path so profile switches still pick up the right DB.
    Defensive against import/instantiation failures so tests and
    non-standard launchers can still use the GoalManager.
    r   )get_hermes_home)	SessionDBz,GoalManager: SessionDB bootstrap failed (%s)Nz$GoalManager: SessionDB() raised (%s))
hermes_constantsr^   hermes_stater_   r   	Exceptionloggerdebugr[   r:   )r^   r_   homeexccacheddbs         r+   _get_session_dbri      s   444444******??$$%%   CSIIIttttt ]]4  FY[[   ;SAAAttttt IdOIs,   #& 
AAA8
B 
B3B..B3Optional[GoalState]c                   | sdS t                      }|dS 	 |                    t          |                     }n3# t          $ r&}t                              d|           Y d}~dS d}~ww xY w|sdS 	 t                              |          S # t          $ r'}t                              d| |           Y d}~dS d}~ww xY w)z4Load the goal for a session, or None if none exists.Nz GoalManager: get_meta failed: %sz3GoalManager: could not parse stored goal for %s: %s)	ri   get_metarY   rb   rc   rd   r   rA   warning)rW   rh   r.   rf   s       r+   	load_goalrn      s     t			B	ztkk)J//00   7===ttttt  t""3'''   LjZ]^^^ttttts-   "; 
A+A&&A+3B 
B>B99B>stateNonec                   | sdS t                      }|dS 	 |                    t          |           |                                           dS # t          $ r&}t
                              d|           Y d}~dS d}~ww xY w)z5Persist a goal to SessionDB. No-op if DB unavailable.Nz GoalManager: set_meta failed: %s)ri   set_metarY   r,   rb   rc   rd   )rW   ro   rh   rf   s       r+   	save_goalrs     s     			B	z>
Ij))5==??;;;;; > > >7=========>s   5A 
A?A::A?c                Z    t          |           }|dS d|_        t          | |           dS )zDMark a goal cleared in the DB (preserved for audit, status=cleared).Ncleared)rn   r   rs   )rW   ro   s     r+   
clear_goalrv     s6    j!!E}ELj%     r-   rH   limitr   c                N    | sdS t          |           |k    r| S | d |         dz   S )Nr8   u   … [truncated])len)rH   rw   s     r+   	_truncaterz     s9     r
4yyE<+++r-   z\{.*?\}c                 
   	 ddl m}   |             }|                    d          pi                     di                               dt                    }t	          |          }|dk    r|S n# t
          $ r Y nw xY wt          S )a#  Resolve auxiliary.goal_judge.max_tokens, falling back to the default.

    ``load_config()`` is cached on the config file's (mtime, size), so calling
    this once per judge turn is cheap. A non-positive or non-int value falls
    back to the default rather than crashing the goal loop.
    r   )load_config	auxiliary
goal_judge
max_tokens)hermes_cli.configr|   r:   DEFAULT_JUDGE_MAX_TOKENSr   rb   )r|   cfgvalues      r+   _goal_judge_max_tokensr   *  s    111111kmmWW[!!'RSr""S788 	
 E

199L    ##s   A*A. .
A;:A;r.   Tuple[bool, str, bool]c                l   | sdS |                                  }|                    d          r=|                     d          }|                    d          }|dk    r||dz   d         }d}	 t          j        |          }ng# t
          $ rZ t                              |          }|r;	 t          j        |                    d                    }n# t
          $ r d}Y nw xY wY nw xY wt          |t                    sd	d
t          | d          dfS |                    d          }t          |t                    r)|                                                                 dv }nt          |          }t          |                    d          pd                                           }|sd}||d	fS )a  Parse the judge's reply. Fail-open to ``(False, "<reason>", parse_failed)``.

    Returns ``(done, reason, parse_failed)``. ``parse_failed`` is True when the
    judge returned output that couldn't be interpreted as the expected JSON
    verdict (empty body, prose, malformed JSON). Callers use that flag to
    auto-pause after N consecutive parse failures so a weak judge model
    doesn't silently burn the turn budget.
    )Fzjudge returned empty responseTz````rC   rJ   Nr   Fzjudge reply was not JSON:    Tdone>   1yesr   truereasonr8   zno reason provided)r3   
startswithfindr'   r9   rb   _JSON_OBJECT_REsearchgroupr;   dictrz   r:   r   lowerbool)r.   rH   nlr?   matchdone_valr   r   s           r+   _parse_judge_responser   B  s     <;;99;;D u !zz#YYt__88Q=D &*D	z$   &&t,, 	z%++a..11    dD!! QJ9S#3F3FJJDPPxxH(C   ~~%%''+GGH~~(##)r**0022F &%s6   .B &C'*'CC'C!C' C!!C'&C')timeoutr#   r   last_responser   r   r#   Optional[List[str]]Tuple[str, str, bool]c          	        |                                  sdS |                                 sdS 	 ddlm}m} n3# t          $ r&}t
                              d|           Y d}~dS d}~ww xY w	  |d          \  }}n3# t          $ r&}t
                              d	|           Y d}~dS d}~ww xY w||sd
S d |pg D             }	t          j        t          j
                                                                      d          }
|	r|d                    d t          |	d          D                       }t                              t#          | d          t#          |d          t#          |t$                    |
          }n>t&                              t#          | d          t#          |t$                    |
          }	 |j        j                            |dt.          dd|dgdt1                      | |            pd          }nL# t          $ r?}t
                              d|           ddt5          |          j         dfcY d}~S d}~ww xY w	 |j        d         j        j        pd}n# t          $ r d}Y nw xY wt?          |          \  }}}|rdnd}t
                              d|t#          |d                      |||fS )!u  Ask the auxiliary model whether the goal is satisfied.

    Returns ``(verdict, reason, parse_failed)`` where verdict is ``"done"``,
    ``"continue"``, or ``"skipped"`` (when the judge couldn't be reached).

    ``parse_failed`` is True only when the judge call succeeded but its output
    was unusable (empty or non-JSON). API/transport errors return False — they
    are transient and should fail-open silently. Callers use this flag to
    auto-pause after N consecutive parse failures (see
    ``DEFAULT_MAX_CONSECUTIVE_PARSE_FAILURES``).

    ``subgoals`` is an optional list of user-added criteria (from
    ``/subgoal``) that the judge must also factor into its DONE/CONTINUE
    decision. When non-empty the prompt switches to the with-subgoals
    template; otherwise behavior is identical to the original judge.

    This is deliberately fail-open: any error returns ``("continue", "...", False)``
    so a broken judge doesn't wedge progress — the turn budget and the
    consecutive-parse-failures auto-pause are the backstops.
    )skippedz
empty goalF)continuez$empty response (nothing to evaluate)Fr   )get_auxiliary_extra_bodyget_text_auxiliary_clientz.goal judge: auxiliary client import failed: %sN)r   zauxiliary client unavailableFr~   z0goal judge: get_text_auxiliary_client failed: %s)r   zno auxiliary client configuredFc                b    g | ],}||                                 |                                 -S r2   )r3   r4   s     r+   r7   zjudge_goal.<locals>.<listcomp>  s2    MMMAQM17799MaggiiMMMr-   )tzz%Y-%m-%d %H:%M:%S %ZrC   c              3  ,   K   | ]\  }}d | d| V  dS rE   r2   rF   s      r+   rI   zjudge_goal.<locals>.<genexpr>  sH       #
 #
!(Dd#
 #
 #
 #
 #
 #
r-   rJ   rK   i  )r   subgoals_blockresponsecurrent_time)r   r   r   system)rolecontentuser)modelmessagestemperaturer   r   
extra_bodyu@   goal judge: API call failed (%s) — falling through to continuer   zjudge error: Fr8   r   z goal judge: verdict=%s reason=%sx   ) r3   agent.auxiliary_clientr   r   rb   rc   rd   r   nowr   utc
astimezonestrftimerM   rN   (JUDGE_USER_PROMPT_WITH_SUBGOALS_TEMPLATEformatrz   _JUDGE_RESPONSE_SNIPPET_CHARSJUDGE_USER_PROMPT_TEMPLATEchatcompletionscreateJUDGE_SYSTEM_PROMPTr   infotyperQ   choicesmessager   r   )r   r   r   r#   r   r   rf   clientr   clean_subgoalsr   r   promptrespr.   r   r   parse_failedverdicts                      r+   
judge_goalr   s  s   6 ::<< .--   IHHA^^^^^^^^^ A A AEsKKK@@@@@@AA11,?? A A AGMMM@@@@@@A ~U~BB NM(.bMMMN<8<000;;==FFG]^^L 
 #
 #
,5nA,N,N,N#
 #
 #
 
 
 :@@4&&$^T::}.KLL%	 A 
 
 ,224&&}.KLL% 3 
 
G{&--!.ABBF33 -////119T . 

 

  G G GVX[\\\?499+=??FFFFFFFGl1o%-3    "7s!;!;D&,,ff*G
KK2GYvs=S=STTTFL((s^   7 
A'A""A'+A: :
B*B%%B*AH 
I4I	III2 2J Jc                      e Zd ZdZedd-dZed.d
            Zd/dZd/dZ	d0dZ
ddd1dZd2d3dZddd4dZd5dZd6dZd7d!Zd8d#Zd9d$Zd0d%Zdd&d:d*Zd;d,ZdS )<GoalManageruf  Per-session goal state + continuation decisions.

    The CLI and gateway each hold one ``GoalManager`` per live session.

    Methods:

    - ``set(goal)`` — start a new standing goal.
    - ``clear()`` — remove the active goal.
    - ``pause()`` / ``resume()`` — explicit user controls.
    - ``status()`` — printable one-liner.
    - ``evaluate_after_turn(last_response)`` — call the judge, update state,
      and return a decision dict the caller uses to drive the next turn.
    - ``next_continuation_prompt()`` — the canonical user-role message to
      feed back into ``run_conversation``.
    )default_max_turnsrW   r   r   r   c               r    || _         t          |pt                    | _        t	          |          | _        d S N)rW   r   r=   r   rn   _state)r*   rW   r   s      r+   __init__zGoalManager.__init__  s3    $!$%6%K:K!L!L+4Z+@+@r-   r$   rj   c                    | j         S r   )r   r)   s    r+   ro   zGoalManager.state  s
    {r-   r   c                4    | j         d uo| j         j        dk    S )Nr   r   r   r)   s    r+   	is_activezGoalManager.is_active  s    {$&I4;+=+IIr-   c                0    | j         d uo| j         j        dv S )N>   r   pausedr   r)   s    r+   has_goalzGoalManager.has_goal  s    {$&U4;+=AU+UUr-   c                   | j         }|	|j        dv rdS |j         d|j         d}|j        r4dt          |j                   dt          |j                  dk    rdnd	 nd	}|j        d
k    rd| | d|j         S |j        dk    r$|j        r
d|j         nd	}d| | | d|j         S |j        dk    rd| | d|j         S d|j         d| | d|j         S )N>   ru   z*No active goal. Set one with /goal <text>./z turnsz, z subgoalrJ   r6   r8   r   u   ⊙ Goal (active, ): r   u    — u   ⏸ Goal (paused, r   u   ✓ Goal done (zGoal ()r   r   r   r   r#   ry   r   r    )r*   r6   turnssubextras        r+   status_linezGoalManager.status_line  sB   K9L00??<55!+555UVU_gQ3qz??QQ3qz??a3G3GCCRQQQeg8x??s??qv???8x12H-AO---bEFFsFEFFafFFF8v<U<C<<AF<<<;;;E;3;;16;;;r-   N)r   r   r   Optional[int]r   c                  |pd                                 }|st          d          t          |dd|rt          |          n| j        t          j                    d          }|| _        t          | j        |           |S )Nr8   zgoal text is emptyr   r   r   )r   r   r   r   r   r   )	r3   
ValueErrorr   r   r   timer   rs   rW   )r*   r   r   ro   s       r+   setzGoalManager.set
  s    
!!## 	31222(1Mc)nnnt7My{{
 
 
 $/5)))r-   user-pausedr   c                    | j         sd S d| j         _        || j         _        t          | j        | j                    | j         S )Nr   )r   r   r    rs   rW   r*   r   s     r+   pausezGoalManager.pause  sA    { 	4%$*!$/4;///{r-   T)reset_budgetr   c                   | j         sd S d| j         _        d | j         _        |rd| j         _        t	          | j        | j                    | j         S )Nr   r   )r   r   r    r   rs   rW   )r*   r   s     r+   resumezGoalManager.resume"  sS    { 	4%$(! 	'%&DK"$/4;///{r-   rp   c                r    | j         d S d| j         _        t          | j        | j                    d | _         d S )Nru   )r   r   rs   rW   r)   s    r+   clearzGoalManager.clear,  s8    ;F&$/4;///r-   c                    | j         sd S d| j         _        d| j         _        || j         _        t	          | j        | j                    d S )Nr   )r   r   r   r   rs   rW   r   s     r+   	mark_donezGoalManager.mark_done3  sI    { 	F##) "($/4;/////r-   rH   c                   | j         |                                 st          d          |pd                                }|st	          d          | j         j                            |           t          | j        | j                    |S )zAppend a user-added criterion to the active goal. Requires
        ``has_goal()``; raises ``RuntimeError`` otherwise.

        Returns the cleaned text so the caller can show it back to the user.
        Nno active goalr8   zsubgoal text is empty)	r   r   RuntimeErrorr3   r   r#   appendrs   rW   )r*   rH   s     r+   add_subgoalzGoalManager.add_subgoal=  s     ;dmmoo/000
!!## 	64555##D)))$/4;///r-   index_1basedc                   | j         |                                 st          d          t          |          dz
  }|dk     s|t	          | j         j                  k    r*t          dt	          | j         j                   d          | j         j                            |          }t          | j	        | j                    |S )z<Remove a subgoal by 1-based index. Returns the removed text.Nr   rJ   r   zindex out of range (1..))
r   r   r   r   ry   r#   
IndexErrorpoprs   rW   )r*   r   idxremoveds       r+   remove_subgoalzGoalManager.remove_subgoalL  s    ;dmmoo/000,!#77cS!56666F#dk.B*C*CFFF   +&**3//$/4;///r-   c                    | j         |                                 st          d          t          | j         j                  }g | j         _        t          | j        | j                    |S )z.Wipe all subgoals. Returns the previous count.Nr   )r   r   r   ry   r#   rs   rW   )r*   prevs     r+   clear_subgoalszGoalManager.clear_subgoalsY  s[    ;dmmoo/0004;'((!$/4;///r-   c                b    | j         dS | j         j        sdS | j                                         S )z-Public helper for the /subgoal slash command.Nz(no active goal)u5   (no subgoals — use /subgoal <text> to add criteria))r   r#   rO   r)   s    r+   render_subgoalszGoalManager.render_subgoalsb  s8    ;%%{# 	KJJ{00222r-   )user_initiatedr   r  rZ   c               l   | j         }||j        dk    r|r|j        ndddddddS |xj        dz  c_        t          j                    |_        t          |j        ||j        pd	          \  }}}||_        ||_	        |r|xj
        dz  c_
        nd
|_
        |dk    r(d|_        t          | j        |           dddd|d| dS |j
        t          k    r>d|_        d|j
         d|_        t          | j        |           dddd|d|j
         ddS |j        |j        k    rNd|_        d|j         d|j         d|_        t          | j        |           dddd|d|j         d|j         ddS t          | j        |           dd|                                 d|d|j         d|j         d| dS )uv  Run the judge and update state. Return a decision dict.

        ``user_initiated`` distinguishes a real user prompt (True) from a
        continuation prompt we fed ourselves (False). Both increment
        ``turns_used`` because both consume model budget.

        Decision keys:
          - ``status``: current goal status after update
          - ``should_continue``: bool — caller should fire another turn
          - ``continuation_prompt``: str or None
          - ``verdict``: "done" | "continue" | "skipped" | "inactive"
          - ``reason``: str
          - ``message``: user-visible one-liner to print/send
        Nr   Finactiver   r8   )r   should_continuecontinuation_promptr   r   r   rJ   )r#   r   r   u   ✓ Goal achieved: r   z(judge model returned unparseable output z turns in a rowr   u%   ⏸ Goal paused — the judge model (z turns) isn't returning the required JSON verdict. Route the judge to a stricter model in ~/.hermes/config.yaml:
  auxiliary:
    goal_judge:
      provider: openrouter
      model: google/gemini-3-flash-preview
Then /goal resume to continue.zturn budget exhausted (r   r   u   ⏸ Goal paused — zD turns used. Use /goal resume to keep going, or /goal clear to stop.Tu   ↻ Continuing toward goal (r   )r   r   r   r   r   r   r   r#   r   r   r!   rs   rW   &DEFAULT_MAX_CONSECUTIVE_PARSE_FAILURESr    r   next_continuation_prompt)r*   r   r  ro   r   r   r   s          r+   evaluate_after_turnzGoalManager.evaluate_after_turnl  s   ( =ELH44*/9%,,T#('+%*   	A!Y[[(2J0F$)
 )
 )
% %"
  	1,,1,,,/0E,f!ELdou--- #('+! 999   +/UUU#ELl5;[lll  dou---"#('+% 5E<\ 5 5 5  $ u..#EL"aE<L"a"au"a"a"aEdou---"#('+% N5+; N Neo N N N
 
 
 	$/5)))##'#@#@#B#B!^u/?^^%/^^V\^^	
 	
 		
r-   r   c                   | j         r| j         j        dk    rd S | j         j        r=t                              | j         j        | j                                                   S t                              | j         j                  S )Nr   )r   r   )r   )r   r   r#   *CONTINUATION_PROMPT_WITH_SUBGOALS_TEMPLATEr   r   rO   CONTINUATION_PROMPT_TEMPLATEr)   s    r+   r  z$GoalManager.next_continuation_prompt  s    { 	dk0H<<4; 	=DD[%#{@@BB E    ,228H2IIIr-   )rW   r   r   r   )r$   rj   )r$   r   rP   )r   r   r   r   r$   r   )r   )r   r   r$   rj   )r   r   r$   rj   )r$   rp   )r   r   r$   rp   )rH   r   r$   r   )r   r   r$   r   r$   r   )r   r   r  r   r$   rZ   )r$   r   )rQ   rR   rS   rT   r=   r   propertyro   r   r   r   r   r   r   r   r   r   r   r   r  r	  r  r2   r-   r+   r   r     s          EV A A A A A A    XJ J J JV V V V< < < <" <@            .2         0 0 0 0         3 3 3 3  $	u
 u
 u
 u
 u
 u
nJ J J J J Jr-   r   )r   r   r  r  r   r   r=   rn   rs   rv   r   )rW   r   r$   r   )r$   r\   )rW   r   r$   rj   )rW   r   ro   r   r$   rp   )rW   r   r$   rp   )rH   r   rw   r   r$   r   r  )r.   r   r$   r   )
r   r   r   r   r   r   r#   r   r$   r   )1rT   
__future__r   r'   loggingrer   dataclassesr   r   r   r   r   typingr	   r
   r   r   r   	getLoggerrQ   rc   r=   DEFAULT_JUDGE_TIMEOUTr   r   r  r  r  r   r   r   r   rY   r[   rU   ri   rn   rs   rv   rz   compileDOTALLr   r   r   r   r   __all__r2   r-   r+   <module>r     s    : # " " " " "   				  0 0 0 0 0 0 0 0 0 0 ' ' ' ' ' ' ' ' 3 3 3 3 3 3 3 3 3 3 3 3 3 3		8	$	$       $  *+ &P  +I " < ), 3\ 3\ 3\ 3\ 3\ 3\ 3\ 3\v        	       <   *
> 
> 
> 
>! ! ! !, , , , "*Z33$ $ $ $0. . . .j +$(\) \) \) \) \) \)HTJ TJ TJ TJ TJ TJ TJ TJn  r-   