
    BVh/]                        d Z ddlZddl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	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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lmZ ddlmZ ej>                  Zej@                  Z  edd       G d dejB                  e
jD                               Z# ejH                  dg d      Z%  edg      e%        ed       ejL                  d       G d dejN                                      Z( ejR                   ejT                  e(ejV                  jX                                ejZ                  e#e(j\                          ejZ                  e%e(j\                          ed g      d'd!       Z/d" Z0ejb                  ejd                  ejf                  ejd                  ejh                  ejd                  ejj                  ejd                  ejl                  ejn                  ejp                  ejn                  ejr                  ejn                  ejt                  ejn                  ejv                  dejx                  dejd                  dejn                  dejz                  dej|                  diZ?d(d#Z@ ej                  ej                  d$e#        ej                  e@d%e#        ej                  ej                  d&e#       y))zSparse tensors.    N)
struct_pb2)pywrap_tensorflow)tf2)composite_tensor)constant_op)dtypes)ops)override_binary_operator)tensor)tensor_shape)tensor_spec)tensor_util)	type_spec)type_spec_registry)array_ops_stack)gen_math_ops)gen_sparse_ops)nested_structure_coder)internal)	tf_exportzsparse.SparseTensorSparseTensorc                   "   e Zd ZdZed        Zd Zdej                  fdZ	e
d        Ze
d        Zd Ze
dej                  fd	       Ze
d
        Ze
d        Ze
d        Zd Ze
d        Zd ZddZed        Ze
d        Zd Zd Zd Zd Zy)r   aE	  Represents a sparse tensor.

  TensorFlow represents a sparse tensor as three separate dense tensors:
  `indices`, `values`, and `dense_shape`.  In Python, the three tensors are
  collected into a `SparseTensor` class for ease of use.  If you have separate
  `indices`, `values`, and `dense_shape` tensors, wrap them in a `SparseTensor`
  object before passing to the ops below.

  Concretely, the sparse tensor `SparseTensor(indices, values, dense_shape)`
  comprises the following components, where `N` and `ndims` are the number
  of values and number of dimensions in the `SparseTensor`, respectively:

  * `indices`: A 2-D int64 tensor of shape `[N, ndims]`, which specifies the
    indices of the elements in the sparse tensor that contain nonzero values
    (elements are zero-indexed). For example, `indices=[[1,3], [2,4]]` specifies
    that the elements with indexes of [1,3] and [2,4] have nonzero values.

  * `values`: A 1-D tensor of any type and shape `[N]`, which supplies the
    values for each element in `indices`. For example, given `indices=[[1,3],
    [2,4]]`, the parameter `values=[18, 3.6]` specifies that element [1,3] of
    the sparse tensor has a value of 18, and element [2,4] of the tensor has a
    value of 3.6.

  * `dense_shape`: A 1-D int64 tensor of shape `[ndims]`, which specifies the
    dense_shape of the sparse tensor. Takes a list indicating the number of
    elements in each dimension. For example, `dense_shape=[3,6]` specifies a
    two-dimensional 3x6 tensor, `dense_shape=[2,3,4]` specifies a
    three-dimensional 2x3x4 tensor, and `dense_shape=[9]` specifies a
    one-dimensional tensor with 9 elements.

  The corresponding dense tensor satisfies:

  ```python
  dense.shape = dense_shape
  dense[tuple(indices[i])] = values[i]
  ```

  By convention, `indices` should be sorted in row-major order (or equivalently
  lexicographic order on the tuples `indices[i]`). This is not enforced when
  `SparseTensor` objects are constructed, but most ops assume correct ordering.
  If the ordering of sparse tensor `st` is wrong, a fixed version can be
  obtained by calling `tf.sparse.reorder(st)`.

  Example: The sparse tensor

  ```python
  SparseTensor(indices=[[0, 0], [1, 2]], values=[1, 2], dense_shape=[3, 4])
  ```

  represents the dense tensor

  ```python
  [[1, 0, 0, 0]
   [0, 0, 2, 0]
   [0, 0, 0, 0]]
  ```
  c                     t        |      st        d| d      t        |j                  |j                  |j
                        S )NzArgument sparse_tensor_value=z1 is neither a SparseTensor nor SparseTensorValue.indicesvaluesdense_shape)	is_sparse	TypeErrorr   r   r   r   )clssparse_tensor_values     Y/home/dcms/DCMS/lib/python3.12/site-packages/tensorflow/python/framework/sparse_tensor.py
from_valuezSparseTensor.from_valuel   sX    ()56I5J KI I J J#++"))'335 5    c                    t        j                  dd|||g      5  t        j                  |dt        j                        }t        j                  |d      }t        j                  |dt        j                        }t        j                  |      }ddd       || _        || _        || _	        | _
        |j                  j                  d      }|j                  j                  d	      }|j                  j                  d	      }|j                  d
   j                  |j                  d
          |j                  d	   j                  |j                  d
          y# 1 sw Y   xY w)af  Creates a `SparseTensor`.

    Args:
      indices: A 2-D int64 tensor of shape `[N, ndims]`.
      values: A 1-D tensor of any type and shape `[N]`.
      dense_shape: A 1-D int64 tensor of shape `[ndims]`.

    Raises:
      ValueError: When building an eager SparseTensor if `dense_shape` is
        unknown or contains unknown elements (None or -1).
    Nr   r   )namedtyper   r&   r         r   )r	   
name_scopeconvert_to_tensorr   int64r   constant_value_as_shape_indices_values_dense_shape_dense_shape_defaultshape	with_rankdimsassert_is_compatible_with)selfr   r   r   dense_shape_defaultindices_shapevalues_shapedense_shape_shapes           r"   __init__zSparseTensor.__init__v   s;    
nw.L	M 	M%%
	7g $$V(;f))
M?k'??L	M DMDL#D 3DMM++A.M<<))!,L#))33A6 q33L4E4Ea4HI q334E4J4J14MN1	M 	Ms   A9E  E)returnc                     | j                   S zrGet the `TensorShape` representing the shape of the dense tensor.

    Returns:
      A `TensorShape` object.
    r2   r7   s    r"   	get_shapezSparseTensor.get_shape   s     $$$r$   c                     | j                   S )zThe indices of non-zero values in the represented dense tensor.

    Returns:
      A 2-D Tensor of int64 with dense_shape `[N, ndims]`, where `N` is the
        number of non-zero values in the tensor, and `ndims` is the rank.
    )r/   rA   s    r"   r   zSparseTensor.indices   s     ==r$   c                     | j                   S )zlThe non-zero values in the represented dense tensor.

    Returns:
      A 1-D Tensor of any data type.
    )r0   rA   s    r"   r   zSparseTensor.values   s     <<r$   c                 D    t        | j                  || j                        S )a  Returns a copy of `self` with `values` replaced by `new_values`.

    This method produces a new `SparseTensor` that has the same nonzero
    `indices` and same `dense_shape`, but updated values.

    Args:
      new_values: The values of the new `SparseTensor`. Needs to have the same
        shape as the current `.values` `Tensor`. May have a different type than
        the current `values`.

    Returns:
      A `SparseTensor` with identical indices and shape but updated values.

    Example usage:

    >>> st = tf.sparse.from_dense([[1, 0, 2, 0], [3, 0, 0, 4]])
    >>> tf.sparse.to_dense(st.with_values([10, 20, 30, 40]))  # 4 nonzero values
    <tf.Tensor: shape=(2, 4), dtype=int32, numpy=
    array([[10,  0, 20,  0],
           [30,  0,  0, 40]], dtype=int32)>

    )r   r/   r1   )r7   
new_valuess     r"   with_valueszSparseTensor.with_values   s    . z43D3DEEr$   c                 .    | j                   j                  S )z4The `Operation` that produces `values` as an output.)r0   oprA   s    r"   rI   zSparseTensor.op   s     <<??r$   c                 .    | j                   j                  S )z'The `DType` of elements in this tensor.)r0   r'   rA   s    r"   r'   zSparseTensor.dtype   s     <<r$   c                     | j                   S )zAA 1-D Tensor of int64 representing the shape of the dense tensor.)r1   rA   s    r"   r   zSparseTensor.dense_shape   s     r$   c                     | j                   S r?   r@   rA   s    r"   r3   zSparseTensor.shape   s     $$$r$   c                     t        |t        j                        st        j                  |      }| j                  j	                  |      | _        y)a  Updates the `TensorShape` representing the shape of the dense tensor.

    With eager execution this operates as a shape assertion.
    Here the shapes match:

    >>> st = tf.SparseTensor(
    ...   indices=[[0, 0], [1, 2]], values=[1, 2], dense_shape=[3, 4])
    >>> st.set_shape([3, 4])

    Passing a `None` in the new shape allows any value for that axis:

    >>> st.set_shape([3, None])

    An error is raised if an incompatible shape is passed.

    >>> st.set_shape([1, 4])
    Traceback (most recent call last):
    ...
    ValueError: Tensor's shape (3, 4) is not compatible with supplied
    shape [1, 4]

    When executing in a `tf.function`, or building a model using
    `tf.keras.Input`, `SparseTensor.set_shape` will *merge* the given `shape`
    with the current shape of this tensor, and set the tensor's shape to the
    merged value (see `tf.TensorShape.merge_with` for details):

    >>> st = tf.keras.Input(shape=[None, None, 3], sparse=True)
    >>> print(st.shape)
    (None, None, None, 3)

    Dimensions set to `None` are not updated:

    >>> st.set_shape([None, 224, 224, None])
    >>> print(st.shape)
    (None, 224, 224, 3)

    The main use case for this is to provide additional shape information
    that cannot be inferred from the graph alone.

    Caution: `set_shape` ensures that the applied shape is compatible with
    the existing shape, but it does not check at runtime. Setting
    incorrect shapes can result in inconsistencies between the
    statically-known graph and the runtime value of tensors.

    Args:
      shape: A `TensorShape` representing the shape of this tensor, a
        `TensorShapeProto`, a list, a tuple, or None.

    Raises:
      ValueError: If `shape` is not compatible with the current shape of
        this tensor.
    N)
isinstancer   TensorShaper2   
merge_with)r7   r3   s     r"   	set_shapezSparseTensor.set_shape   s>    j e\556&&u-e $ 9 9 D DU KDr$   c                 .    | j                   j                  S )zDThe `Graph` that contains the index, value, and dense_shape tensors.)r/   graphrA   s    r"   rS   zSparseTensor.graph!  s     ==r$   c                 V    d| j                   d| j                  d| j                  dS )NzSparseTensor(indices=z	, values=z, dense_shape=))r/   r0   r1   rA   s    r"   __repr__zSparseTensor.__repr__&  s!    t||T%6%68 8r$   Nc                     t        | j                  | j                  | j                  g|| j                  |      \  }}}t        |||      S )a  Evaluates this sparse tensor in a `Session`.

    Calling this method will execute all preceding operations that
    produce the inputs needed for the operation that produces this
    tensor.

    *N.B.* Before invoking `SparseTensor.eval()`, its graph must have been
    launched in a session, and either a default session must be
    available, or `session` must be specified explicitly.

    Args:
      feed_dict: A dictionary that maps `Tensor` objects to feed values. See
        `tf.Session.run` for a description of the valid feed values.
      session: (Optional.) The `Session` to be used to evaluate this sparse
        tensor. If none, the default session will be used.

    Returns:
      A `SparseTensorValue` object.
    )_eval_using_default_sessionr   r   r   rS   SparseTensorValue)r7   	feed_dictsessionr   r   r   s         r"   evalzSparseTensor.eval*  sI    ( $?	t{{D$4$45y$**$ GV[ Wfk::r$   c                 &    t        t        | |       y N)_override_helperr   )operatorfuncs     r"   _override_operatorzSparseTensor._override_operatorC  s    \8T2r$   c                 B    t        | j                  | j                        S r^   )SparseTensorSpecr3   r'   rA   s    r"   
_type_speczSparseTensor._type_specG  s    DJJ

33r$   c                     |j                   +|j                   dk7  rt        d| d|j                    d      t        j                  |d         }t	        t        j
                  |      | j                        S )Nr*   z-Expected a shape with 1 dimension. Obtained: z which has z dimensions.r   )ndims
ValueErrorr   dimension_valuerd   unknown_shaper'   )r7   r3   ranks      r"   _shape_invariant_to_type_specz*SparseTensor._shape_invariant_to_type_specK  ss     {{5;;!#3Fug N$$)KK=> ? ?''a1DL66t<djjIIr$   c                 "    | j                         S r^   )
_consumersrA   s    r"   	consumerszSparseTensor.consumersX  s    ??r$   c                    | j                         st        d      t        j                  | j                  | j
                  j                               }t        | j                  | j                        D ]  \  }}||t        |      <    |S )zReturns a numpy `array` with the values for this `SparseTensor`.

    Requires that this `SparseTensor` was constructed in eager execution mode.
    z5SparseTensor.numpy() is only supported in eager mode.)r'   )	_is_eagerrh   npzerosr   r'   as_numpy_dtypezipr   r   tuple)r7   arrivs       r"   _numpyzSparseTensor._numpy[  ss    
 >>NOO
((4##4::+D+D+F
GCDLL$++. 1c%(m Jr$   c                 h    t        d | j                  | j                  | j                  fD              S )zReturns True if this `SparseTensor` was constructed in eager execution.

    Requires that each individual component of `SparseTensor`
    (`indices`, `values` and `dense_shape`) is an instance of `EagerTensor`.
    c              3   P   K   | ]  }t        |t        j                           y wr^   )rN   r	   EagerTensor.0ts     r"   	<genexpr>z)SparseTensor._is_eager.<locals>.<genexpr>o  s%      @ 	1coo&@   $&)allr   r   r   rA   s    r"   rq   zSparseTensor._is_eagerh  s7      @,,T-=-=>@ @ @r$   NN)__name__
__module____qualname____doc__classmethodr#   r<   r   rO   rB   propertyr   r   rG   r	   	OperationrI   r'   r   r3   rQ   rS   rV   r\   staticmethodrb   re   rl   ro   rz   rq    r$   r"   r   r   0   s!   8t 5 5$OL%11 %    F2 #--       % %7Lr  8;2 3 3 4 4J	@r$   rY   r   )v1rd   ztf.SparseTensorSpecc                       e Zd ZdZddgZ ed       Zdej                  fdZ	d Z
ed        Zed	        Zed
        Zd Zd Zed        Zd Zd Zd Zd Zd Zd Zd Zd Zed        Zy)rd   z2Type specification for a `tf.sparse.SparseTensor`._shape_dtypec                     t         S r^   r   rA   s    r"   <lambda>zSparseTensorSpec.<lambda>  s    \ r$   Nc                 l    t        j                  |      | _        t        j                  |      | _        y)zConstructs a type specification for a `tf.sparse.SparseTensor`.

    Args:
      shape: The dense shape of the `SparseTensor`, or `None` to allow any dense
        shape.
      dtype: `tf.DType` of values in the `SparseTensor`.
    N)r   as_shaper   r   as_dtyper   )r7   r3   r'   s      r"   r<   zSparseTensorSpec.__init__  s&     ''.DK//%(DKr$   c                 2    | j                   | j                  fS r^   )r   r   rA   s    r"   
_serializezSparseTensorSpec._serialize  s    KK%%r$   c                     | j                   S )zBThe `tf.dtypes.DType` specified by this type for the SparseTensor.r   rA   s    r"   r'   zSparseTensorSpec.dtype       ;;r$   c                     | j                   S )zAThe `tf.TensorShape` specified by this type for the SparseTensor.r   rA   s    r"   r3   zSparseTensorSpec.shape  r   r$   c                    | j                   j                  }d }t        j                  ||gt        j
                        t        j                  |g| j                        t        j                  |gt        j
                        gS r^   )r   rg   r   
TensorSpecr   r-   r   )r7   rk   
num_valuess      r"   _component_specsz!SparseTensorSpec._component_specs  se    ;;DJ
D16<<@
|T[[9vv||46 6r$   c                     t        |t              rt        j                  |      }|j                  |j
                  |j                  gS r^   )rN   rY   r   r#   r   r   r   r7   values     r"   _to_componentszSparseTensorSpec._to_components  s8    %*+%%e,eMM5<<):):;;r$   c                     t        d |D              rt        j                         st        | S t	        | }|j
                  j                  | j                        |_        |S )Nc              3   P   K   | ]  }t        |t        j                           y wr^   )rN   rr   ndarrayr~   s     r"   r   z4SparseTensorSpec._from_components.<locals>.<genexpr>  s     ;!Jq"**%;r   )r   r   enabledrY   r   r2   rP   r   )r7   tensor_listresults      r"   _from_componentsz!SparseTensorSpec._from_components  sS    ;{;;KKM,,[)f$*$?$?$J$J
++%f!mr$   c                 L    t        j                  d t        j                        gS r^   )r   r   r   variantrA   s    r"   _flat_tensor_specsz#SparseTensorSpec._flat_tensor_specs  s     ""4899r$   c                     t         j                  |      }t        j                  |j                  |j
                  |j                  t        j                        gS )Nout_type)	r   r#   r   serialize_sparser   r   r   r   r   r   s     r"   _to_tensor_listz SparseTensorSpec._to_tensor_list  sF    ##E*E++u||U%6%6! " "r$   c                 :   t        j                  |j                        }| j                  j	                  |      j
                  dk(  rt        d| d      t        j                  |j                  |j                  |j                  t        j                        gS )Nr   zLUnbatching a sparse tensor is only supported for rank >= 1. Obtained input: .r   )r   r.   r   r   rP   rg   rh   r   serialize_many_sparser   r   r   r   )r7   r   r   s      r"   _to_batched_tensor_listz(SparseTensorSpec._to_batched_tensor_list  s    55e6G6GHK{{k*00A5"G1&' ' 00u||U%6%6! " "r$   c                 6   t        j                  |d   | j                        }|\  }}}| j                  j                  }|j                  d |g       | j                  j                         r1t        j                  | j                  t        j                  d      }n| j                  j                  t        d | j                  j                  D              rt        j                  || j                  j                        }t!        | j                  j                        D ]?  \  }}|j"                  t%        j&                  |j"                  |j(                        ||<   A t        j*                  |      }n|j                  |g       t-        |||      S )Nr   r3   r'   r&   c              3   8   K   | ]  }|j                   d u  y wr^   )r   )r   dims     r"   r   z@SparseTensorSpec._from_compatible_tensor_list.<locals>.<genexpr>  s     @ciit#@s   )num)r   deserialize_sparser   r   rg   rQ   is_fully_definedr	   r,   r   r-   rk   anyr5   r   unstack	enumerater   r   constantr'   stackr   )	r7   r   r   r   r   rk   piecesrx   r   s	            r"   _from_compatible_tensor_listz-SparseTensorSpec._from_compatible_tensor_list  s=    33KNDKKPK#. GV[;;DtTl# {{##%))
++V\\9k
++


&
@t{{/?/?@
@&&{8H8HIfdkk../ I&!S99 !**399k6G6GH&)I $))&1kTF#55r$   c                     t        t        j                  |g      j                  | j                        | j
                        S r^   )rd   r   rO   concatenater   r   )r7   
batch_sizes     r"   _batchzSparseTensorSpec._batch  s5      *.::4;;G r$   c                     | j                   j                  dk(  rt        d      t        | j                   dd  | j                        S )Nr   z3Unbatching a tensor is only supported for rank >= 1r*   )r   rg   rh   rd   r   rA   s    r"   _unbatchzSparseTensorSpec._unbatch  s;    {{ALMMDKKOT[[99r$   c                     | j                   S r^   r   rA   s    r"   _to_legacy_output_typesz(SparseTensorSpec._to_legacy_output_types      ;;r$   c                     | j                   S r^   r   rA   s    r"   _to_legacy_output_shapesz)SparseTensorSpec._to_legacy_output_shapes  r   r$   c                     t         S r^   r   rA   s    r"   _to_legacy_output_classesz*SparseTensorSpec._to_legacy_output_classes  s    r$   c                    t        |t              r | |j                  |j                        S t        |t              rot        |j
                  t        j                        r' | |j                  |j
                  j                        S | j                  t        j                  |            S t        d| dt        |      j                   d      )Nz6Expected SparseTensor or SparseTensorValue. Received: z	 of type r   )rN   r   r3   r'   rY   r   rr   r   r   r#   r   typer   )r    r   s     r"   r#   zSparseTensorSpec.from_value  s    %&ekk**%*+	ELL"**	-5$$ell&8&899~~l55e<==Nye)=)=(>aA B Br$   )r   r   r   r   	__slots__r   
value_typer   float32r<   r   r'   r3   r   r   r   r   r   r   r   r   r   r   r   r   r   r#   r   r$   r"   rd   rd   y  s     ;")12*v~~ 	)&     6 6<
	 : :""6.
:
 
B 
Br$   "convert_to_tensor_or_sparse_tensorc                 f   |t        j                  |      }t        | t              rt        j                  |       } t        | t              rN|rJ|j                  | j                        s/t        d|j                   d| j                  j                         | S t        j                  | ||      S )a  Converts value to a `SparseTensor` or `Tensor`.

  Args:
    value: A `SparseTensor`, `SparseTensorValue`, or an object whose type has a
      registered `Tensor` conversion function.
    dtype: Optional element type for the returned tensor. If missing, the type
      is inferred from the type of `value`.
    name: Optional name to use if a new `Tensor` is created.

  Returns:
    A `SparseTensor` or `Tensor` based on `value`.

  Raises:
    RuntimeError: If result type is incompatible with `dtype`.
  z"Sparse dtype mismatch. Requested: z,  Actual: r   )r   r   rN   rY   r   r#   is_compatible_withr'   RuntimeErrorr&   r	   r,   )r   r'   r&   s      r"   r   r     s    " OOE"E()##E*E|$U--ekk:=ejj\ J%%*[[%5%5$68 9 9L			uE	==r$   c                 .    t        | t        t        f      S )a  Check whether `x` is sparse.

  Check whether an object is a `tf.sparse.SparseTensor` or
  `tf.compat.v1.SparseTensorValue`.

  Args:
    x: A python object to check.

  Returns:
    `True` iff `x` is a `tf.sparse.SparseTensor` or
    `tf.compat.v1.SparseTensorValue`.
  )rN   r   rY   )xs    r"   r   r   3  s     
A&78	99r$   c                    t        j                  |d| |||g      5 }t        j                  |d      }t        j                  |d      }|j                  j                  }|j                  j                  }||k7  rt        d|d|d      	 t        |   }|,t        j                  ||      }t        j                  ||      }t        j                  | ||||      cddd       S # t        $ rV}t        d|d	d
j                  t        j                         D 	cg c]  }	t        |	       nc c}	w c}	       d      |d}~ww xY w# 1 sw Y   yxY w)z.Internal helper function for 'sp_t / dense_t'.truediv	sp_valuesr(   yz*`x` and `y` must have the same dtype, got z != r   zInvalid dtype z" in __truediv__. Expected one of {z, z}.N)r	   r+   r,   r'   
base_dtyper   _TRUEDIV_TABLEKeyErrorjoinkeysreprr   castr   sparse_dense_cwise_div)

sp_indicesr   sp_shaper   r&   x_dtypey_dtyper'   excr   s
             r"   _sparse_dense_truedivr   Y  s_   
~~
I
Ix; %%ikBIac*Aoo((Ggg  G'4{!- W%e ##Iu5i


Au
%a00Ix-   7+ &))n.A.A.CDT!WDDEFcK  s=   A2E	C)AE)	E2*ED/.EEEEdivr   mulr   r^   )Dr   collectionsnumpyrr   tensorflow.core.protobufr   tensorflow.pythonr   r   tensorflow.python.frameworkr   r   r   r	   r
   r   r   r   r   r   r   tensorflow.python.opsr   r   r   tensorflow.python.saved_modelr   tensorflow.python.typesr    tensorflow.python.util.tf_exportr   rX   r_   NativeObjectCompositeTensorr   
namedtuplerY   registerBatchableTypeSpecrd   register_codecBuiltInTypeSpecCodecTypeSpecProtoSPARSE_TENSOR_SPEC'register_type_spec_from_value_converterr#   r   r   uint8r   int8uint16int16uint32float64int32uint64r-   bfloat16float16	complex64
complex128r   r   override_binary_operator_helperr   sparse_dense_cwise_mulr   r$   r"   <module>r     s      / / ! 8 3 . + @ . 4 3 3 1 : 1 . 0 @ , 6 %@@ **   .1@@8((*:*J*J @@ 2@@F
 +K**+>+OQ  #	!" #$5 6 23HBy22 HB 4 HBV &  % %///*22EE 2	 1 1"--/ 1	 1 1'224 345> 6>8:$ LL&..
KK
MM6>>
LL&..
MM6>>
LL&..
MM6>>
LL&..
OOT
NND
NND
NND
d
t*@ 9  8 8))5, 9  8 89l 9  8 8))5,r$   