� u��g�v��f�ddlZddlZddlZddlZddlZddlZddlmZddlm Z ddl m Z m Z ddl mZddlmZddlmZmZdd lmZeje��ZGd �d e��ZGd �d e ��ZGd�de��ZGd�de��ZGd�de��ZGd�de ��Z!d�Z"d�Z#e ��Z$e ��Z%e ��Z&e ��Z'e ��Z(e ��Z)d�Z*d�Z+d%d�Z,d�Z-d�Z.d�Z/d�Z0dej1�2d ��d!�Z3Gd"�d#e��Z4d$�Z5dS)&�N)�urlparse)�UserDict)�Optional�Union�)� TokenCache)�_IndividualCache)�ThrottledHttpClientBase�RetryAfterParser)�_is_running_in_cloud_shellc��eZdZdS)�ManagedIdentityErrorN��__name__� __module__� __qualname__���e/home/asafur/pinokio/api/open-webui.git/app/env/lib/python3.11/site-packages/msal/managed_identity.pyrr��������Drrc���eZdZdZdZdZdZdZdZdZ eded ed iZ e d ���Z e d ���Z e d ���Zd�fd� Z�xZS)�ManagedIdentityz�Feed an instance of this class to :class:`msal.ManagedIdentityClient` to acquire token for the specified managed identity. �ManagedIdentityIdType�Id�ClientId� ResourceId�ObjectId�SystemAssigned� client_id� msi_res_id� object_idc��t|t��p)|�|��p|�|��S�N)� isinstancer�is_system_assigned�is_user_assigned��cls�unknowns r�is_managed_identityz#ManagedIdentity.is_managed_identity/s@���7�O�4�4�-��%�%�g�.�.�-��#�#�G�,�,� .rc��t|t��p7t|t��o"|�|j��|jkSr#)r$�SystemAssignedManagedIdentity�dict�get�ID_TYPE�SYSTEM_ASSIGNEDr's rr%z"ManagedIdentity.is_system_assigned5sH���'�#@�A�A�A� �w�� %� %� @�� � �C�K�(�(�C�,?�?� Arc���t|t��pOt|t��o:|�|j��|jvo|�|j��Sr#)r$�UserAssignedManagedIdentityr-r.r/�_types_mapping�IDr's rr&z ManagedIdentity.is_user_assigned;s[���'�#>�?�?�%� �w�� %� %� $�� � �C�K�(�(�C�,>�>� $�� � �C�F�#�#� %rNc�t��tt|���|j||j|i��dSr#)�superr�__init__r/r4)�self� identifier�id_type� __class__s �rr7zManagedIdentity.__init__BsB��� �o�t�$�$�-�-� �L�'� �G�Z�/ � � � � � r)NN)rrr�__doc__r/r4� CLIENT_ID� RESOURCE_ID� OBJECT_IDr0r3� classmethodr*r%r&r7� __classcell__�r;s@rrrs����������&�G� �B��I��K��I�&�O� �;��\��;��N� �.�.��[�.� �A�A��[�A� �%�%��[�%�  � � � � � � � � � rrc�"��eZdZdZ�fd�Z�xZS)r,z�Represent a system-assigned managed identity. It is equivalent to a Python dict of:: {"ManagedIdentityIdType": "SystemAssigned", "Id": None} or a JSON blob of:: {"ManagedIdentityIdType": "SystemAssigned", "Id": null} c�d��tt|���|j���dS)N)r:)r6r,r7r0)r8r;s �rr7z&SystemAssignedManagedIdentity.__init__Us.��� �+�T�2�2�;�;�D�DX�;�Y�Y�Y�Y�Yr�rrrr<r7rArBs@rr,r,JsK������� � �Z�Z�Z�Z�Z�Z�Z�Z�Zrr,c�,��eZdZdZdddd��fd� Z�xZS)r2a9Represent a user-assigned managed identity. Depends on the id you provided, the outcome is equivalent to one of the below:: {"ManagedIdentityIdType": "ClientId", "Id": "foo"} {"ManagedIdentityIdType": "ResourceId", "Id": "foo"} {"ManagedIdentityIdType": "ObjectId", "Id": "foo"} N)r� resource_idr!c�l��|r5|s3|s1tt|���|j|���dS|s5|r3|s1tt|���|j|���dS|s5|s3|r1tt|���|j|���dSt d���)N)r:r9zPYou shall specify one of the three parameters: client_id, resource_id, object_id)r6r2r7r=r>r?r)r8rrGr!r;s �rr7z$UserAssignedManagedIdentity.__init__bs��� � 5�[� 5�� 5� �-�t� 4� 4� =� =���9� >� >� >� >� >� >�� 5�{� 5�9� 5� �-�t� 4� 4� =� =��(�[� >� B� B� B� B� B�� 5�;� 5�9� 5� �-�t� 4� 4� =� =���9� >� >� >� >� >� >�'�4�5�5� 5rrErBs@rr2r2YsU���������%)�d�d� 5� 5� 5� 5� 5� 5� 5� 5� 5� 5� 5rr2c���eZdZ�fd�Z�xZS)�_ThrottledHttpClientc �����tt���j|fi|��t�j�fd�t d��j���|j���_dS)Nc ����d�|d��t|�d����t|�d����z����S)Nz"REQ {} hash={} 429/5xx/Retry-Afterr�params�data)�format�_hash�strr.)�func�args�kwargsr8s �r�<lambda>z/_ThrottledHttpClient.__init__.<locals>.<lambda>wsd���1U�1\�1\��Q��� � ��� � �8�,�,�-�-��F�J�J�v�4F�4F�0G�0G�G�I�I�2�2�r�)�mapping� key_maker� expires_in)r6rJr7�IndividualCache�_expiring_mappingr �parser.)r8� http_clientrTr;s` �rr7z_ThrottledHttpClient.__init__ss�����2��"�D�)�)�2�;�I�I�&�I�I�I� �?��*�����(��*�*�0� � � ��o� � ����r)rrrr7rArBs@rrJrJrs8������� � � � � � � � � rrJc�x�eZdZdZd\ZZdZdZdZddd�de e e e e ffd �Zd �Zdd �d ed eefd�ZdS)�ManagedIdentityClienta*This API encapsulates multiple managed identity back-ends: VM, App Service, Azure Automation (Runbooks), Azure Function, Service Fabric, and Azure Arc. It also provides token cache support. .. note:: Cloud Shell support is NOT implemented in this class. Since MSAL Python 1.18 in May 2022, it has been implemented in :func:`PublicClientApplication.acquire_token_interactive` via calling pattern ``PublicClientApplication(...).acquire_token_interactive(scopes=[...], prompt="none")``. That is appropriate, because Cloud Shell yields a token with delegated permissions for the end user who has signed in to the Azure Portal (like what a ``PublicClientApplication`` does), not a token with application permissions for an app. )N�managed_identity� token_source�identity_provider�cacheN)� token_cache� http_cacher`c���t�|��std|�����||_t t |t ��r|jn||���|_|p t��|_ dS)a� Create a managed identity client. :param managed_identity: It accepts an instance of :class:`SystemAssignedManagedIdentity` or :class:`UserAssignedManagedIdentity`. They are equivalent to a dict with a certain shape, which may be loaded from a JSON configuration file or an env var. :param http_client: An http client object. For example, you can use ``requests.Session()``, optionally with exponential backoff behavior demonstrated in this recipe:: import msal, requests from requests.adapters import HTTPAdapter, Retry s = requests.Session() retries = Retry(total=3, backoff_factor=0.1, status_forcelist=[ 429, 500, 501, 502, 503, 504]) s.mount('https://', HTTPAdapter(max_retries=retries)) managed_identity = ... client = msal.ManagedIdentityClient(managed_identity, http_client=s) :param token_cache: Optional. It accepts a :class:`msal.TokenCache` instance to store tokens. It will use an in-memory token cache by default. :param http_cache: Optional. It has the same characteristics as the :paramref:`msal.ClientApplication.http_cache`. Recipe 1: Hard code a managed identity for your app:: import msal, requests client = msal.ManagedIdentityClient( msal.UserAssignedManagedIdentity(client_id="foo"), http_client=requests.Session(), ) token = client.acquire_token_for_client("resource") Recipe 2: Write once, run everywhere. If you use different managed identity on different deployment, you may use an environment variable (such as MY_MANAGED_IDENTITY_CONFIG) to store a json blob like ``{"ManagedIdentityIdType": "ClientId", "Id": "foo"}`` or ``{"ManagedIdentityIdType": "SystemAssigned", "Id": null}``. The following app can load managed identity configuration dynamically:: import json, os, msal, requests config = os.getenv("MY_MANAGED_IDENTITY_CONFIG") assert config, "An ENV VAR with value should exist" client = msal.ManagedIdentityClient( json.loads(config), http_client=requests.Session(), ) token = client.acquire_token_for_client("resource") zIncorrect managed_identity: )reN) rr*r�_managed_identityrJr$r r]� _http_clientr� _token_cache)r8r`r]rdres rr7zManagedIdentityClient.__init__�s���H�2�2�3C�D�D� C�&�A�/?�A�A�C�C� C�!1���0��k�+B�C�C� U�K� #� #�IT�!� � � ���(�7�:�<�<����rc�N�|j�tj��|_|jSr#)� _ManagedIdentityClient__instance�socket�getfqdn)r8s r� _get_instancez#ManagedIdentityClient._get_instance�s!�� �?� "�$�n�.�.�D�O���r)�claims_challenge�resourceroc �r�d}|j�tjd��}t j��}|�s|j�|jjj|gt||� ��|j d������}|D]�}t|d��|z }|dkr�!t�d��d|d d |�d d ��d t|��|j|ji}d |vr3t|d ��|d <t|d ��|krn|cS t#|j|j|��} d| vr�| �d d��}d| vr|dkrt|dz ��| d<|j�t||gd�|� ��|j ��| ii�����d| vrt|| dz��| d <|j| |j<| rd| vs|s| Sn #|s�YnxYw|S)asAcquire token for the managed identity. The result will be automatically cached. Subsequent calls will automatically search from cache first. :param resource: The resource for which the token is acquired. :param claims_challenge: Optional. It is a string representation of a JSON object (which contains lists of claims being requested). The tenant admin may choose to revoke all Managed Identity tokens, and then a *claims challenge* will be returned by the target resource, as a `claims_challenge` directive in the `www-authenticate` header, even if the app developer did not opt in for the "CP1" client capability. Upon receiving a `claims_challenge`, MSAL will skip a token cache read, and will attempt to acquire a new token. .. note:: Known issue: When an Azure VM has only one user-assigned managed identity, and your app specifies to use system-assigned managed identity, Azure VM may still return a token for your user-assigned identity. This is a service-side behavior that cannot be changed by this library. `Azure VM docs <https://learn.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/how-to-use-vm-token#get-a-token-using-http>`_ N� SYSTEM_ASSIGNED_MANAGED_IDENTITY)r� environment�realm�home_account_id)�target�query� expires_oni,zCache hit an AT� access_token�secret� token_type�BearerrY� refresh_oni� refresh_ini �z https://{}/{})r�scope�token_endpoint�responserMrN�error)rgr.rr4�timeri�find�CredentialType� ACCESS_TOKENr-rn�_tenant�int�logger�debug� _TOKEN_SOURCE�_TOKEN_SOURCE_CACHE� _obtain_tokenrh�addrO�_TOKEN_SOURCE_IDP) r8rpro�access_token_from_cache�client_id_in_cache�now�matches�entryrY�results r�acquire_token_for_clientz.ManagedIdentityClient.acquire_token_for_client�s���D#'��!�3�7�7� � � B�D�D���i�k�k��� /��'�,�,��!�0�=� �z��0� $� 2� 2� 4� 4��,�$(� ���-� � �G�!� /� /�� ��|�!4�5�5��;� ���$�$��� � �.�/�/�/�"�E�(�O� �%�)�)�L�(�"C�"C� �#�j�/�/��&��(@� +�'�  �5�(�(�<?��l�@S�<T�<T�+�L�9��5��.�/�/�#�5�5���.�.�.�.� �"�4�#4�d�6L�h�W�W�F���'�'�#�Z�Z� �d�;�;� ��v�-�-�*��2D�2D�+.�z�A�~�+>�+>�F�<�(��!�%�%�d�0�#�*�#2�#9�#9��*�*�,�,�d�l�$<�$<�#���'�'�'���� �6�)�)�+.�s�V�L�5I�/I�+J�+J�F�<�(�-1�-C��t�)�*�� �7�&�0�0�:Q�0�� �1�� �*� �� � ����&�&s �C$H-�-H4)rrrr<rkr�r�r�r�rr-rr,r2r7rnrQrr�rrrr_r_�s���������"3��J��"�M�+��!����W8�W8�W8�� � � )� '� )��W8�W8�W8�W8�r���+/� Y'�Y'�Y'��Y'�#�3�-� Y'�Y'�Y'�Y'�Y'�Y'rr_c�r�t|��}|jr d�|j|j��S|S)Nz{}://{})r�schemerO�netloc)r��us r�_scope_to_resourcer�Ss6������A��x�4������!�(�3�3�3� �Lrc�`�dtjvr dtjvrtjdStjdkrtj�d��sLtjdkr>tj�tj�d����rdSdSdS)N�IDENTITY_ENDPOINT� IMDS_ENDPOINT�linuxz/opt/azcmagent/bin/himds�win32z4${ProgramFiles}\AzureConnectedMachineAgent\himds.exez5http://localhost:40342/metadata/identity/oauth2/token)�os�environ�sys�platform�path�exists� expandvarsrrr�_get_arc_endpointr�Zs����b�j�(�(�_�� �-J�-J��z�-�.�.� � ����B�G�N�N�3M�$N�$N�� �<�7� "� "�r�w�~�~�b�g�6H�6H� C�7 �7 �( �( � "� G�F� #� "� "� "rc�R�dtjvr#dtjvrdtjvrtSdtjvrdtjvrtSdtjvrdtjvrtSt ��rt St��rtStS)z�Detect the current environment and return the likely identity source. When this function returns ``CLOUD_SHELL``, you should use :func:`msal.PublicClientApplication.acquire_token_interactive` with ``prompt="none"`` to obtain a token. r��IDENTITY_HEADER�IDENTITY_SERVER_THUMBPRINT� MSI_ENDPOINT� MSI_SECRET) r�r��SERVICE_FABRIC� APP_SERVICE�MACHINE_LEARNINGr�� AZURE_ARCr � CLOUD_SHELL� DEFAULT_TO_VMrrr�get_managed_identity_sourcer�ns��� �r�z�)�)�.?�2�:�.M�.M�,�� �:�:����b�j�(�(�->�"�*�-L�-L������#�#� �� �(B�(B���������!�#�#���� �rc��dtjvr{dtjvrmdtjvr_|rt�d��t |tjdtjdtjd|��SdtjvrAdtjvr3t |tjdtjd||��SdtjvrAdtjvr3t |tjdtjd||��St��}|r:t� |��rtd���t|||��St|||��S)Nr�r�r�z�Ignoring managed_identity parameter. Managed Identity in Service Fabric is configured in the cluster, not during runtime. See also https://learn.microsoft.com/en-us/azure/service-fabric/configure-existing-cluster-enable-managed-identity-token-servicer�r�z�Invalid managed_identity parameter. Azure Arc supports only system-assigned managed identity, See also https://learn.microsoft.com/en-us/azure/service-fabric/configure-existing-cluster-enable-managed-identity-token-service) r�r�r�r��_obtain_token_on_service_fabric�_obtain_token_on_app_service�!_obtain_token_on_machine_learningr�rr&r�_obtain_token_on_arc�_obtain_token_on_azure_vm)r]r`rp� arc_endpoints rr�r��s����r�z�)�)�.?�2�:�.M�.M�,�� �:�:� � K� �L�L�J� K� K� K� /� � �J�*� +� �J�(� )� �J�3� 4� �  � � ��b�j�(�(�->�"�*�-L�-L�+� � �J�*� +� �J�(� )� � �  � � ����#�#� �� �(B�(B�0� � �J�~� &� �J�|� $� � �  � � �%�&�&�L��I� � +� +�,<� =� =� K�&�J�K�K� K� $�K��x�H�H�H� $�[�2B�H� M� M�Mrc��|p tj�|�tj����}|r|tj||<dSdSr#)rr3r.r/r4)rMr`� types_mapping�id_names r� _adjust_paramr��sZ���>�� >�C�C����_�4�5�5�7�7�G��?�*�?�+=�>��w����?�?rc�r�t�d��d|d�}t||��|�t jdd���d��dz|dd i� ��} tj|j ��}|�d ��r\|�d ��rG|d t|d ��|�d ��|�dd��d�S|S#tj j $r"t�d|j ���wxYw)Nz0Obtaining token via managed identity on Azure VMz 2018-02-01�� api-versionrp�!AZURE_POD_IDENTITY_AUTHORITY_HOSTzhttp://169.254.169.254�/z/metadata/identity/oauth2/token�Metadata�true�rM�headersryrYrpr{r|�ryrYrpr{�!IMDS emits unexpected payload: %s) r�r�r�r.r��getenv�strip�json�loads�textr��decoder�JSONDecodeError)r]r`rprM�resp�payloads rr�r��sL�� �L�L�C�D�D�D�#�� � �F��&�*�+�+�+� �?�?� � � /�1I� � ��e�C�j�j�<� =���V�$� � � �D� ��*�T�Y�'�'�� �;�;�~� &� &� �7�;�;�|�+D�+D� � '�� 7�!�'�,�"7�8�8�#�K�K� �3�3�%�k�k�,��A�A� �� � ��� �<� '����� � �8�$�)�D�D�D� ����s�4B D�>D�6D6c �*�t�d��d|d�}t||tjdtjdtjdi���|�|||dd �� ��} tj |j ��}|�d ��r}|�d ��rh|d t|d ��ttj ����z |�d ��|�dd��d�Sdd� |�d��|�d����d�S#tjj$r"t�d|j ���wxYw)z�Obtains token for `App Service <https://learn.microsoft.com/en-us/azure/app-service/overview-managed-identity?tabs=portal%2Chttp#rest-endpoint-reference>`_, Azure Functions, and Azure Automation. z9Obtaining token via managed identity on Azure App Servicez 2019-08-01r�r� mi_res_idr!)r�r�)zX-IDENTITY-HEADERr�r�ryrxrpr{r|r�� invalid_scopez{}, {}� statusCode�message�r��error_descriptionr�)r�r�r�rr=r>r?r.r�r�r�r�r�rOr�r�)r]�endpoint�identity_headerr`rprMr�r�s rr�r��s��� �L�L�L�M�M�M�#�� � �F��&�*��!�;��#�[��!�;�;����� �?�?���!0���� � � �D���*�T�Y�'�'�� �;�;�~� &� &� �7�;�;�|�+D�+D� � '�� 7�!�'�,�"7�8�8�3�t�y�{�{�;K�;K�K�#�K�K� �3�3�%�k�k�,��A�A� �� �%�!)���� � �L�)�)�7�;�;�y�+A�+A�"C�"C��� �� �<� '����� � �8�$�)�D�D�D� ����s�2B*E�>E�6Fc���t�d��d|d�}t||��|ddkrd|vr|�d��|d<|�||d|i���} t j|j��}|�d ��r}|�d ��rh|d t|d ��ttj ����z |�d ��|�d d ��d�Sdd� |��d�S#t j j $r"t�d|j���wxYw)Nz>Obtaining token via managed identity on Azure Machine Learningz 2017-09-01r�r�r�clientidrzr�ryrxrpr{r|r�r�z{}r�r�) r�r�r��popr.r�r�r�r�r�rOr�r�)r]r�rzr`rprMr�r�s rr�r�s���  �L�L�Q�R�R�R�)�x� @� @�F��&�*�+�+�+� �m�� �,�,���1F�1F�#�Z�Z� �4�4��z�� �?�?����6�"� � � �D� ��*�T�Y�'�'�� �;�;�~� &� &� �7�;�;�|�+D�+D� � '�� 7�!�'�,�"7�8�8�3�t�y�{�{�;K�;K�K�#�K�K� �3�3�%�k�k�,��A�A� �� �%�!%���W�!5�!5��� �� �<� '����� � �8�$�)�D�D�D� ����s�3B*D6�D6�66E,c��t�d��|�|d|d�d|i���} tj|j��}|�d��ro|�d��rZ|dt |d��t tj����z |�d��|d d �S|�d i��}d d dd�}|�|d dd��|jd�S#tjj $r"t�d|j���wxYw)zfObtains token for `Service Fabric <https://learn.microsoft.com/en-us/azure/service-fabric/>`_ z<Obtaining token via managed identity on Azure Service Fabricz2019-07-01-previewr��Secretr�ryrxrpr{r�r��unauthorized_client�invalid_clientr�)�SecretHeaderNotFound�ManagedIdentityNotFound�ArgumentNullOrEmpty�code�invalid_requestr�r�) r�r�r.r�r�r�r�r�r�r�) r]r�r��server_thumbprintrpr�r�r�� error_mappings rr�r�*sw�� �L�L�O�P�P�P� �?�?��3��J�J��?�+� � � �D� ��*�T�Y�'�'�� �;�;�~� &� &� �7�;�;�|�+D�+D� � '�� 7�!��L�)����D�I�K�K�(�(�)�$�K�K� �3�3�%�l�3� �� �� � �G�R�(�(��$9�'7�#2��� � #�&�&�w�w�'7��'?�AR�S�S�!%���� �� �<� '����� � �8�$�)�D�D�D� ����s�BD�AD�6Ez/var/opt/azcmagent/tokensz/%ProgramData%\AzureConnectedMachineAgent\Tokens)r�r�c��eZdZdS)�ArcPlatformNotSupportedErrorNrrrrr�r�Xrrr�c �� �t�d��|�|d|d�ddi���}d� � fd�|j���D���� d ���d ��}t |��d kr|d ���d ks'td� |j�����tj tvrtdtj �d����tj�ttj tj�tj�|d����d dz��}tj|��jdkrtd���t+|��5}|���}ddd��n #1swxYwY|�|d|d�dd� |��d����} t/j|j��} | �d��r\| �d��rG| dt5| d��| �dd��| �d��d�Sn#t.jj$rYnwxYwd|jd�S)Nz1Obtaining token via managed identity on Azure Arcz 2020-06-01r�r�r�r�zwww-authenticatec�p��i|]2\}}|����k�|���|��3Sr)�lower)�.0�k�v�www_auths �r� <dictcomp>z(_obtain_token_on_arc.<locals>.<dictcomp>dsB��� � � ���A������h�9N�9N���� � �1�9N�9N�9Nr��=rrz basic realmz*Unrecognizable WWW-Authenticate header: {}z Platform z was undefined and unsupportedrz.keyiz+Local key file shall not be larger than 4KBzBasic {})r�� AuthorizationryrYr{r|rp)ryrYr{rpr�r�)r�r�r.r��items�split�lenr�rrOr�r��+_supported_arc_platforms_and_their_prefixesr�r�r��join�splitext�basename�stat�st_size�open�readr�r�r�r�r�r�) r]r�rpr�� challenge�filename�frzr�r�r�s @rr�r�[s��� �L�L�D�E�E�E� �?�?��+��B�B��V�$� � � �D� "�H� � � � �"&��!3�!3�!5�!5� � � � �#�h�� � �E�E�#�J�J� � � �N�N�a� � �I�a�L�$6�$6�$8�$8�M�$I�$I�"� 8� ?� ?�� � M� M�O�O� O� �|�F�F�F�*� D�� � D� D� D�F�F� F��w�|�|�3�C�L�A� ������)�)�)�A�,�7�7�8�8��;�f�D�F�F�H� �w�x��� �4�'�'�"�#P�Q�Q�Q� �h����1�����������������������������+��B�B�#�j�6G�6G��6O�6O�P�P�� � �H�  ��*�X�]�+�+�� �;�;�~� &� &� �7�;�;�|�+D�+D� �!(�� 7�!�'�,�"7�8�8�%�k�k�,��A�A�#�K�K� �3�3� �� ��� �<� '� � � � �� ����#�%�]� � � s%�G)�)G-�0G-�&B J1�1K�Kr#)6r��loggingr�rlr�r�� urllib.parser� collectionsr�typingrrrdr�individual_cacher rZ�throttled_http_clientr r � cloudshellr � getLoggerrr�� ValueErrorrrr,r2rJ�objectr_r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�rrr�<module>rs/��  � � � ����� � � � � � � � � � � � � � � � �!�!�!�!�!�!� � � � � � �"�"�"�"�"�"�"�"�#�#�#�#�#�#�A�A�A�A�A�A�L�L�L�L�L�L�L�L�2�2�2�2�2�2� �� �8� $� $�� � � � � �:� � � �, �, �, �, �, �h�, �, �, �^ Z� Z� Z� Z� Z�O� Z� Z� Z�5�5�5�5�5�/�5�5�5�2 � � � � �2� � � � N'�N'�N'�N'�N'�F�N'�N'�N'�b��� G� G� G��f�h�h� � �F�H�H� ��f�h�h� ��6�8�8����������� ����,,N�,N�,N�^?�?�?�?����:/�/�/�b���D&�&�&�T)� �W� � � R� S� S�/�/�+�  � � � � �#7� � � �1 �1 �1 �1 �1 r
Memory