Ë
    Ûqj¿@  ã                  óB  — d Z ddlmZ ddlZddlZddlmZmZ ddlm	Z	m
Z
mZmZ ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddd„Z G d„ de«      Z G d„ de«      Z G d„ de«      Z G d„ de«      Z G d„ de«      Z G d„ de«      Z ed«      Z ed«      Z y)z 
SQL composition utility module
é    )ÚannotationsN)ÚABCÚabstractmethod)ÚAnyÚIteratorÚIterableÚSequenceé   )ÚEscaping)ÚAdaptContext)ÚPyFormat)ÚLiteralString)Úconn_encoding)ÚTransformerc                ó6   — t        | «      j                  |«      S )aÞ  
    Adapt a Python object to a quoted SQL string.

    Use this function only if you absolutely want to convert a Python string to
    an SQL quoted literal to use e.g. to generate batch SQL and you won't have
    a connection available when you will need to use it.

    This function is relatively inefficient, because it doesn't cache the
    adaptation rules. If you pass a `!context` you can adapt the adaptation
    rules used, otherwise only global rules are used.

    )ÚLiteralÚ	as_string)ÚobjÚcontexts     úL/var/www/html/kelly-backend/venv/lib/python3.12/site-packages/psycopg/sql.pyÚquoter      s   € ô �3‹<×!Ñ! 'Ó*Ð*ó    c                  ó^   — e Zd ZdZdd„Zdd„Zeddd„«       Zddd„Zdd„Z	dd„Z
dd	„Zdd
„Zy)Ú
ComposableaP  
    Abstract base class for objects that can be used to compose an SQL string.

    `!Composable` objects can be joined using the ``+`` operator: the result
    will be a `Composed` instance containing the objects joined. The operator
    ``*`` is also supported with an integer argument: the result is a
    `!Composed` instance containing the left argument repeated as many times as
    requested.

    `!SQL` and `!Composed` objects can be passed directly to
    `~psycopg.Cursor.execute()`, `~psycopg.Cursor.executemany()`,
    `~psycopg.Cursor.copy()` in place of the query string.
    c                ó   — || _         y ©N©Ú_obj)Úselfr   s     r   Ú__init__zComposable.__init__5   s	   € Øˆ�	r   c                óN   — | j                   j                  › d| j                  ›d�S )NÚ(Ú))Ú	__class__Ú__name__r   ©r   s    r   Ú__repr__zComposable.__repr__8   s$   € Ø—.‘.×)Ñ)Ð*¨!¨D¯I©I¨=¸Ð:Ð:r   Nc                ó   — t         ‚)a~  
        Return the value of the object as bytes.

        :param context: the context to evaluate the object into.
        :type context: `connection` or `cursor`

        The method is automatically invoked by `~psycopg.Cursor.execute()`,
        `~psycopg.Cursor.executemany()`, `~psycopg.Cursor.copy()` if a
        `!Composable` is passed instead of the query string.

        )ÚNotImplementedError©r   r   s     r   Úas_byteszComposable.as_bytes;   s
   € ô "Ð!r   c                óê   — |r|j                   nd}t        |«      }| j                  |«      }t        |t        «      r|j                  |«      S t        j                  |«      j                  |«      d   S )z®
        Return the value of the object as string.

        :param context: the context to evaluate the string into.
        :type context: `connection` or `cursor`

        Nr   )Ú
connectionr   r+   Ú
isinstanceÚbytesÚdecodeÚcodecsÚlookup)r   r   ÚconnÚencÚbs        r   r   zComposable.as_stringJ   sd   € ñ &-ˆw×!Ò!°$ˆÜ˜DÓ!ˆØ�M‰M˜'Ó"ˆÜ�aœÔØ—8‘8˜C“=Ð ô —=‘= Ó%×,Ñ,¨QÓ/°Ñ2Ð2r   c                óž   — t        |t        «      rt        | g«      |z   S t        |t        «      rt        | g«      t        |g«      z   S t        S r   )r.   ÚComposedr   ÚNotImplemented©r   Úothers     r   Ú__add__zComposable.__add__[   sG   € Ü�eœXÔ&Ü˜T˜FÓ# eÑ+Ð+Ü�eœZÔ(Ü˜T˜FÓ#¤h°¨wÓ&7Ñ7Ð7ä!Ð!r   c                ó    — t        | g|z  «      S r   )r7   )r   Úns     r   Ú__mul__zComposable.__mul__c   s   € Ü˜˜ ™
Ó#Ð#r   c                ód   — t        | «      t        |«      u xr | j                  |j                  k(  S r   )Útyper   r9   s     r   Ú__eq__zComposable.__eq__f   s'   € Ü�D‹zœT %›[Ð(ÒD¨T¯Y©Y¸%¿*¹*Ñ-DÐDr   c                ó&   — | j                  |«       S r   )rA   r9   s     r   Ú__ne__zComposable.__ne__i   s   € Ø—;‘;˜uÓ%Ð%Ð%r   )r   r   ©ÚreturnÚstrr   ©r   úAdaptContext | NonerE   r/   ©r   rH   rE   rF   ©r:   r   rE   r7   )r=   ÚintrE   r7   )r:   r   rE   Úbool)r%   Ú
__module__Ú__qualname__Ú__doc__r    r'   r   r+   r   r;   r>   rA   rC   © r   r   r   r   &   s?   „ ñóó;ð ó"ó ð"ô3ó""ó$óEô&r   r   c                  óR   ‡ — e Zd ZU dZded<   d	ˆ fd„Zd
dd„Zdd„Zdd„Zdd„Z	ˆ xZ
S )r7   a.  
    A `Composable` object made of a sequence of `!Composable`.

    The object is usually created using `!Composable` operators and methods
    (such as the `SQL.format()` method). `!Composed` objects can be passed
    directly to `~psycopg.Cursor.execute()`, `~psycopg.Cursor.executemany()`,
    `~psycopg.Cursor.copy()` in place of the query string.

    It is also possible to create a `!Composed` directly specifying a sequence
    of objects as arguments: if they are not `!Composable` they will be wrapped
    in a `Literal`.

    Example::

        >>> comp = sql.Composed(
        ...     [sql.SQL("INSERT INTO "), sql.Identifier("table")])
        >>> print(comp.as_string(conn))
        INSERT INTO "table"

    `!Composed` objects are iterable (so they can be used in `SQL.join` for
    instance).
    zlist[Composable]r   c                ó‚   •— |D �cg c]  }t        |t        «      r|n
t        |«      ‘Œ! }}t        ‰| �  |«       y c c}w r   )r.   r   r   Úsuperr    )r   Úseqr   r$   s      €r   r    zComposed.__init__‡   s<   ø€ ÙORÓSÉsÈ”j ¤jÔ1‰s´w¸s³|ÑCÈsˆÐSÜ‰Ñ˜Õùò Ts   †$<c                óL   ‡— dj                  ˆfd„| j                  D «       «      S )Nr   c              3  ó@   •K  — | ]  }|j                  ‰«      –— Œ y ­wr   )r+   )Ú.0r   r   s     €r   Ú	<genexpr>z$Composed.as_bytes.<locals>.<genexpr>Œ   s   øè ø€ ÐC¹°#˜Ÿ™ W×-¹ùs   ƒ)Újoinr   r*   s    `r   r+   zComposed.as_bytes‹   s   ø€ Ø�x‰xÓC¸¿ºÓCÓCÐCr   c                ó,   — t        | j                  «      S r   )Úiterr   r&   s    r   Ú__iter__zComposed.__iter__Ž   s   € Ü�D—I‘I‹Ðr   c                óÄ   — t        |t        «      r"t        | j                  |j                  z   «      S t        |t        «      rt        | j                  |gz   «      S t        S r   )r.   r7   r   r   r8   r9   s     r   r;   zComposed.__add__‘   sJ   € Ü�eœXÔ&Ü˜DŸI™I¨¯
©
Ñ2Ó3Ð3Ü�eœZÔ(Ü˜DŸI™I¨¨Ñ/Ó0Ð0ä!Ð!r   c                ó®   — t        |t        «      rt        |«      }nt        |t        «      st        d|›d�«      ‚|j	                  | j
                  «      S )a~  
        Return a new `!Composed` interposing the `!joiner` with the `!Composed` items.

        The `!joiner` must be a `SQL` or a string which will be interpreted as
        an `SQL`.

        Example::

            >>> fields = sql.Identifier('foo') + sql.Identifier('bar')  # a Composed
            >>> print(fields.join(', ').as_string(conn))
            "foo", "bar"

        z5Composed.join() argument must be strings or SQL, got ú instead)r.   rF   ÚSQLÚ	TypeErrorrY   r   )r   Újoiners     r   rY   zComposed.join™   sT   € ô �fœcÔ"Ü˜“[‰FÜ˜F¤CÔ(ÜðØ�z ð+óð ð
 �{‰{˜4Ÿ9™9Ó%Ð%r   )rT   zSequence[Any]r   rG   )rE   zIterator[Composable]rJ   )rb   zSQL | LiteralStringrE   r7   )r%   rM   rN   rO   Ú__annotations__r    r+   r\   r;   rY   Ú__classcell__©r$   s   @r   r7   r7   m   s*   ø… ñð. ÓõôDóó"÷&r   r7   c                  óv   ‡ — e Zd ZU dZded<    ej                  «       Zd	ˆ fd„Zd
dd„Z	d
dd„Z
dd„Zdd„Zˆ xZS )r`   añ  
    A `Composable` representing a snippet of SQL statement.

    `!SQL` exposes `join()` and `format()` methods useful to create a template
    where to merge variable parts of a query (for instance field or table
    names).

    The `!obj` string doesn't undergo any form of escaping, so it is not
    suitable to represent variable identifiers or values: you should only use
    it to pass constant strings representing templates or snippets of SQL
    statements; use other objects such as `Identifier` or `Literal` to
    represent variable parts.

    `!SQL` objects can be passed directly to `~psycopg.Cursor.execute()`,
    `~psycopg.Cursor.executemany()`, `~psycopg.Cursor.copy()` in place of the
    query string.

    Example::

        >>> query = sql.SQL("SELECT {0} FROM {1}").format(
        ...    sql.SQL(', ').join([sql.Identifier('foo'), sql.Identifier('bar')]),
        ...    sql.Identifier('table'))
        >>> print(query.as_string(conn))
        SELECT "foo", "bar" FROM "table"
    r   r   c                ób   •— t         ‰| �  |«       t        |t        «      st	        d|›d�«      ‚y )Nz SQL values must be strings, got r_   )rS   r    r.   rF   ra   )r   r   r$   s     €r   r    zSQL.__init__Ð   s4   ø€ Ü‰Ñ˜ÔÜ˜#œsÔ#ÜÐ>¸s¸gÀXÐNÓOÐOð $r   c                ó   — | j                   S r   r   r*   s     r   r   zSQL.as_stringÕ   s   € Ø�y‰yÐr   c                ón   — |r|j                   nd }t        |«      }| j                  j                  |«      S r   )r-   r   r   Úencode©r   r   r3   r4   s       r   r+   zSQL.as_bytesØ   s0   € Ù%,ˆw×!Ò!°$ˆÜ˜DÓ!ˆØ�y‰y×Ñ Ó$Ð$r   c                óä  — g }d}| j                   j                  | j                  «      D ]º  \  }}}}|rt        d«      ‚|rt        d«      ‚|r|j	                  t        |«      «       |€ŒA|j                  «       r-|rt        d«      ‚|j	                  |t        |«         «       d}Œ~|s'|€t        d«      ‚|j	                  ||   «       |dz  }Œ§|j	                  ||   «       Œ¼ t        |«      S )aý  
        Merge `Composable` objects into a template.

        :param args: parameters to replace to numbered (``{0}``, ``{1}``) or
            auto-numbered (``{}``) placeholders
        :param kwargs: parameters to replace to named (``{name}``) placeholders
        :return: the union of the `!SQL` string with placeholders replaced
        :rtype: `Composed`

        The method is similar to the Python `str.format()` method: the string
        template supports auto-numbered (``{}``), numbered (``{0}``,
        ``{1}``...), and named placeholders (``{name}``), with positional
        arguments replacing the numbered placeholders and keywords replacing
        the named ones. However placeholder modifiers (``{0!r}``, ``{0:<10}``)
        are not supported.

        If a `!Composable` objects is passed to the template it will be merged
        according to its `as_string()` method. If any other Python object is
        passed, it will be wrapped in a `Literal` object and so escaped
        according to SQL rules.

        Example::

            >>> print(sql.SQL("SELECT * FROM {} WHERE {} = %s")
            ...     .format(sql.Identifier('people'), sql.Identifier('id'))
            ...     .as_string(conn))
            SELECT * FROM "people" WHERE "id" = %s

            >>> print(sql.SQL("SELECT * FROM {tbl} WHERE name = {name}")
            ...     .format(tbl=sql.Identifier('people'), name="O'Rourke"))
            ...     .as_string(conn))
            SELECT * FROM "people" WHERE name = 'O''Rourke'

        r   z(no format specification supported by SQLz%no format conversion supported by SQLNz6cannot switch from automatic field numbering to manualz6cannot switch from manual field numbering to automaticr
   )	Ú
_formatterÚparser   Ú
ValueErrorÚappendr`   ÚisdigitrK   r7   )	r   ÚargsÚkwargsÚrvÚautonumÚpreÚnameÚspecÚconvs	            r   Úformatz
SQL.formatÝ   sù   € ðF  "ˆØˆð &*§_¡_×%:Ñ%:¸4¿9¹9Ö%EÑ!ˆC��t˜TÙÜ Ð!KÓLÐLÙÜ Ð!HÓIÐIÙØ—	‘	œ#˜c›(Ô#àˆ|Øà�|‰|Œ~ÙÜ$ØPóð ð —	‘	˜$œs 4›y™/Ô*Ø‘áØ�?Ü$ØPóð ð —	‘	˜$˜w™-Ô(Ø˜1‘‘ð —	‘	˜& ™,Õ'ð9 &Fô< ˜‹|Ðr   c                óì   — g }t        |«      }	 |j                  t        |«      «       |D ]$  }|j                  | «       |j                  |«       Œ& t	        |«      S # t        $ r Y t	        |«      S w xY w)a  
        Join a sequence of `Composable`.

        :param seq: the elements to join.
        :type seq: iterable of `!Composable`

        Use the `!SQL` object's string to separate the elements in `!seq`.
        Note that `Composed` objects are iterable too, so they can be used as
        argument for this method.

        Example::

            >>> snip = sql.SQL(', ').join(
            ...     sql.Identifier(n) for n in ['foo', 'bar', 'baz'])
            >>> print(snip.as_string(conn))
            "foo", "bar", "baz"
        )r[   rp   ÚnextÚStopIterationr7   )r   rT   rt   ÚitÚis        r   rY   zSQL.join%  su   € ð$ ˆÜ�#‹Yˆð	Ø�I‰I”d˜2“hÔó �Ø—	‘	˜$”Ø—	‘	˜!•ð ô ˜‹|Ðøô ò 	Øô ˜‹|Ðð	ús   �A Á	A3Á2A3)r   r   r   rI   rG   )rr   r   rs   r   rE   r7   )rT   zIterable[Composable]rE   r7   )r%   rM   rN   rO   rc   ÚstringÚ	Formatterrm   r    r   r+   rz   rY   rd   re   s   @r   r`   r`   ²   s<   ø… ñð4 ÓØ!�×!Ñ!Ó#€JõPô
ô%ó
F÷Pr   r`   c                  óJ   ‡ — e Zd ZU dZded<   dˆ fd„Zd	d„Zd
dd„Zdd„Zˆ xZ	S )Ú
Identifiera#  
    A `Composable` representing an SQL identifier or a dot-separated sequence.

    Identifiers usually represent names of database objects, such as tables or
    fields. PostgreSQL identifiers follow `different rules`__ than SQL string
    literals for escaping (e.g. they use double quotes instead of single).

    .. __: https://www.postgresql.org/docs/current/sql-syntax-lexical.html#         SQL-SYNTAX-IDENTIFIERS

    Example::

        >>> t1 = sql.Identifier("foo")
        >>> t2 = sql.Identifier("ba'r")
        >>> t3 = sql.Identifier('ba"z')
        >>> print(sql.SQL(', ').join([t1, t2, t3]).as_string(conn))
        "foo", "ba'r", "ba""z"

    Multiple strings can be passed to the object to represent a qualified name,
    i.e. a dot-separated sequence of identifiers.

    Example::

        >>> query = sql.SQL("SELECT {} FROM {}").format(
        ...     sql.Identifier("table", "field"),
        ...     sql.Identifier("schema", "table"))
        >>> print(query.as_string(conn))
        SELECT "table"."field" FROM "schema"."table"

    zSequence[str]r   c                óŠ   •— t         ‰| �  |«       |st        d«      ‚|D ]!  }t        |t        «      rŒt        d|›d�«      ‚ y )NzIdentifier cannot be emptyz*SQL identifier parts must be strings, got r_   )rS   r    ra   r.   rF   )r   ÚstringsÚsr$   s      €r   r    zIdentifier.__init__g  sL   ø€ ä‰Ñ˜Ô!áÜÐ8Ó9Ð9ãˆAÜ˜a¤Õ%ÜØ@ÀÀÀXÐNóð ñ r   c                óˆ   — | j                   j                  › ddj                  t        t        | j
                  «      «      › d�S )Nr"   ú, r#   )r$   r%   rY   ÚmapÚreprr   r&   s    r   r'   zIdentifier.__repr__t  s5   € Ø—.‘.×)Ñ)Ð*¨!¨D¯I©I´c¼$ÀÇ	Á	Ó6JÓ,KÐ+LÈAÐNÐNr   c                óx  — |r|j                   nd }|rXt        |j                  «      }t        |«      }| j                  D �cg c]"  }|j                  |j                  |«      «      ‘Œ$ }}n6| j                  D �cg c]!  }| j                  |j                  «       «      ‘Œ# }}dj                  |«      S c c}w c c}w )Nó   .)	r-   r   Úpgconnr   r   Úescape_identifierrj   Ú_escape_identifierrY   )r   r   r3   Úescr4   r†   Úescss          r   r+   zIdentifier.as_bytesw  s—   € Ù%,ˆw×!Ò!°$ˆÙÜ˜4Ÿ;™;Ó'ˆCÜ Ó%ˆCØBFÇ)Â)ÓLÁ)¸Q�C×)Ñ)¨!¯(©(°3«-Õ8À)ˆDÑLàAEÇÂÓKÁ¸A�D×+Ñ+¨A¯H©H«JÕ7ÀˆDÐKØ�y‰y˜‹Ðùò MùâKs   Á'B2Á9&B7c                ó2   — d|j                  dd«      z   dz   S )zK
        Approximation of PQescapeIdentifier taking no connection.
        ó   "s   "")Úreplace)r   r†   s     r   r�   zIdentifier._escape_identifier�  s   € ð �a—i‘i  eÓ,Ñ,¨tÑ3Ð3r   )r…   rF   rD   r   rG   )r†   r/   rE   r/   )
r%   rM   rN   rO   rc   r    r'   r+   r�   rd   re   s   @r   rƒ   rƒ   E  s%   ø… ñð> ÓõóOô÷4r   rƒ   c                  ó   — e Zd ZdZddd„Zy)r   a™  
    A `Composable` representing an SQL value to include in a query.

    Usually you will want to include placeholders in the query and pass values
    as `~cursor.execute()` arguments. If however you really really need to
    include a literal value in the query you can use this object.

    The string returned by `!as_string()` follows the normal :ref:`adaptation
    rules <types-adaptation>` for Python objects.

    Example::

        >>> s1 = sql.Literal("fo'o")
        >>> s2 = sql.Literal(42)
        >>> s3 = sql.Literal(date(2000, 1, 1))
        >>> print(sql.SQL(', ').join([s1, s2, s3]).as_string(conn))
        'fo''o', 42, '2000-01-01'::date

    Nc                ób   — t        j                  |«      }|j                  | j                  «      S r   )r   Úfrom_contextÚ
as_literalr   )r   r   Útxs      r   r+   zLiteral.as_bytes�  s%   € Ü×%Ñ% gÓ.ˆØ�}‰}˜TŸY™YÓ'Ð'r   r   rG   )r%   rM   rN   rO   r+   rP   r   r   r   r   ˆ  s   „ ñõ((r   r   c                  óZ   ‡ — e Zd ZdZdej
                  fdˆ fd„Zdd„Zd	d
d„Zd	dd„Z	ˆ xZ
S )ÚPlaceholdera	  A `Composable` representing a placeholder for query parameters.

    If the name is specified, generate a named placeholder (e.g. ``%(name)s``,
    ``%(name)b``), otherwise generate a positional placeholder (e.g. ``%s``,
    ``%b``).

    The object is useful to generate SQL queries with a variable number of
    arguments.

    Examples::

        >>> names = ['foo', 'bar', 'baz']

        >>> q1 = sql.SQL("INSERT INTO my_table ({}) VALUES ({})").format(
        ...     sql.SQL(', ').join(map(sql.Identifier, names)),
        ...     sql.SQL(', ').join(sql.Placeholder() * len(names)))
        >>> print(q1.as_string(conn))
        INSERT INTO my_table ("foo", "bar", "baz") VALUES (%s, %s, %s)

        >>> q2 = sql.SQL("INSERT INTO my_table ({}) VALUES ({})").format(
        ...     sql.SQL(', ').join(map(sql.Identifier, names)),
        ...     sql.SQL(', ').join(map(sql.Placeholder, names)))
        >>> print(q2.as_string(conn))
        INSERT INTO my_table ("foo", "bar", "baz") VALUES (%(foo)s, %(bar)s, %(baz)s)

    Ú c                ó,  •— t         ‰| �  |«       t        |t        «      st	        d|›�«      ‚d|v rt        d|›�«      ‚t        |«      t        u rt        |«      }t        |t        «      s!t	        dt        |«      j                  ›�«      ‚|| _	        y )Nzexpected string as name, got r#   zinvalid name: z!expected PyFormat as format, got )
rS   r    r.   rF   ra   ro   r@   r   r%   Ú_format)r   rw   rz   r$   s      €r   r    zPlaceholder.__init__¾  s‘   ø€ Ü‰Ñ˜ÔÜ˜$¤Ô$ÜÐ;¸D¸8ÐDÓEÐEà�$‰;Ü˜~¨d¨XÐ6Ó7Ð7ä�‹<œ3ÑÜ˜fÓ%ˆFÜ˜&¤(Ô+ÜØ3´D¸³L×4IÑ4IÐ3LÐMóð ð "(ˆ�r   c                óD  — g }| j                   r$|j                  t        | j                   «      «       | j                  t        j
                  ur(|j                  d| j                  j                  › �«       | j                  j                  › ddj                  |«      › d�S )Nzformat=r"   rˆ   r#   )
r   rp   rŠ   rž   r   ÚAUTOrw   r$   r%   rY   )r   Úpartss     r   r'   zPlaceholder.__repr__Ï  sx   € ØˆØ�9Š9Ø�L‰Lœ˜dŸi™i›Ô)Ø�<‰<œxŸ}™}Ñ,Ø�L‰L˜7 4§<¡<×#4Ñ#4Ð"5Ð6Ô7à—.‘.×)Ñ)Ð*¨!¨D¯I©I°eÓ,<Ð+=¸QÐ?Ð?r   c                ót   — | j                   j                  }| j                  rd| j                  › d|› �S d|› �S )Nz%(r#   Ú%)rž   Úvaluer   )r   r   Úcodes      r   r   zPlaceholder.as_stringØ  s9   € Ø�|‰|×!Ñ!ˆØ*.¯)ª)��D—I‘I�;˜a ˜vÐ&ÐC¸1¸T¸F¸ÐCr   c                óx   — |r|j                   nd }t        |«      }| j                  |«      j                  |«      S r   )r-   r   r   rj   rk   s       r   r+   zPlaceholder.as_bytesÜ  s5   € Ù%,ˆw×!Ò!°$ˆÜ˜DÓ!ˆØ�~‰~˜gÓ&×-Ñ-¨cÓ2Ð2r   )rw   rF   rz   zstr | PyFormatrD   r   rI   rG   )r%   rM   rN   rO   r   r    r    r'   r   r+   rd   re   s   @r   r›   r›   ¢  s.   ø„ ñð6 $&ÀÇÁö (ó"@ôD÷3ð 3r   r›   ÚNULLÚDEFAULTr   )r   r   r   rH   rE   rF   )!rO   Ú
__future__r   r1   r€   Úabcr   r   Útypingr   r   r   r	   Úpqr   r   Ú_enumsr   Ú_compatr   Ú
_encodingsr   Ú_transformerr   r   r   r7   r`   rƒ   r   r›   r§   r¨   rP   r   r   Ú<module>r±      sž   ðñõ #ã Û ß #ß 4Ó 4å Ý Ý Ý "Ý %Ý %ô+ô D&�ô D&ôNB&ˆzô B&ôJPˆ*ô Pôf@4�ô @4ôF(ˆjô (ô4=3�*ô =3ñB ˆ6ƒ{€Ù
ˆi‹.�r   