Ë
    S²jåX  ã            $       óŒ  — d Z ddlZddlmZ ddlmZmZ ddlZ ej                  e	«      Z
g d¢Zdee   dz  dee   fd„Z ed	¬
«      dedefd„«       Z G d„ de«      Zej$                  j'                  di ¬«      	 	 	 	 	 	 	 d:dej(                  dej(                  dej(                  dej(                  dej(                  dz  dededededz  dee   dz  dedej(                  dz  dej(                  dz  dedz  deej(                  ej(                  ej(                  f   fd„«       Zej0                  	 	 	 	 	 	 	 d:dej(                  dej(                  dej(                  dej(                  dej(                  dz  dededededz  dee   dz  dedej(                  dz  dej(                  dz  dedz  deej(                  ej(                  ej(                  f   fd „«       Zddd!ddddd"œdej(                  dej(                  dej(                  dej(                  dej(                  dz  deded#edz  dedz  deeef   dedej(                  dz  dej(                  dz  dedz  dej(                  eej(                  ej(                  f   z  fd$„Zej$                  j'                  d%d&h¬«      	 	 	 	 	 	 	 d:d&ej(                  dej(                  dej(                  dej(                  dej(                  dej(                  dz  dededededz  dee   dz  dedej(                  dz  dej(                  dz  dedz  dej(                  f d'„«       Zej0                  	 	 	 	 	 	 	 d:d&ej(                  dej(                  dej(                  dej(                  dej(                  dej(                  dz  dededededz  dee   dz  dedej(                  dz  dej(                  dz  dedz  dej(                  f d(„«       Zddd!ddddd"œd&ej(                  dej(                  dej(                  dej(                  dej(                  dej(                  dz  deded#edz  dedz  deeef   dedej(                  dz  dej(                  dz  dedz  dej(                  eej(                  ej(                  f   z  f d)„Zd*ed+eed,f   d-eddfd.„Zej$                  j'                  d/i ¬«      	 	 d;d0ej(                  dej(                  dej(                  dej(                  d&ej(                  d1ej(                  dej(                  dej(                  dededed2ej(                  dedz  dee   dz  deej(                  ej(                  ej(                  f   fd3„«       Zej0                  	 	 d;d0ej(                  dej(                  dej(                  dej(                  d&ej(                  d1ej(                  dej(                  dej(                  dededed2ej(                  dedz  dee   dz  deej(                  ej(                  ej(                  f   fd4„«       Z d*ed0ej(                  d5ej(                  d6ej(                  deej(                  dz  d,f   f
d7„Z!ejE                  e!e¬8«       ejF                  jI                  ejJ                  jL                  jN                  «       dd9l(m)Z)m*Z*m+Z+m,Z, e*e,ejJ                  jZ                  j.                  <   e+e,ejJ                  jZ                  j6                  <   e)e,ejJ                  jZ                  j>                  <   y)<zÊ
Variable-length attention implementation using Flash Attention.

This module provides a high-level Python interface for variable-length attention
that calls into the optimized Flash Attention kernels.
é    N)Ú	lru_cache)ÚAnyÚ
NamedTuple)Úvarlen_attnÚvarlen_attn_outÚ
AuxRequestÚwindow_sizeÚreturnc                 ó\   — | €ddg} t        | «      dk7  rt        dt        | «      › �«      ‚| S )Néÿÿÿÿé   z$window_size must have length 2, got )ÚlenÚ
ValueError)r	   s    úX/var/www/html/ia-enhanced/venv/lib/python3.12/site-packages/torch/nn/attention/varlen.pyÚ_normalize_window_sizer      s=   € ØÐØ˜2�hˆä
ˆ;Ó˜1ÒÜÐ?ÄÀKÓ@PÐ?QÐRÓSÐSØÐó    é   )ÚmaxsizeÚdevice_indexc                  ó   — y)z;Cache device capability check to avoid repeated CUDA calls.F© )r   s    r   Ú_should_use_cudnnr      s   € ð r   c                   ó    — e Zd ZU dZdZeed<   y)r   z 
    Request which auxiliary outputs to compute from varlen_attn.

    Each field is a boolean indicating whether that auxiliary output should be computed.
    FÚlseN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   ÚboolÚ__annotations__r   r   r   r   r   #   s   … ñð €CˆÔr   r   ztorch_attn::_varlen_attn)Úmutates_argsFÚqueryÚkeyÚvalueÚcu_seq_qÚcu_seq_kÚmax_qÚmax_kÚ	is_causalÚscaleÚ
enable_gqaÚ	seqused_kÚblock_tableÚ
num_splitsc                 óÒ  — t        |	«      }	| j                  xr t        | j                  j                  «      }|rŸt
        j                  d«       |
rt        d«      ‚|�t        d«      ‚|	d   dk7  s|	d   dk7  rt        d«      ‚|€|�t        d	«      ‚t        j                  j                  j                  | ||d||||d
d|d|¬«      }|d   |d   |d   }}}nZt
        j                  d«       t        j                  j                  j                  | ||||||d|d||	d   |	d   |||¬«      \  }}}}}t        j                  dt        j                  | j                  ¬«      }|||fS )zž
    Private custom op for variable-length attention.

    This is the internal implementation. Users should use the public varlen_attn function instead.
    ú#Using cuDNN backend for varlen_attnz,GQA is not supported with the cuDNN backend.Nz3num_splits is not supported with the cuDNN backend.r   r   é   úTcuDNN backend does not support window attention. Please use Flash Attention backend.zBseqused_k/block_table is not yet supported with the cuDNN backend.Tç        F©r*   é   ú-Using Flash Attention backend for varlen_attn)Úreturn_debug_maskr*   Úwindow_size_leftÚwindow_size_rightr,   r-   r.   ©r   ©ÚdtypeÚdevice)r   Úis_cudar   r=   ÚindexÚlogÚinfoÚRuntimeErrorÚtorchÚopsÚatenÚ_cudnn_attention_forwardÚ_flash_attention_forwardÚzerosÚuint64)r"   r#   r$   r%   r&   r'   r(   r)   r*   r	   r+   r,   r-   r.   Ú	use_cudnnÚresultÚoutputÚsoftmax_lseÚ	rng_stateÚ_Ú
rng_state_s                        r   Ú_varlen_attnrQ   -   s   € ô, )¨Ó5€Kà—‘ÒGÔ"3°E·L±L×4FÑ4FÓ"G€IáÜ�‰Ð6Ô7áäÐMÓNÐNØÐ!äÐTÓUÐUØ�q‰>˜RÒ ;¨q¡>°RÒ#7ÜØfóð ð Ð  KÐ$;ô ØTóð ô —‘—‘×8Ñ8ØØØØØØØØØØØØØð 9ó 
ˆð  *0°©°F¸1±I¸vÀa¹y˜Y�‰ä�‰Ð@ÔAÜ/4¯y©y¯~©~×/VÑ/VØØØØØØØØØØ#ØØ(¨™^Ø)¨!™nØØ#Ø!ð! 0Wó 0
Ñ,ˆ�˜Y¨¨1ô& —‘Ø”E—L‘L¨¯©ô€Jð �; 
Ð*Ð*r   c                 ó   — t        |	«      }	t        j                  | «      }| j                  d«      }| j                  d«      }t        j                  ||ft        j
                  | j                  ¬«      }t        j                  j                  rŒt        j                  j                  «       }|t        j                  j                  j                  k(  rG|j                  d«      dz
  }t        j                  |||ft        j
                  | j                  ¬«      }t        j                  dt        j                  | j                  ¬«      }|||fS )zç
    Fake implementation for meta tensor computation and tracing.

    Based on the 3D varlen path from meta__flash_attention_forward:
    - query shape: (total, num_heads, head_dim)
    - logsumexp shape: (num_heads, total_q)
    r   r1   r;   r:   )r   rC   Ú
empty_likeÚsizeÚemptyÚfloatr=   ÚversionÚhipÚ_CÚ_get_rocm_fa_preferred_backendÚ_ROCmFABackendÚAOTritonrI   )r"   r#   r$   r%   r&   r'   r(   r)   r*   r	   r+   r,   r-   r.   rL   Útotal_qÚ	num_headsÚ	logsumexpÚ	preferredÚ
batch_sizerN   s                        r   Ú_varlen_attn_fakerb   ‡   s÷   € ô0 )¨Ó5€Kô ×Ñ˜eÓ$€Fð �j‰j˜‹m€GØ—
‘
˜1“€IÜ—‘Ø	�GÐ¤E§K¡K¸¿¹ô€Iô ‡}�}×ÒÜ—H‘H×;Ñ;Ó=ˆ	ØœŸ™×/Ñ/×8Ñ8Ò8à!Ÿ™ qÓ)¨AÑ-ˆJÜŸ™Ø˜Y¨Ð.´e·k±kÈ%Ï,É,ôˆIô —‘˜D¬¯©¸U¿\¹\ÔJ€Ià�9˜iÐ'Ð'r   )r   r   )Ú
return_auxr*   r	   r+   r,   r-   r.   rc   c                óŽ  — | j                  d«      }|�|j                  d«      n|j                  d«      }|
s||k7  rt        d|› d|› d�«      ‚|
r||z  dk7  rt        d|› d|› d�«      ‚|	d	k(  }t        j                  j                  j                  | ||||||||t        |	«      |
|||«      \  }}}|�|j                  r||fS |S )
a‘  Compute variable-length attention using Flash Attention.

    This function is similar to scaled_dot_product_attention but optimized for
    variable-length sequences using cumulative sequence position tensors.

    Args:
        query (Tensor): Query tensor; shape :math:`(T_q, H_q, D)`
        key (Tensor): Key tensor; shape :math:`(T_k, H_{kv}, D)`, or
            :math:`(\text{total\_pages}, \text{page\_size}, H_{kv}, D)` when ``block_table`` is provided.
        value (Tensor): Value tensor; shape :math:`(T_k, H_{kv}, D)`, or
            :math:`(\text{total\_pages}, \text{page\_size}, H_{kv}, D)` when ``block_table`` is provided.
        cu_seq_q (Tensor): Cumulative sequence positions for queries; shape :math:`(N+1,)`
        cu_seq_k (Tensor): Cumulative sequence positions for keys/values; shape :math:`(N+1,)`
        max_q (int): Maximum query sequence length in the batch.
        max_k (int): Maximum key/value sequence length in the batch.
        return_aux (Optional[AuxRequest]): If not None and ``return_aux.lse`` is True, also returns the logsumexp tensor.
        scale (float, optional): Scaling factor for attention scores
        window_size (tuple[int, int], optional): Window size for sliding window attention as (left, right).
            Use (-1, -1) for full attention (default), (-1, 0) for causal attention,
            or (W, 0) for causal attention with sliding window of size W.
        enable_gqa (bool): If set to True, enables Grouped Query Attention (GQA)
            and allows key/value to have fewer heads than query.
            Each KV head is shared by a group of :math:`H_q / H_{kv}` query heads,
            so :math:`H_q` must be divisible by :math:`H_{kv}`.
            Default is False.
        seqused_k (Tensor, optional): Number of valid KV tokens per batch element; shape :math:`(N,)`.
            When set, only the first ``seqused_k[i]`` tokens in the key/value sequence for batch
            element *i* participate in attention. Useful for KV-cache decoding where the cache slot
            is larger than the actual sequence. Inference-only (not supported in backward).
        block_table (Tensor, optional): Block table for paged KV cache; shape
            :math:`(N, \text{max\_pages\_per\_seq})`, dtype ``int32``.
            Requires ``seqused_k``. Inference-only (not supported in backward).

            When ``block_table`` is provided, ``key`` and ``value`` are a "pool" of
            pages of tokens of KV data and the pages belong to any sequence/order.
            The ``block_table`` is what maps each sequence's logical chunks
            back to physical pages in this pool.

            ``seqused_k[i]`` tells the kernel how many tokens in sequence *i* are
            actually valid, since the last page is typically only partially filled.
        num_splits (int, optional): Number of splits for split-KV. Set to ``1``
            to disable split-KV which enables batch invariance. Split-KV
            parallelizes the key/value sequence dimension across multiple thread
            blocks and combines partial results. The split decision depends
            on ``max_k`` (the longest sequence in the batch), so different batch
            compositions can change the reduction order and produce different
            floating-point results for the same sequence. When this is disabled,
            bitwise identical outputs are guaranteed for a given sequence
            regardless of what other sequences are in the batch, at the
            cost of lower GPU utilization when there are few queries. When
            ``None`` (default), the kernel chooses automatically.

    Returns:
        output (Tensor): Output tensor from attention computation; shape :math:`(T_q, H_q, D)`.

        If ``return_aux`` is not None and ``return_aux.lse`` is True:
            lse (Tensor): Log-sum-exp of attention scores; shape :math:`(T_q, H_q)`.

    Shape legend:
        - :math:`N`: Batch size
        - :math:`T_q`: Total number of query tokens in the batch (sum of all query sequence lengths)
        - :math:`T_k`: Total number of key/value tokens in the batch (sum of all key/value sequence lengths)
        - :math:`H_q`: Number of query attention heads
        - :math:`H_{kv}`: Number of key/value attention heads (equal to :math:`H_q` unless GQA is enabled)
        - :math:`D`: Head dimension

    Example::

        >>> # xdoctest: +REQUIRES(env:TORCH_DOCTEST_CUDA)
        >>> batch_size, max_seq_len, embed_dim, num_heads = 2, 512, 1024, 16
        >>> head_dim = embed_dim // num_heads
        >>> seq_lengths = []
        >>> for _ in range(batch_size):
        ...     length = torch.randint(1, max_seq_len // 64 + 1, (1,)).item() * 64
        ...     seq_lengths.append(min(length, max_seq_len))
        >>> seq_lengths = torch.tensor(seq_lengths, device="cuda")
        >>> total_tokens = seq_lengths.sum().item()
        >>>
        >>> # Create packed query, key, value tensors
        >>> query = torch.randn(
        ...     total_tokens, num_heads, head_dim, dtype=torch.float16, device="cuda"
        ... )
        >>> key = torch.randn(
        ...     total_tokens, num_heads, head_dim, dtype=torch.float16, device="cuda"
        ... )
        >>> value = torch.randn(
        ...     total_tokens, num_heads, head_dim, dtype=torch.float16, device="cuda"
        ... )
        >>>
        >>> # Build cumulative sequence tensor
        >>> cu_seq = torch.zeros(batch_size + 1, device="cuda", dtype=torch.int32)
        >>> cu_seq[1:] = seq_lengths.cumsum(0)
        >>> max_len = seq_lengths.max().item()
        >>>
        >>> # Call varlen_attn
        >>> output = varlen_attn(
        ...     query, key, value, cu_seq, cu_seq, max_len, max_len
        ... )
    r1   r   úGExpect query and key/value to have the same number of heads but got Hq=ú	 and Hkv=ú&. Try setting enable_gqa=True for GQA.r   úMExpect number of query heads to be a multiple of kv heads for GQA but got Hq=ú.©r   r   )rT   r   rC   rD   Ú
torch_attnrQ   Úlistr   )r"   r#   r$   r%   r&   r'   r(   rc   r*   r	   r+   r,   r-   r.   Únum_heads_qÚnum_heads_kr)   Úoutr   rO   s                       r   r   r   ¹   s  € ðj —*‘*˜Q“-€KØ!,Ð!8�#—(‘(˜1”+¸c¿h¹hÀq»k€KÙ˜+¨Ò4ÜðØ%˜ i°¨}ð =3ð4ó
ð 	
ñ
 �k KÑ/°1Ò4ÜðØ%˜ i°¨}¸Að?ó
ð 	
ð
 ˜wÑ&€IÜ—)‘)×&Ñ&×3Ñ3ØØØØØØØØØÜˆ[ÓØØØØó�K€Cˆˆað  Ð *§.¢.Ø�CˆxˆØ€Jr   ztorch_attn::_varlen_attn_outro   c                 ó:  — t        |
«      }
|j                  xr t        |j                  j                  «      }|rt        d«      ‚t        j                  d«       t        j                  j                  j                  | |||||||d|d|	|
d   |
d   |||¬«      }|S )z«
    Private custom op for variable-length attention with pre-allocated output.
    Same as _varlen_attn but writes the attention output into the provided out tensor.
    z+cuDNN backend does not support out variant.z1Using Flash Attention backend for varlen_attn_outr3   Fr   r1   )r*   r8   r9   r,   r-   r.   )r   r>   r   r=   r?   rB   r@   rA   rC   rD   rE   Ú+_flash_attention_forward_no_dropout_inplace)ro   r"   r#   r$   r%   r&   r'   r(   r)   r*   r	   r+   r,   r-   r.   rJ   rM   s                    r   Ú_varlen_attn_outrr   R  s©   € ô, )¨Ó5€Kà—‘ÒGÔ"3°E·L±L×4FÑ4FÓ"G€IáäÐHÓIÐIä‡H�HÐ@ÔAÜ—)‘)—.‘.×LÑLØØØØØØØØØØØØØ$ Q™Ø% a™.ØØØð# Mó €Kð( Ðr   c                 óú  — |j                  d«      }|j                  d«      }t        j                  ||ft        j                  |j                  ¬«      }t        j
                  j                  rŒt        j                  j                  «       }|t        j                  j                  j                  k(  rG|j                  d«      dz
  }t        j                  |||ft        j                  |j                  ¬«      }|S )úF
    Fake implementation for meta tensor computation and tracing.
    r   r1   r;   )rT   rC   rU   rV   r=   rW   rX   rY   rZ   r[   r\   )ro   r"   r#   r$   r%   r&   r'   r(   r)   r*   r	   r+   r,   r-   r.   r]   r^   r_   r`   ra   s                       r   Ú_varlen_attn_out_fakeru   ˆ  s¸   € ð* �j‰j˜‹m€GØ—
‘
˜1“€IÜ—‘Ø	�GÐ¤E§K¡K¸¿¹ô€Iô ‡}�}×ÒÜ—H‘H×;Ñ;Ó=ˆ	ØœŸ™×/Ñ/×8Ñ8Ò8Ø!Ÿ™ qÓ)¨AÑ-ˆJÜŸ™Ø˜Y¨Ð.´e·k±kÈ%Ï,É,ôˆIð Ðr   c                óˆ  — |j                  d«      }|�|j                  d«      n|j                  d«      }|s||k7  rt        d|› d|› d�«      ‚|r||z  dk7  rt        d|› d|› d�«      ‚|
d	k(  }t        j                  j                  j                  | |||||||||	t        |
«      ||||«      }|�|j                  r| |fS | S )
zèCompute variable-length attention using Flash Attention with a pre-allocated output tensor.

    Same as :func:`varlen_attn` but writes the attention output into the provided ``out`` tensor
    instead of allocating a new one.

    r1   r   re   rf   rg   r   rh   ri   rj   )rT   r   rC   rD   rk   rr   rl   r   )ro   r"   r#   r$   r%   r&   r'   r(   rc   r*   r	   r+   r,   r-   r.   rm   rn   r)   r   s                      r   r   r   ®  s  € ð0 —*‘*˜Q“-€KØ!,Ð!8�#—(‘(˜1”+¸c¿h¹hÀq»k€KÙ˜+¨Ò4ÜðØ%˜ i°¨}ð =3ð4ó
ð 	
ñ
 �k KÑ/°1Ò4ÜðØ%˜ i°¨}¸Að?ó
ð 	
ð
 ˜wÑ&€IÜ
�)‰)×
Ñ
×
/Ñ
/ØØØØØØØØØØÜˆ[ÓØØØØó€Cð" Ð *§.¢.Ø�CˆxˆØ€Jr   ÚctxÚinputs.rL   c                 óÜ   — |\  }}}}}}}	}
}}}}}}|\  }}}|�t        d«      ‚|�t        d«      ‚| j                  ||||||||«       || _        |	| _        |
| _        || _        || _        y )Nz)seqused_k is an inference-only parameter.z+block_table is an inference-only parameter.)rB   Úsave_for_backwardr'   r(   r)   r*   r	   )rw   rx   rL   r"   r#   r$   r%   r&   r'   r(   r)   r*   r	   r+   r,   r-   r.   ro   r   rN   s                       r   Ú_setup_contextr{   ë  s¥   € ð  	ñØØØØØØØØØØØØØØà Ñ€CˆˆiàÐÜÐFÓGÐGØÐÜÐHÓIÐIà×Ñ˜%  e¨X°xÀÀcÈ9ÔUà€C„IØ€C„IØ€C„MØ€C„IØ!€C…Or   z!torch_attn::_varlen_attn_backwardÚgrad_outr   rN   c                 óN  — t        |«      }t        j                  d|j                  ¬«      }|j                  xr t        |j                  j                  «      }|rmt        j                  d«       |d   dk7  s|d   dk7  rt        d«      ‚t        j                  j                  j                  | |||||||||	d|
|||¬«      \  }}}nYt        j                  d	«       t        j                  j                  j                  | |||||||||	d|
||||d   |d   ¬
«      \  }}}|||fS )Nr   )r=   r0   r   r1   r2   r3   r4   r6   )r*   r8   r9   )r   rC   rU   r=   r>   r   r?   r@   rA   rB   rD   rE   Ú_cudnn_attention_backwardÚ_flash_attention_backward)r|   r"   r#   r$   ro   r   r%   r&   r'   r(   r)   rN   r*   r	   ÚunusedrJ   ÚdqÚdkÚdvs                      r   Ú_varlen_attn_backwardr„     sD  € ô" )¨Ó5€Kä�[‰[˜ 5§<¡<Ô0€Fà—‘ÒGÔ"3°E·L±L×4FÑ4FÓ"G€IÙÜ�‰Ð6Ô7Ø�q‰>˜RÒ ;¨q¡>°RÒ#7ÜØfóð ô —Y‘Y—^‘^×=Ñ=ØØØØØØØØØØØØØØØð >ó 
‰
ˆˆB‘ô$ 	�‰Ð@ÔAÜ—Y‘Y—^‘^×=Ñ=ØØØØØØØØØØØØØØØØ(¨™^Ø)¨!™nð# >ó 
‰
ˆˆB�ð& ˆr�2ˆ:Ðr   c                 ó    — t        |«      }t        j                  |«      }t        j                  |«      }t        j                  |«      }|||fS )rt   )r   rC   rS   )r|   r"   r#   r$   ro   r   r%   r&   r'   r(   r)   rN   r*   r	   Ú
grad_queryÚgrad_keyÚ
grad_values                    r   Ú_varlen_attn_backward_faker‰   Q  sK   € ô( )¨Ó5€Kä×!Ñ! %Ó(€JÜ×Ñ Ó$€HÜ×!Ñ! %Ó(€Jà�x Ð+Ð+r   Úgrad_lseÚgrad_rngc                 ó2  — | j                   \  }}}}}}	}
}| j                  }| j                  }| j                  }| j                  }| j
                  }t        j                  j                  j                  |||||	|
||||||||«      \  }}}d}|||gd|z  ¢­S )Né   )N)
Úsaved_tensorsr'   r(   r)   r*   r	   rC   rD   rk   r„   )rw   r|   rŠ   r‹   r"   r#   r$   r%   r&   ro   r   rN   r'   r(   r)   r*   r	   r�   r‚   rƒ   Ú
num_paramss                        r   Ú	_backwardr�   n  s·   € ð BE×ARÑARÑ>€Eˆ3��x ¨3°°Yà�I‰I€EØ�I‰I€EØ—‘€IØ�I‰I€EØ—/‘/€Kä—‘×%Ñ%×;Ñ;ØØØØØØØØØØØØØØó�J€BˆˆBð$ €JØ��BÐ0˜' JÑ.Ñ0Ð0r   )Úsetup_context)Ú_varlen_attn_backward_flopÚ_varlen_attn_forward_flopÚ_varlen_attn_out_flopÚflop_registry)FNNFNNN)NN).r   ÚloggingÚ	functoolsr   Útypingr   r   rC   Ú	getLoggerr   r@   Ú__all__rl   Úintr   r   r   r   ÚlibraryÚ	custom_opÚTensorrV   ÚtuplerQ   Úregister_fakerb   r   rr   ru   r   r{   r„   r‰   r�   Úregister_autogradÚ_dynamoÚdisallow_in_graphrD   rE   rq   Útorch.utils.flop_counterr’   r“   r”   r•   rk   r   r   r   ú<module>r¥      sc
  ðñó Ý ß "ã ð €g×Ñ˜Ó!€â
:€ð¨¨S©	°DÑ(8ð ¸TÀ#¹Yó ñ �1Ôð Cð ¨Dò ó ðô
�ô ð ‡�×ÑÐ3À"ÐÓEð ØØ$(ØØ%)Ø'+Ø!ñV+Ø�<‰<ðV+à	�‰ðV+ð �<‰<ðV+ð �l‰lð	V+ð
 �l‰l˜TÑ!ðV+ð ðV+ð ðV+ð ðV+ð �4‰<ðV+ð �c‘˜TÑ!ðV+ð ðV+ð �|‰|˜dÑ"ðV+ð —‘ Ñ$ðV+ð �d‘
ðV+ð ˆ5�<‰<˜Ÿ™ u§|¡|Ð3Ñ4òV+ó FðV+ðr ×Ñð ØØ$(ØØ%)Ø'+Ø!ñ.(Ø�<‰<ð.(à	�‰ð.(ð �<‰<ð.(ð �l‰lð	.(ð
 �l‰l˜TÑ!ð.(ð ð.(ð ð.(ð ð.(ð �4‰<ð.(ð �c‘˜TÑ!ð.(ð ð.(ð �|‰|˜dÑ"ð.(ð —‘ Ñ$ð.(ð �d‘
ð.(ð ˆ5�<‰<˜Ÿ™ u§|¡|Ð3Ñ4ò.(ó ð.(ðt %)ØØ#+ØØ%)Ø'+Ø!òVØ�<‰<ðVà	�‰ðVð �<‰<ðVð �l‰lð	Vð
 �l‰l˜TÑ!ðVð ðVð ðVð ˜TÑ!ðVð �4‰<ðVð �s˜C�x‘ðVð ðVð �|‰|˜dÑ"ðVð —‘ Ñ$ðVð �d‘
ðVð  ‡\�\�E˜%Ÿ,™,¨¯©Ð4Ñ5Ñ5ó!Vðr ‡�×ÑÐ7ÀuÀgÐÓNð ØØ$(ØØ%)Ø'+Ø!ñ2Ø	�‰ð2à�<‰<ð2ð 
�‰ð2ð �<‰<ð	2ð
 �l‰lð2ð �l‰l˜TÑ!ð2ð ð2ð ð2ð ð2ð �4‰<ð2ð �c‘˜TÑ!ð2ð ð2ð �|‰|˜dÑ"ð2ð —‘ Ñ$ð2ð �d‘
ð2ð  ‡\�\ò!2ó Oð2ðj ×Ñð ØØ$(ØØ%)Ø'+Ø!ñ"Ø	�‰ð"à�<‰<ð"ð 
�‰ð"ð �<‰<ð	"ð
 �l‰lð"ð �l‰l˜TÑ!ð"ð ð"ð ð"ð ð"ð �4‰<ð"ð �c‘˜TÑ!ð"ð ð"ð �|‰|˜dÑ"ð"ð —‘ Ñ$ð"ð �d‘
ð"ð  ‡\�\ò!"ó  ð"ð^ %)ØØ#+ØØ%)Ø'+Ø!ò!:Ø	�‰ð:à�<‰<ð:ð 
�‰ð:ð �<‰<ð	:ð
 �l‰lð:ð �l‰l˜TÑ!ð:ð ð:ð ð:ð ˜TÑ!ð:ð �4‰<ð:ð �s˜C�x‘ð:ð ð:ð �|‰|˜dÑ"ð:ð —‘ Ñ$ð:ð  �d‘
ð!:ð" ‡\�\�E˜%Ÿ,™,¨¯©Ð4Ñ5Ñ5ó#:ðz"˜ð " U¨3°¨8¡_ð "¸cð "Àdó "ðB ‡�×ÑÐ<È2ÐÓNð Ø$(ñAØ�l‰lðAà�<‰<ðAð 
�‰ðAð �<‰<ð	Að
 
�‰ðAð 
�‰ðAð �l‰lðAð �l‰lðAð ðAð ðAð ðAð �|‰|ðAð �4‰<ðAð �c‘˜TÑ!ðAð ˆ5�<‰<˜Ÿ™ u§|¡|Ð3Ñ4òAó OðAðH ×$Ñ$ð Ø$(ñ,Ø�l‰lð,à�<‰<ð,ð 
�‰ð,ð �<‰<ð	,ð
 
�‰ð,ð 
�‰ð,ð �l‰lð,ð �l‰lð,ð ð,ð ð,ð ð,ð �|‰|ð,ð �4‰<ð,ð �c‘˜TÑ!ð,ð ˆ5�<‰<˜Ÿ™ u§|¡|Ð3Ñ4ò,ó %ð,ð81Ø	ð1ØŸ™ð1Ø05·±ð1ØHMÏÉð1à
ˆ5�<‰<˜$Ñ Ð#Ñ$ó1ðB × Ñ ˜y¸Ð Ô Gà ‡�× Ñ Ø	‡I�I‡N�N×>Ñ>ô÷ó ð 4M€ˆe�i‰i×"Ñ"×/Ñ/Ñ 0Ø7L€ˆe�i‰i×"Ñ"×3Ñ3Ñ 4Ø<V€ˆe�i‰i×"Ñ"×8Ñ8Ò 9r   