
    sjv                       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ZddlZddl	m
Z
 ddlmZmZmZmZ ddlmZ erddlmZ  ej        e          Z e
e          j        ZdZi Zd	ed
<   dZd4dZd5dZd5dZ d6dZ!d7dZ"d Z#d8dZ$d5dZ%d9dZ&d:d Z'd;d"Z(dd#d<d'Z)d(d#d=d)Z*d(d#d>d+Z+ G d, d-          Z,d?d/Z-	 d@dAd1Z.dBd3Z/dS )CaX  Memory provider plugin discovery.

Scans four sources for memory provider plugins:

1. Bundled providers: ``plugins/memory/<name>/`` (shipped with hermes-agent)
2. User-installed providers: ``$HERMES_HOME/plugins/<name>/``
3. Project-local providers: ``./.hermes/plugins/<name>/``, opt-in via
   ``HERMES_ENABLE_PROJECT_PLUGINS``
4. Pip-installed providers: ``hermes_agent.memory_providers`` entry points

Directory providers must contain ``__init__.py`` with a class implementing
the MemoryProvider ABC. Pip packages expose a provider or ``register(ctx)``
callback through the entry-point group.

These are the same four sources the general ``PluginManager`` scans, but the
precedence is deliberately the reverse of its later-source-wins order: here
**bundled wins**, then user, then project, then entry point. A memory provider
is activated by name, so letting a directory dropped into the working tree
shadow a shipped provider would silently redirect the agent's memory. Changing
this order is a breaking change, not a cleanup.

Only ONE provider can be active at a time, selected via
``memory.provider`` in config.yaml.

Usage:
    from plugins.memory import discover_memory_providers, load_memory_provider

    available = discover_memory_providers()   # [(name, desc, available), ...]
    provider = load_memory_provider("mnemosyne")  # MemoryProvider instance
    )annotationsN)Path)ListOptionalTupleTYPE_CHECKING)cfg_getMemoryProviderzhermes_agent.memory_providerszdict[str, Path]"_REGISTERED_MEMORY_PROVIDER_SKILLS_hermes_user_memorynamestrsearch_locations	List[str]returnNonec                    | t           j        v rdS t          j                            | dd          }||_        t          j                            |          t           j        | <   dS )u  Register an empty package shell in sys.modules.

    User-installed providers import as ``_hermes_user_memory.<name>``, a
    dotted name whose parents exist nowhere on disk.  Unless those parents
    are present in ``sys.modules``, any relative import inside the plugin
    (``from . import config``) fails with
    ``ModuleNotFoundError: No module named '_hermes_user_memory'`` — the
    same reason the loader already registers ``plugins`` and
    ``plugins.memory`` for bundled providers.
    NT)
is_package)sysmodules	importlib	machinery
ModuleSpecsubmodule_search_locationsutilmodule_from_spec)r   r   specs      ;/home/agent/.hermes/hermes-agent/plugins/memory/__init__.py_register_synthetic_packager    :   s]     s{))$)FFD&6D#!77==CK    Optional[Path]c                 |    	 ddl m}   |             dz  }|                                r|ndS # t          $ r Y dS w xY w)z8Return ``$HERMES_HOME/plugins/`` or None if unavailable.r   )get_hermes_homepluginsN)hermes_constantsr$   is_dir	Exception)r$   ds     r   _get_user_plugins_dirr*   P   sd    444444O	)HHJJ(qqD(   tts   *- 
;;c                     	 ddl m}   | d          sdS t          j                    dz  dz  }|                                r|ndS # t
          $ r Y dS w xY w)u$  Return ``./.hermes/plugins/`` or None if unavailable or not opted in.

    Gated on ``HERMES_ENABLE_PROJECT_PLUGINS`` exactly as the general
    ``PluginManager`` gates its own project scan — a repository you merely
    ``cd`` into must not be able to offer the agent a memory backend.
    r   )_env_enabledHERMES_ENABLE_PROJECT_PLUGINSNz.hermesr%   )hermes_cli.pluginsr,   r   cwdr'   r(   )r,   r)   s     r   _get_project_plugins_dirr0   Z   s    333333|;<< 	4HJJ"Y.HHJJ(qqD(   tts   A 0A 
AApathr   boolc                    | dz  }|                                 sdS 	 |                    dd          dd         }d|v pd	|v S # t          $ r Y dS w xY w)
u   Heuristic: does *path* look like a memory provider plugin?

    Checks for ``register_memory_provider`` or ``MemoryProvider`` in the
    ``__init__.py`` source.  Cheap text scan — no import needed.
    __init__.pyFreplacezutf-8)errorsencodingNi    register_memory_providerr   )exists	read_textr(   )r1   	init_filesources      r   _is_memory_provider_dirr=   l   s     }$I u$$I$HH$O)V3Q7G67QQ   uus   &A 
AAList[Tuple[str, Path]]c                 .   t                      } g }t                                          rt          t                                                    D ]}|                                r|j                            d          r1|dz                                  sI|                     |j                   |	                    |j        |f           t                      t                      fD ]}|st          |                                          D ]}|                                r|j                            d          r1|j        | v r;t          |          sK|                     |j                   |	                    |j        |f           |S )zYield ``(name, path)`` for all discovered provider directories.

    Scans bundled, then user-installed, then project-local.  Bundled takes
    precedence on name collisions (first-seen wins via ``seen`` set).
    )_.r4   )set_MEMORY_PLUGINS_DIRr'   sortediterdirr   
startswithr9   addappendr*   r0   r=   )seendirschild
source_dirs       r   _iter_provider_dirsrM   |   s    D#%D !!## -/7799:: 	- 	-E<<>> UZ%:%::%F%F M)1133 HHUZ   KKU+,,,, -..0H0J0JK - -
 	J..0011 	- 	-E<<>> UZ%:%::%F%F zT!!*511 HHUZ   KKU+,,,,	- Kr!   c                    	 t           j                                        } t          | d          r(t	          |                     t                              S t          | t                    r(t	          | 	                    t          g                     S d | D             S # t          $ r'}t                              d|           g cY d}~S d}~ww xY w)z1Yield pip-installed memory provider entry points.select)groupc                2    g | ]}|j         t          k    |S  )rP   ENTRY_POINTS_GROUP.0eps     r   
<listcomp>z&_iter_entry_points.<locals>.<listcomp>   s%    CCCrBH0B$B$B$B$B$Br!   z+Memory provider entry-point scan failed: %sN)r   metadataentry_pointshasattrlistrO   rS   
isinstancedictgetr(   loggerdebug)epsexcs     r   _iter_entry_pointsrc      s    	 --//3!! 	>

);
<<===c4   	9 2B77888CCSCCCC   BCHHH						s*   AB! <B! B! !
C+CCCc                D   t           | z  }|                                r|dz                                  r|S t                      t	                      fD ]1}|s|| z  }|                                rt          |          r|c S 2t          t          |                     S )u  Resolve a provider name to the directory holding its files.

    Checks bundled, then user-installed, then project-local, then the package
    directory of a pip entry-point provider.

    The entry-point case matters because two of a provider's files are read
    from disk rather than imported: ``config_schema.py`` (loaded by path so the
    web server never pulls in the agent runtime — see
    ``plugins/memory/config_schema.py``) and ``cli.py`` (loaded by
    ``discover_plugin_cli_commands`` at argparse time). Without a directory, a
    pip-installed provider silently loses its dashboard config panel and its
    ``hermes <provider>`` subcommands — working, but a second-class citizen next
    to a directory install.
    r4   )rC   r'   r9   r*   r0   r=   _entry_point_package_dirfind_provider_entry_point)r   bundledrL   	candidates       r   find_provider_dirri      s      "D(G~~ W}4<<>> ,..0H0J0JK  
 	%	 	"9)"D"D 	#$=d$C$CDDDr!   c           	     j   | dS 	 ddl m} | j        pd                    d          d                                         } ||          }|sdS t          |          }|j        dk    r|j        ndS # t          $ r6}t          
                    dt          | dd	          |           Y d}~dS d}~ww xY w)
u  The directory of an entry point's module, resolved WITHOUT importing it.

    Discovery must stay free of third-party imports: ``find_provider_dir`` is
    called from the dashboard and from argparse setup, long before the operator
    has selected a provider, so importing every installed candidate would run
    arbitrary code on the strength of a package merely being present.
    ``resolve_module_origin`` walks the module's file layout instead.

    Only package entry points (``pkg/__init__.py``) yield a directory — a
    provider pointed at a bare ``module.py`` has nowhere to put a sibling
    ``config_schema.py``, so it correctly resolves to None.
    Nr   )resolve_module_origin :r4   z4Could not resolve directory for entry point '%s': %sr   ?)r.   rk   valuesplitstripr   r   parentr(   r_   r`   getattr)entry_pointrk   module_nameoriginr1   rb   s         r   re   re      s     t<<<<<<"(.B55c::1=CCEE&&{33 	4F||"i=88t{{dB   K[&#66	= 	= 	=ttttts   AA2 "A2 2
B2<+B--B2c                F    t                      D ]}|j        | k    r|c S dS )z;Resolve a provider name to a pip entry point, if installed.N)rc   r   )r   rt   s     r   rf   rf      s;    )++  t## $4r!   c                     d t                      D             } |                     d t                      D                        t          |           S )u  Cheap name-only listing of discoverable memory providers.

    Unlike :func:`discover_memory_providers`, this does NOT import provider
    modules or run availability checks — a directory scan plus entry-point
    *enumeration*, which reads distribution metadata without executing any of
    it. Safe to call at module-import time (e.g. when building the dashboard
    config schema, where it fills the ``memory.provider`` dropdown).
    c                    h | ]\  }}|S rR   rR   )rU   r   r@   s      r   	<setcomp>z-list_memory_provider_names.<locals>.<setcomp>   s    777gdAT777r!   c              3  $   K   | ]}|j         V  d S N)r   rT   s     r   	<genexpr>z-list_memory_provider_names.<locals>.<genexpr>  s$      88R888888r!   )rM   updaterc   rD   )namess    r   list_memory_provider_namesr      sR     87!4!6!6777E	LL88#5#7#7888888%==r!   List[Tuple[str, str, bool]]c                 N   g } t                      }t                      D ]\  }}d}|dz  }|                                rl	 ddl}t	          |d          5 }|                    |          pi }ddd           n# 1 swxY w Y   |                    dd          }n# t          $ r Y nw xY wd}		 t          |d	
          }
|
r|
	                                }	nd	}	n# t          $ r d	}	Y nw xY w| 
                    |||	f           |                    |           t                      D ]}}|j        }||v rd}d}		 t          |d	
          }
|
r|
	                                }	nd	}	n# t          $ r d	}	Y nw xY w| 
                    |||	f           |                    |           ~| S )a  Scan directory and pip entry-point memory providers.

    Returns list of (name, description, is_available) tuples.
    Bundled providers take precedence on name collisions, followed by
    user-installed directory providers, then pip entry-point providers.
    rl   plugin.yamlr   N	utf-8-sigr7   descriptionTFregister_skills)rB   rM   r9   yamlopen	safe_loadr^   r(   _load_provider_from_diris_availablerH   rG   rc   r   _load_provider_from_entry_point)resultsrI   r   rK   desc	yaml_filer   fmeta	availableproviderrt   s               r   discover_memory_providersr     se    GUUD*,,  eM)	 	)k::: 3a>>!,,2D3 3 3 3 3 3 3 3 3 3 3 3 3 3 3xxr22    		.ueLLLH "$1133		!	 	 	 	III	 	dI.///)++  4<<	
	6 %  H  "$1133		!	 	 	 	III	 	dI.///NsZ    BA9-B9A=	=B A=	B
B('B(.*CC('C(:*E%%E43E4r   r   Optional[bool]Optional['MemoryProvider']c                  || t                      k    }t          |           }|rdnt          |           }|s|t                              d|            dS 	 |rt          ||          nt          ||          }|r|S t                              d|            dS # t          $ r'}t                              d| |           Y d}~dS d}~ww xY w)a  Load and return a MemoryProvider instance by name.

    Checks bundled (``plugins/memory/<name>/``), user-installed
    (``$HERMES_HOME/plugins/<name>/``), and pip entry-point providers.
    Bundled providers take precedence on name collisions.

    Skills register only when *name* is the configured active provider unless
    ``register_skills`` is passed explicitly. This keeps status and setup
    inspection of inactive providers free of registry side effects.

    Returns None if the provider is not found or fails to load.
    NzHMemory provider '%s' not found in bundled, user plugins, or entry pointsr   z:Memory provider '%s' loaded but no provider instance foundz'Failed to load memory provider '%s': %s)	_get_active_memory_providerri   rf   r_   r`   r   r   warningr(   )r   r   provider_dirrt   r   es         r   load_memory_providerr   B  s   " "="?"??$T**L&K$$,Ed,K,KK K/V	
 	
 	
 t #L/RRRR0 /   	  	OSUYZZZt   @$JJJttttts   'B B 
C(C

CTc               L   ddl m} |                                 }t          ||          r|S t          |t                    r+t          ||          r	  |            S # t          $ r Y nw xY wt          |d          r9t          | j	        |          }|
                    |           |j        r|j        S t          |          rV	  |            }t          ||          r|S n# t          $ r Y nw xY wt          | j	        |          } ||           |j        S t          |          D ]Y}t          ||d          }t          |t                    r1t          ||          r!||ur	  |            c S # t          $ r Y Uw xY wZt                               d| j	                   dS )zFImport a provider entry point and extract the MemoryProvider instance.r   r
   registerr   Nz3Memory provider entry point '%s' loaded no provider)agent.memory_providerr   loadr\   type
issubclassr(   rZ   _ProviderCollectorr   r   r   callable	TypeErrordirrs   r_   r`   )rt   r   r   loaded	collectorr   	attr_nameattrs           r   r   r   q  s    544444F&.)) &$ Jv~$F$F 	688O 	 	 	D	 vz"" &&{'7YYY		""" 	&%% 
"	vxxH(N33    	 	 	D	 '{'7YYY	y!![[  	vy$//tT"" 	z$'G'G 	..tvv    LLFHXYYY4s6   	A 
A*)A*C# #
C0/C0'	E33
F ?F r   c                  | j         }t          | j        v p| j        t          k    }|rd| nt           d| }| dz  }|                                sdS t          j                            |          }|t          |dd          r|}ndD ]}|t          j        vrt          t                    j        }	|dk    r|	j        }	|	dz  }
|
                                rt          j                            |t          |
          t          |	          g          }|rZt          j                            |          }|t          j        |<   	 |j                            |           # t&          $ r Y w xY w|st)          t          g            t          j                            |t          |          t          |           g          }|sdS t          j                            |          }|t          j        |<   |                     d	          D ]}|j         dk    r|j        }| d| }|t          j        vrt          j                            |t          |                    }|r}t          j                            |          }|t          j        |<   	 |j                            |           # t&          $ r&}t.                              d
||           Y d}~d}~ww xY w	 |j                            |           nT# t&          $ rG}t.                              d||           t          j                            |d           Y d}~dS d}~ww xY wt5          |d          rt7          ||          }	 |                    |           nW# t&          $ rJ}|j        t.                              d||           nt.                              d||           Y d}~nd}~ww xY w|j        r|j        S ddlm } tC          |          D ]Y}t          ||d          }tE          |tF                    r1tI          ||          r!||ur	  |            c S # t&          $ r Y Uw xY wZdS )u   Import a provider module and extract the MemoryProvider instance.

    The module must have either:
    - A register(ctx) function (plugin-style) — we simulate a ctx
    - A top-level class that extends MemoryProvider — we instantiate it
    plugins.memory.rA   r4   N__file__)r%   zplugins.memoryr%   )r   z*.pyzFailed to load submodule %s: %szFailed to exec_module %s: %sr   r   zregister() failed for %s: %suv   Memory provider '%s' raised after registering (%s) — using the registered provider; later registrations were skippedr   r
   )%r   rC   parentsrr   _USER_NAMESPACEr9   r   r   r^   rs   r   r   r   r   spec_from_file_locationr   r   loaderexec_moduler(   r    globstemr_   r`   poprZ   r   r   r   r   r   r   r   r\   r   r   )r   r   r   _is_bundledru   r;   cachedmodrr   parent_pathparent_initr   
parent_modsub_filesub_namefull_sub_namesub_specsub_modr   r   r   r   r   s                          r   r   r     s    D &)==kATXkAkK.9Z*D***/?Z?ZTX?Z?ZK},I t
 [__[))Fgfj$?? 4 	! 	!FS[(("8nn3Y&&"-"4K)M9%%'' !$>AAK 0 0474D4D3E B  D  !%.^%D%DT%J%J
.8F+! K33J????( ! ! ! D!
  	='<<< ~55Y(+L(9(9': 6 
 
  	4n--d33#&K  %))&11 	Z 	ZH}--}H*77X77MCK//$>AA!3x==   Z'n==hGGG18CK.Z 33G<<<<$ Z Z Z%FWXYYYYYYYYZ	K##C(((( 	 	 	LL7aHHHKOOK...44444	 sJ &&t_MMM		LL#### 	 	 	
 !);T1EEEEV!  	  	&%% 544444XX  	sIt,,tT"" 	z$'G'G 	..tvv    4sm   	E$$
E10E1J33
K#=KK#(L 
M<MM9N 
O#A OO#	Q
QQc                  @    e Zd ZdZddddZd	 Zd
 Zd ZddZd Z	dS )r   uF  Plugin context for memory providers.

    Captures ``register_memory_provider`` directly — that is the one call the
    exclusive activation path owns — and delegates everything else to a real
    ``PluginContext`` (see ``__getattr__``), so a memory provider has the same
    registration surface as any other plugin.
    Tr   r   r   r   r2   c               >    || _         d | _        || _        d | _        d S r|   )r   r   _register_skills_context)selfr   r   s      r   __init__z_ProviderCollector.__init__*  s#    	 /r!   c                    || _         d S r|   )r   )r   r   s     r   r8   z+_ProviderCollector.register_memory_provider0  s     r!   c                   | j         sdS 	 |                                 } |j        |i | |r|d         n|                    d          }| j         d| }ddlm}  |                                |          }||t          |<   dS dS # t          $ r,}t                              d| j        |           Y d}~dS d}~ww xY w)u  Forward plugin-provided skills to the general plugin registry.

        Handled explicitly rather than through ``__getattr__`` because skills
        are tracked for pruning: switching the active provider has to retract
        the skills the previous one registered, which needs the qualified name
        and resolved path recorded here.

        Gated on ``register_skills`` so merely *inspecting* an inactive
        provider — ``hermes memory status``, the setup picker — leaves no
        registry side effects behind.
        Nr   r   rm   get_plugin_managerz1Memory provider '%s' failed to register skill: %s)r   _plugin_contextregister_skillr^   r   r.   r   find_plugin_skillr   r(   r_   r`   )	r   argskwargsmanager_context
skill_namequalified_namer   registered_pathrb   s	            r   r   z!_ProviderCollector.register_skill3  s    $ 	F	^"2244O*O*D;F;;;$(@afjj.@.@J $	88J88N======0022DD^TTO*ET2>BBB +* 	^ 	^ 	^LLLdiY\]]]]]]]]]	^s   A;B
 

C !B;;C c                    d S r|   rR   )r   r   r   s      r   register_cli_commandz'_ProviderCollector.register_cli_commandO  s    r!   r   c                ^                          d          st                     fd}|S )uV  Delegate any other ``register_*`` call to a real ``PluginContext``.

        Memory providers used to get a hand-maintained stub of three no-ops
        here, which had two failure modes. Calls it *did* know about
        (``register_tool``, ``register_hook``) were silently dropped, so a
        provider's tools simply never appeared. Calls it did *not* know about
        raised ``AttributeError`` — and ``register_auxiliary_task`` is one of
        them, despite ``PluginContext.register_auxiliary_task`` documenting a
        memory provider (hindsight's pre-retain dedup) as its worked example.
        That exception surfaces as "register() failed" and costs the provider.

        Delegating instead of enumerating means this can never drift behind
        ``PluginContext`` again: a capability added there works for memory
        providers on the same commit, which is what the "widen the generic
        plugin surface" rule in AGENTS.md asks for.

        Only ``register_*`` is forwarded. Everything else raises normally, so a
        typo still fails loudly rather than being absorbed.
        	register_c                     	                                                                 | i |S # t          $ r-}t                              dj        |           Y d }~d S d }~ww xY w)Nz%Memory provider '%s' failed to %s: %s)r   __getattribute__r(   r_   r   r   )r   r   rb   r   r   s      r   _forwardz0_ProviderCollector.__getattr__.<locals>._forwardi  s    	Dt++-->>tDDdUfUUU    ;TYc   ttttts   ,0 
A'"A""A')rF   AttributeError)r   r   r   s   `` r   __getattr__z_ProviderCollector.__getattr__R  sM    ( {++ 	' &&&
	 
	 
	 
	 
	 
	 r!   c                    | j         :ddlm}m}m}  || j        | j                  } || |                      | _         | j         S )u(  A real ``PluginContext`` for this provider, built once on demand.

        Lazy because the common case — a provider that only calls
        ``register_memory_provider`` — must not pay for importing the general
        plugin manager, which discovery touches on every hermes startup.
        Nr   )PluginContextPluginManifestr   )r   key)r   r.   r   r   r   r   )r   r   r   r   manifests        r   r   z"_ProviderCollector._plugin_contextw  sg     = \\\\\\\\\\%~49$)DDDH)M(4F4F4H4HIIDM}r!   N)r   r   r   r2   )r   r   )
__name__
__module____qualname____doc__r   r8   r   r   r   r   rR   r!   r   r   r   !  s          >B      ! ! !^ ^ ^8  # # # #J    r!   r   Optional[str]c                 l    	 ddl m}   |             }t          |dd          pdS # t          $ r Y dS w xY w)u   Read the active memory provider name from config.yaml.

    Returns the provider name (e.g. ``"honcho"``) or None if no
    external provider is configured.  Lightweight — only reads config,
    no plugin loading.
    r   )load_configmemoryr   N)hermes_cli.configr   r	   r(   )r   configs     r   r   r     s]    111111vx44<<   tts   "% 
33active_providerc                p   | t                      } ddlm}  |            }t          t                                                    D ]n\  }}|                    d          \  }}}|| k    r%|                    |          |k    r|                    |           t          	                    |d           odS )zCRemove tracked skills that no longer belong to the active provider.Nr   r   rm   )
r   r.   r   r[   r   items	partitionr   remove_plugin_skillr   )r   r   managerr   r   	namespacer@   s          r   &_prune_inactive_memory_provider_skillsr     s     577555555  ""G+/*0022, , E E' )22377	1a''$$^44GG''777*..~tDDDDE Er!   
List[dict]c            	     <   g } t                                           s| S t                      }|s| S t          |          }|s| S |dz  }|                                s| S t           |j        v p|j        t           k    }|rd| dnt           d| d}	 |t          j	        v rt          j	        |         }n|s=t          t          g            t          t           d| t          |          g           t          j                            |t          |                    }|r|j        s| S t          j                            |          }|t          j	        |<   |j                            |           t%          |dd          }t'          |          s| S d| d}	d	}
|d
z  }|                                rr	 ddl}t+          |d          5 }|                    |          pi }ddd           n# 1 swxY w Y   |                    dd	          }|r|}	|}
n# t0          $ r Y nw xY wt%          || dd          pt%          |dd          }|                     ||	|
|||d           n3# t0          $ r&}t4                              d||           Y d}~nd}~ww xY w| S )u  Return CLI commands for the **active** memory plugin only.

    Only one memory provider can be active at a time (set via
    ``memory.provider`` in config.yaml).  This function reads that
    value and only loads CLI registration for the matching plugin.
    If no provider is active, no commands are registered.

    Looks for a ``register_cli(subparser)`` function in the active
    plugin's ``cli.py``.  Returns a list of at most one dict with
    keys: ``name``, ``help``, ``description``, ``setup_fn``,
    ``handler_fn``.

    This is a lightweight scan — it only imports ``cli.py``, not the
    full plugin module.  Safe to call during argparse setup before
    any provider is loaded.
    zcli.pyr   z.clirA   register_cliNzManage z memory pluginrl   r   r   r   r   r   _commandhoncho_command)r   helpr   setup_fn
handler_fnpluginz-Failed to scan CLI for memory plugin '%s': %s)rC   r'   r   ri   r9   r   rr   r   r   r   r    r   r   r   r   r   r   r   rs   r   r   r   r   r^   r(   rH   r_   r`   )r   r   
plugin_dircli_filer   ru   cli_modr   r   	help_textr   r   r   r   r   r   r   r   s                     r   discover_plugin_cli_commandsr    s   " G%%'' 133O  #?33J H$H?? %);;gz?PTg?gK=Hx9O9999Q`NxNxcrNxNxNxK:Z#+%%k+.GG  ,OR@@@+&::::S__<M   >99S]] D  t{ n55d;;G'.CK$K##G,,,w==%% 	N >o===	.	 
		)k::: 3a>>!,,2D3 3 3 3 3 3 3 3 3 3 3 3 3 3 3xxr22 ' $I"&K    W&B&B&BDII >W&6== 	 	#&$$%
 
 	 	 	 	  Z Z ZDoWXYYYYYYYYZ Nso   BI) *A)I) !I) 6H G/#H /G33H 6G37H I) 
H$!I) #H$$AI) )
J3JJ)r   r   r   r   r   r   )r   r"   )r1   r   r   r2   )r   r>   )r   r   r   r"   )r   r   )r   r   )r   r   )r   r   r   r   r   r   )r   r2   r   r   )r   r   r   r2   r   r   )r   r   r|   )r   r   r   r   )r   r   )0r   
__future__r   r   importlib.machineryimportlib.metadataimportlib.utilloggingr   pathlibr   typingr   r   r   r   r   r	   r   r   	getLoggerr   r_   r   rr   rC   rS   r   __annotations__r   r    r*   r0   r=   rM   rc   ri   re   rf   r   r   r   r   r   r   r   r   r  rR   r!   r   <module>r     s    > # " " " " "                  



       7 7 7 7 7 7 7 7 7 7 7 7 % % % % % % 5444444		8	$	$d8nn+ 4 68 " 8 8 8 8 (> > > >,      $    " " " "J  E E E E<   <      : : : :@ '+, , , , , ,d !/ / / / / /j !{ { { { { {|b b b b b b b bJ     &*E E E E E*` ` ` ` ` `r!   