
    4YshS                        d Z ddlmZ ddlmZ ddlmZ g dZddlmZmZm	Z	 ddl
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mZmZmZmZmZmZmZ erddlmZ d Z G d de       Z! G d de       Z" G d de      Z#ee$ge%f   Z&eee%e$f   eee%e$f   f   Z'ee'df   Z(eee(e$f      Z)ee$ee%e$f   f   Z* G d d      Z+ee   Z,eg df   Z- G d de       Z.d Z/d Z0d#dZ1d Z2 e       Z3d Z4d  Z5d! Z6d" Z7y)$a  
A collection of utilities for canonicalizing and inspecting graphs.

Among other things, they solve of the problem of deterministic bnode
comparisons.

Warning: the time to canonicalize bnodes may increase exponentially on
degenerate larger graphs. Use with care!

Example of comparing two graphs::

    >>> g1 = Graph().parse(format='n3', data='''
    ...     @prefix : <http://example.org/ns#> .
    ...     <http://example.org> :rel
    ...         <http://example.org/same>,
    ...         [ :label "Same" ],
    ...         <http://example.org/a>,
    ...         [ :label "A" ] .
    ... ''')
    >>> g2 = Graph().parse(format='n3', data='''
    ...     @prefix : <http://example.org/ns#> .
    ...     <http://example.org> :rel
    ...         <http://example.org/same>,
    ...         [ :label "Same" ],
    ...         <http://example.org/b>,
    ...         [ :label "B" ] .
    ... ''')
    >>>
    >>> iso1 = to_isomorphic(g1)
    >>> iso2 = to_isomorphic(g2)

These are not isomorphic::

    >>> iso1 == iso2
    False

Diff the two graphs::

    >>> in_both, in_first, in_second = graph_diff(iso1, iso2)

Present in both::

    >>> def dump_nt_sorted(g):
    ...     for l in sorted(g.serialize(format='nt').splitlines()):
    ...         if l: print(l.decode('ascii'))

    >>> dump_nt_sorted(in_both) #doctest: +SKIP
    <http://example.org>
        <http://example.org/ns#rel> <http://example.org/same> .
    <http://example.org>
        <http://example.org/ns#rel> _:cbcaabaaba17fecbc304a64f8edee4335e .
    _:cbcaabaaba17fecbc304a64f8edee4335e
        <http://example.org/ns#label> "Same" .

Only in first::

    >>> dump_nt_sorted(in_first) #doctest: +SKIP
    <http://example.org>
        <http://example.org/ns#rel> <http://example.org/a> .
    <http://example.org>
        <http://example.org/ns#rel> _:cb124e4c6da0579f810c0ffe4eff485bd9 .
    _:cb124e4c6da0579f810c0ffe4eff485bd9
        <http://example.org/ns#label> "A" .

Only in second::

    >>> dump_nt_sorted(in_second) #doctest: +SKIP
    <http://example.org>
        <http://example.org/ns#rel> <http://example.org/b> .
    <http://example.org>
        <http://example.org/ns#rel> _:cb558f30e21ddfc05ca53108348338ade8 .
    _:cb558f30e21ddfc05ca53108348338ade8
        <http://example.org/ns#label> "B" .
    )absolute_import)division)print_function)IsomorphicGraphto_isomorphic
isomorphicto_canonical_graph
graph_diffsimilar)GraphConjunctiveGraphReadOnlyGraphAggregate)BNodeNodeURIRef)sha256)datetime)defaultdict)	SetDictTYPE_CHECKINGUnionListTupleCallableOptionalIterator)HASHc                 r    | j                   dz  dz  dz  }|| j                  z  }|| j                  dz  z  }|S )N   <   g    .A)dayssecondsmicroseconds)tdresults     n/var/www/sten-cake5-migrate2.hellocrow.space/lexinfo-master/env/lib/python3.12/site-packages/rdflib/compare.py_total_secondsr(   u   s?    WWr\B#F
bjjF
boo	))FM    c                       e Zd Zd Zd Zy)_runtimec                     || _         y Nlabelselfr/   s     r'   __init__z_runtime.__init__}   	    
r)   c                 V      j                   j                  dz    _          fd}|S )Nr+   c                      t        j                         } | i |}d|v r7|d   2|d   }t        t        j                         |z
        |j                  <   |S )Nstats)r   nowr(   r/   )argskwargsstartr&   r6   fr1   s        r'   	wrapped_fz$_runtime.__call__.<locals>.wrapped_f   sZ    LLNE''F& VG_%@w$28<<>E3I$Jdjj!Mr)   r/   __name__r1   r;   r<   s   `` r'   __call__z_runtime.__call__   s*    ::j0DJ	 r)   Nr>   
__module____qualname__r2   r@    r)   r'   r+   r+   |       r)   r+   c                       e Zd Zd Zd Zy)_call_countc                     || _         y r-   r.   r0   s     r'   r2   z_call_count.__init__   r3   r)   c                 V      j                   j                  dz    _          fd}|S )Nr+   c                      d|v r>|d   9|d   }j                   |vrd|j                   <   |j                   xx   dz  cc<    | i |S )Nr6   r      r.   )r8   r9   r6   r;   r1   s      r'   r<   z'_call_count.__call__.<locals>.wrapped_f   s[    & VG_%@w::U*()E$**%djj!Q&!d%f%%r)   r=   r?   s   `` r'   r@   z_call_count.__call__   s*    ::j0DJ	& r)   NrA   rD   r)   r'   rG   rG      rE   r)   rG   c                   H     e Zd ZdZ fdZd Zd Z fdZddZddZ	 xZ
S )	r   a%  An implementation of the RGDA1 graph digest algorithm.

    An implementation of RGDA1 (publication below),
    a combination of Sayers & Karp's graph digest algorithm using
    sum and SHA-256 <http://www.hpl.hp.com/techreports/2003/HPL-2003-235R1.pdf>
    and traces <http://pallini.di.uniroma1.it>, an average case
    polynomial time algorithm for graph canonicalization.

    McCusker, J. P. (2015). WebSig: A Digital Signature Framework for the Web.
    Rensselaer Polytechnic Institute, Troy, NY.
    http://gradworks.umi.com/3727015.pdf
    c                 ,    t        t        | 
  di | y )NrD   )superr   r2   )r1   r9   	__class__s     r'   r2   zIsomorphicGraph.__init__   s    ot-77r)   c                     t        |t              syt        |       t        |      k7  ry| j                         |j                         k(  S )zGraph isomorphism testing.F)
isinstancer   leninternal_hashr1   others     r'   __eq__zIsomorphicGraph.__eq__   s?    %1Y#e*$!!#u':':'<<<r)   c                 &    | j                  |       S )z#Negative graph isomorphism testing.)rV   rT   s     r'   __ne__zIsomorphicGraph.__ne__   s    ;;u%%%r)   c                 (    t         t        |          S r-   )rN   r   __hash__)r1   rO   s    r'   rZ   zIsomorphicGraph.__hash__   s    _d466r)   c                 &    | j                  |      S )z*Synonym for IsomorphicGraph.internal_hash.r6   )rS   r1   r6   s     r'   graph_digestzIsomorphicGraph.graph_digest   s    !!!..r)   c                 8    t        |       j                  |      S )z
        This is defined instead of __hash__ to avoid a circular recursion
        scenario with the Memory store for rdflib which requires a hash lookup
        in order to return a generator of triples.
        r\   _TripleCanonicalizerto_hashr]   s     r'   rS   zIsomorphicGraph.internal_hash   s     $D)111>>r)   r-   )r>   rB   rC   __doc__r2   rV   rX   rZ   r^   rS   __classcell__)rO   s   @r'   r   r      s&    8=&7/?r)   r   .c            	       z    e Zd Z	 	 ddee   dededefdZd Z	d Z
ddeeed	f      d
efdZdd defdZd Zd Zy)ColorNnodeshashfunccolor
hash_cachec                 R    |i }|| _         || _        || _        || _        d | _        y r-   )_hash_cacheri   rg   rh   _hash_color)r1   rg   rh   ri   rj   s        r'   r2   zColor.__init__   s4     J%

 r)   c                 :    | j                         \  }}d|d|dS )NzColor z (z nodes)key)r1   rg   ri   s      r'   __str__zColor.__str__   s    xxzu(-u55r)   c                 L    t        | j                        | j                         fS r-   )rR   rg   
hash_colorr1   s    r'   rp   z	Color.key   s    DJJ!233r)   .returnc                 D   || j                   }|| j                  v r| j                  |   S d }t        |t              r ||      S d}|D ]9  }|| j	                  dj                  |D cg c]
  } ||       c}            z  }; d|z  }|| j                  |<   |S c c}w )Nc                 X    t        | t              r| j                         S t        |       S r-   )rQ   r   n3strxs    r'   	stringifyz#Color.hash_color.<locals>.stringify   s     !T"ttv1vr)   r    %x)ri   rl   rQ   r   rh   join)r1   ri   r|   valuetripler{   vals          r'   rs   zColor.hash_color   s    =JJED$$$##E**	 eT"U## 	MFT]]3886,JaYq\,J#KLLE	M%<"%
 -Ks   )BWgraphc                 x   i }| j                   D ]  }t        | j                        }|j                   D ]~  }||j                  |d |f      D 	cg c]  \  }}}	d||j	                         f c}	}}z  }||j                  |d |f      D 	cg c]  \  }}}	|j	                         |df c}	}}z  } t        |      }| j	                  |      }
|
|vr(t        g | j                  || j                        }|||
<   ||
   j                   j                  |        |j                         S c c}	}}w c c}	}}w )NrK      rj   )rg   listri   triplesrs   tuplerf   rh   rl   appendvalues)r1   r   r   colorsn	new_colornodesponew_hash_colorcs               r'   distinguishzColor.distinguish  s>   #% 	3A/3DJJ/?I :?--DRV:X /6q!QQ1<<>* 	 :?--tUV:X /6q!QQ\\^Q* 		 i(I!__Y7NV+"dmmY4CSCST)*~&>"((//2	3  }}s   D.D5c                 2    t        | j                        dk(  S )NrK   )rR   rg   rt   s    r'   discretezColor.discrete  s    4::!##r)   c                 v    t        | j                  d d  | j                  | j                  | j                        S Nr   )rf   rg   rh   ri   rl   rt   s    r'   copyz
Color.copy  s.    JJqM4==$**AQAQ
 	
r)   )rD   Nr-   )r>   rB   rC   r   r   HashFuncColorItemTuple	HashCacher2   rq   rp   r   r   	ColorItemry   rs   r   r   r   r   rD   r)   r'   rf   rf      s    
 !# $ Dz    	 
  64y#~)> ? 3 *W U ($
r)   rf   r   c                      e Zd ZefdedefdZdee   de	fdZ
dee   fdZd Zdee   deeeef      fd	Zdee   d
ee   dee   fdZ ed      ddee   fd       Zdee   dee   fdZ	 ddeee      deeeee   f      deeee   f   fdZ ed      ddgfdee   dee   dee   dee   fd       Zddee   fdZdeeeef   deeef   fdZy)ra   r   rh   c                 H    || _         dt        ffd}i | _        || _        y )Nr   c                             }|j                  t        |       j                  d             t        |j	                         d      S )Nutf8   )updatery   encodeint	hexdigest)r   hrh   s     r'   	_hashfuncz0_TripleCanonicalizer.__init__.<locals>._hashfunc'  s6    
AHHSV]]6*+q{{}b))r)   )r   ry   rl   rh   )r1   r   rh   r   s     ` r'   r2   z_TripleCanonicalizer.__init__$  s'    
	* 	*
 ')!r)   coloringru   c                 f    t        |D cg c]  }|j                         r| c}      dk(  S c c}w Nr   )rR   r   )r1   r   r   s      r'   	_discretez_TripleCanonicalizer._discrete/  s(    x<!qzz|A<=BB<s   ..c           
      l   t               }t               }t        t               | _        | j                  D ]  \  }}}t        |||g      }t        |D cg c]  }t	        |t
              s| c}      }t        |      dkD  sO|||z
  z  }||z  }t	        |t
              r| j                  |   j                  |       t	        |t
              r| j                  |   j                  |       t	        |t
              s| j                  |   j                  |       | j                  |   j                  |        t        |      dkD  r_t        t        |      | j                  | j                        g|D cg c]&  }t        |g| j                  || j                        ( c}z   S g S c c}w c c}w )a\  Finds an initial color for the graph.

        Finds an initial color of the graph by finding all blank nodes and
        non-blank nodes that are adjacent. Nodes that are not adjacent to blank
        nodes are not included, as they are a) already colored (by URI or literal)
        and b) do not factor into the color of any blank node.
        r   r   )setr   
_neighborsr   rQ   r   rR   addrf   r   rh   rl   )	r1   bnodesothersr   r   r   rg   r{   bs	            r'   _initial_colorz#_TripleCanonicalizer._initial_color2  su    !U%c*zz 	.GAq!Aq	NE>1Au)=Q>?A1vz%!)#!a'OOA&**1-a'OOA&**1-a'OOA&**1-OOA&**1-	. v;?$v,$BRBRSTX qc4==!8H8HIX  
 I# ?Xs   F,
*F,
:+F1c                 
   t        |j                        }|j                  t        |j                        f       |j                  j                  |       t        |g| j                  t        |      | j                        }|S r   )
r   ri   r   rR   rg   removerf   rh   r   rl   )r1   ri   
individualr   r   s        r'   _individuatez!_TripleCanonicalizer._individuateR  sg    %	#ekk*,-:&L$--y)9dFVFV
 r)   c              #      K   |D cg c]  }|j                         r| c}D ]  }|j                  D ]  }||f 
  y c c}w wr-   )r   rg   )r1   r   r   r   s       r'   _get_candidatesz$_TripleCanonicalizer._get_candidates\  sG     %:QZZ\!: 	A Ag	:s   AAA%Asequencec                 $   t        |d d      }|d d  }t        |      dkD  r| j                  |      s|j                         }|d d  D ]  }t        |j                        dkD  st        |j                  d   t              s9t        |j                  || j                        d d      }|j                  |       |j                  |       	 |j                  |      }|d | |z   ||dz   d  z   } t        |      dkD  r| j                  |      sg }t               }|D ]U  }	|	j                         }
|
|v r)||
   j                  j                  |	j                         @|j                  |	       |	||
<   W |S # t        $ r |dd  |z   }Y Ew xY w)Nc                 "    | j                         S r-   ro   rz   s    r'   <lambda>z._TripleCanonicalizer._refine.<locals>.<lambda>b  s    !%%' r)   T)rp   reverser   rK   c                 "    | j                         S r-   ro   rz   s    r'   r   z._TripleCanonicalizer._refine.<locals>.<lambda>j  s    aeeg r)   )sortedrR   r   poprg   rQ   r   r   r   r   extendindex
ValueErrordictrs   r   )r1   r   r   r   r   r   sicombined_colorscombined_color_mapri   
color_hashs              r'   _refinez_TripleCanonicalizer._refinea  s   ((94HA;(max(@Aa[ 9qww<!#z!''!*e'D#a4- $F
 OOA&OOF+9%^^A.#+CR=6#9HR!VX<N#N9 (max(@  (*/3v 	7E))+J//":.44;;EKKH&&u-16":.	7  & 9#)!":#89s   "E::FFto_hash_runtimeNr6   c                     d}| j                  |      D ]A  }|| j                  dj                  |D cg c]  }|j                          c}            z  }C |d|z  |d<   |S c c}w )Nr   r\   r}   r~   r^   )canonical_triplesrh   r   rx   )r1   r6   r&   r   r{   s        r'   rb   z_TripleCanonicalizer.to_hash  sr    ,,5,9 	HFdmmCHHf-Eaddf-E$FGGF	H$(6ME.! .Fs   A%c                 l   |D cg c]  }|j                          }}| j                  |      s{|D cg c]  }|j                         r| c}d   }|j                  d   }| j	                  ||      }|j                  |       | j                  ||g      }| j                  |      s{|S c c}w c c}w r   )r   r   r   rg   r   r   r   )r1   r   r   r{   ri   r   r   s          r'   _experimental_pathz'_TripleCanonicalizer._experimental_path  s    &./AFFH//..* (=1

Q=a@E;;q>D))%6IOOI&||Hyk:H ..*  0=s   B,B1	B1	colorings	groupingsc                     |st        t              }t        | D ]C  }t        |D cg c]  }|j                  d    c}      }|D ]
  }|||   z  } |D ]  }|||<   	 E |S c c}w r   )r   r   ziprg   )r1   r   r   groupr   gr   s          r'   _create_generatorz&_TripleCanonicalizer._create_generator  s    
 #C(I)_ 	!E/AQWWQZ/0A "Yq\!" ! 	!!		!  0s   A"
individuationsr   depthc                    |	d|vrd|d<   |dxx   dz  cc<   | j                  |      }g }d }d }d }t        t              }	t               }
|D ]u  \  }}||	v r(|	|   |
z  }t        |      dkD  r|
j	                  |       3|
j	                  |       g }d }|D ]+  }|j                         }|j                  |       ||k(  s*|}- | j                  ||      }|j                  |       | j                  ||g      }t        |D cg c]  }|j                          c}      }| j                  |      }t        |D cg c]  }|j                          c}      }|r| j                  ||g|	      }	|}|||k  r	|g}|}|}5||kD  r|>|dxx   dz  cc<   M||k7  r|j                  |       e|i|dxx   dz  cc<   x |D cg c]  }| j                  |      s| }}t        |      dk(  rcd }d }|D ]U  }|d   g}| j                  |||      }t        D cg c]  }|j                          c}      }|||kD  sL|g}|}|d   }W ||d<   |d   S c c}w c c}w c c}w c c}w )Npruningsr   rK   r6   r   )r   r   r   rR   r   r   r   r   r   r   rp   r   r   r   _traces)r1   r   r6   r   
candidatesbest
best_scorebest_experimental_scorelast_coloring	generatorvisited	candidateri   vcoloring_copy
color_copyr   c_copyr   refined_coloringcolor_scoreexperimentalexperimental_scorer{   r   
best_depthds                              r'   r   z_TripleCanonicalizer._traces  s    5!8 !E*aA))(3
"$
"&+6s+;	 U * &	+IuI%i(72q6A:KK	*KK	")+MJ ($$V,:!'J	(
 ))*i@I  +#||MI;G2B CQ CDK22=AL!$|%D!aeeg%D!E 22"L19	 )M!Z+%=()(
*<'k)$*%*%#'>>,- $*%*%M&	+N 37&LQ$..:Kq&L&Lx=AJJ  &1XJ LLaLH	#6F$GQUUW$GH%z)A ){H!,J!"1J& "E!H{G !D%D( 'M %Hs   I
<I"

I'!I'!I,
c              #     K   |t        j                         }| j                         }|3t        | j                        |d<   t        dt        |      dz
        |d<   | j                  ||d d        }|1t        t        j                         z
        |d<   t        |      |d<   | j                  |      s"dg}| j                  |||      }||d   |d<   n|
d|d	<   d|d<   |t        |      |d
<   t        |D cg c]!  }|j                  d   |j                         f# c}      }|#t        t        j                         z
        |d<   | j                  D ]!  }t        | j                  ||            }| # y c c}w w)Ntriple_countr   rK   adjacent_nodesinitial_coloring_runtimeinitial_color_countr   
tree_depthr   color_countcanonicalize_triples_runtime)r   r7   r   rR   r   maxr   r(   r   r   r   rg   rs   r   _canonicalize_bnodes)	r1   r6   start_coloringr   r   r   bnode_labelsr   r&   s	            r'   r   z&_TripleCanonicalizer.canonical_triples  s    %\\^N&&($'

OE.!&)!S]Q->&?E"#<<(1+60>/1E,- ,/x=E'(~~h'CE||HE|GH &+Ahl#&'E"#"#E,#&x=E- 8Laaggaj!,,.9LM4B/5E01 jj 	F444V\JKFL	 Ms   C<F>&F$A"Fr   labelsc              #   l   K   |D ]+  }t        |t              rt        d||   z         (| - y w)Nzcb%s)r   )rQ   r   )r1   r   r   terms       r'   r   z)_TripleCanonicalizer._canonicalize_bnodes  s:       	D$&&6$<"788
		s   24r-   ) r>   rB   rC   r   r   _HashTr2   r   rf   boolr   r   r   r   r   r   r   r   r+   r   Statsrb   r   r   r   r   rG   r   r   r   ry   r   rD   r)   r'   ra   ra   #  s   8> 	"e 	"v 	"C$u+ C$ CU @U tU{AS8T 
U tE{ tE{ >  Xe_  !4; 4;  6:U$ Ds4y12 
dCIo		 !" "&3	Du+D D Cy	D
 
eD #DL x  DD$,-7;D#Ir)   ra   c                     t        | t              r| S t               }t        | d      rt        | j                        }|| z  }|S )N
identifier)r  )rQ   r   hasattrr  )r   r&   s     r'   r   r     sA    %)Ful# E,<,<=
eOFMr)   c                 p    t        |       j                         }t        |      j                         }||k(  S )a  Compare graph for equality.

    Uses an algorithm to compute unique hashes which takes bnodes into account.

    Examples::

        >>> g1 = Graph().parse(format='n3', data='''
        ...     @prefix : <http://example.org/ns#> .
        ...     <http://example.org> :rel <http://example.org/a> .
        ...     <http://example.org> :rel <http://example.org/b> .
        ...     <http://example.org> :rel [ :label "A bnode." ] .
        ... ''')
        >>> g2 = Graph().parse(format='n3', data='''
        ...     @prefix ns: <http://example.org/ns#> .
        ...     <http://example.org> ns:rel [ ns:label "A bnode." ] .
        ...     <http://example.org> ns:rel <http://example.org/b>,
        ...             <http://example.org/a> .
        ... ''')
        >>> isomorphic(g1, g2)
        True

        >>> g3 = Graph().parse(format='n3', data='''
        ...     @prefix : <http://example.org/ns#> .
        ...     <http://example.org> :rel <http://example.org/a> .
        ...     <http://example.org> :rel <http://example.org/b> .
        ...     <http://example.org> :rel <http://example.org/c> .
        ... ''')
        >>> isomorphic(g1, g3)
        False
    r`   )graph1graph2gd1gd2s       r'   r   r     s4    > v
&
.
.
0C
v
&
.
.
0C#:r)   Nc                 j    t               }|t        |       j                  |      z  }t        |g      S )zCreates a canonical, read-only graph.

    Creates a canonical, read-only graph where all bnode id:s are based on
    deterministical SHA-256 checksums, correlated with the graph contents.
    r\   )r   ra   r   r   )g1r6   r   s      r'   r	   r	   C  s6     GE	!"%77e7DDE!5'**r)   c                 V    t        |       }t        |      }||z  }||z
  }||z
  }|||fS )zEReturns three sets of triples: "in both", "in first" and "in second".)r	   )r  g2cg1cg2in_bothin_first	in_seconds          r'   r
   r
   N  s@     R
 C
R
 CCiGSyHc	IXy))r)   c                 :    t        d t        | |      D              S )a@  Checks if the two graphs are "similar".

    Checks if the two graphs are "similar", by comparing sorted triples where
    all bnodes have been replaced by a singular mock bnode (the
    ``_MOCK_BNODE``).

    This is a much cheaper, but less reliable, alternative to the comparison
    algorithm in ``isomorphic``.
    c              3   ,   K   | ]  \  }}||k(    y wr-   rD   ).0t1t2s      r'   	<genexpr>zsimilar.<locals>.<genexpr>f  s     IHRrRxIs   )all_squashed_graphs_triples)r  r  s     r'   r   r   \  s     I(@R(HIIIr)   c              #      K   t        t        t        |             t        t        |                  D ]  \  }}||f  y wr-   )r   r   _squash_graph)r  r  r  r  s       r'   r  r  i  s=     }R016-:K3LM R"fs   A Ac                     d | D        S )Nc              3   2   K   | ]  }t        |        y wr-   )_squash_bnodes)r  r   s     r'   r  z _squash_graph.<locals>.<genexpr>o  s     7vN6"7s   rD   )r   s    r'   r  r  n  s    777r)   c                 &    t        d | D              S )Nc              3   T   K   | ]   }t        |t              xr t        xs | " y wr-   )rQ   r   _MOCK_BNODE)r  ts     r'   r  z!_squash_bnodes.<locals>.<genexpr>s  s$     M*Q&6;<1<Ms   &()r   )r   s    r'   r!  r!  r  s    MfMMMr)   r-   )8rc   
__future__r   r   r   __all__rdflib.graphr   r   r   rdflib.termr   r   r   hashlibr   r   collectionsr   typingr   r   r   r   r   r   r   r   r   _hashlibr   r(   objectr+   rG   r   ry   r   r   r   r   r   r  rf   _TripleTr  ra   r   r   r	   r
   r$  r   r  r  r!  rD   r)   r'   <module>r0     sM  IT '  % I H + +   #
 
 
 v && &*?& *?Z SE3J%S/65c?:;	y#~&T.#-./	S%S/!"F
 F
R :	"f*	o6 od!H+* g
J
8Nr)   