
    Evgf              	          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mZ d dlmZmZ  G d d          Z G d d          Z G d d          Z G d d          Z G d d          Z G d deee          Z G d de          Z G d dee          Z G d dee          Z  G d dee           Z! G d  d!eee          Z" G d" d#ee"          Z# G d$ d%eee          Z$ G d& d'ee$          Z% G d( d)eeee          Z& G d* d+ee&          Z' G d, d-e&          Z( G d. d/ee(          Z) G d0 d1eeeee          Z* G d2 d3ee*          Z+	 d9d6Z,d7 Z-d8 Z.dS ):    N)settings)ImproperlyConfigured)models)Http404)timezone)cached_property)gettext)View)BaseDetailView!SingleObjectTemplateResponseMixin)MultipleObjectMixin#MultipleObjectTemplateResponseMixinc                   >    e Zd ZdZdZdZd Zd Zd Zd Z	d Z
d	 ZdS )
	YearMixinz-Mixin for views manipulating year-based data.z%YNc                     | j         S )zv
        Get a year format string in strptime syntax to be used to parse the
        year from url variables.
        )year_formatselfs    W/var/www/pixelcanvas.ch/venv/lib/python3.11/site-packages/django/views/generic/dates.pyget_year_formatzYearMixin.get_year_format       
     c                     | j         }|]	 | j        d         }nN# t          $ rA 	 | j        j        d         }n*# t          $ r t          t          d                    w xY wY nw xY w|S )z8Return the year for which this view should display data.NyearzNo year specified)r   kwargsKeyErrorrequestGETr   _)r   r   s     r   get_yearzYearMixin.get_year"       y<:{6* : : ::<+F3DD : : :!!$7"8"8999: D:
 #    
A$7A$'AA$#A$c                 (    t          | |dd          S )zGet the next valid year.Fr   is_previousperiod_get_next_prevr   dates     r   get_next_yearzYearMixin.get_next_year/       dDeFKKKKr   c                 (    t          | |dd          S )zGet the previous valid year.Tr   r$   r'   r)   s     r   get_previous_yearzYearMixin.get_previous_year3       dDd6JJJJr   c                     	 |                     |j        dz   dd          S # t          $ r t          t	          d                    w xY w)
        Return the start date of the next interval.

        The interval is defined by start date <= item date < next start date.
           r   monthdayDate out of range)replacer   
ValueErrorr   r   r)   s     r   _get_next_yearzYearMixin._get_next_year7   sW    	2<<TY]!<CCC 	2 	2 	2!/00111	2s	   " 'A	c                 0    |                     dd          S ).Return the start date of the current interval.r2   r4   r5   r7   r)   s     r   _get_current_yearzYearMixin._get_current_yearB   s    ||!|+++r   )__name__
__module____qualname____doc__r   r   r   r    r+   r.   r9   r>    r   r   r   r      s        77KD       L L LK K K	2 	2 	2, , , , ,r   r   c                   >    e Zd ZdZdZdZd Zd Zd Zd Z	d Z
d	 ZdS )

MonthMixinz.Mixin for views manipulating month-based data.z%bNc                     | j         S )zx
        Get a month format string in strptime syntax to be used to parse the
        month from url variables.
        )month_formatr   s    r   get_month_formatzMonthMixin.get_month_formatM       
   r   c                     | j         }|]	 | j        d         }nN# t          $ rA 	 | j        j        d         }n*# t          $ r t          t          d                    w xY wY nw xY w|S )z9Return the month for which this view should display data.Nr4   zNo month specified)r4   r   r   r   r   r   r   )r   r4   s     r   	get_monthzMonthMixin.get_monthT   s    
=;G, ; ; ;; L,W5EE ; ; ;!!$8"9"9:::; E;
 r"   c                 (    t          | |dd          S )zGet the next valid month.Fr4   r$   r'   r)   s     r   get_next_monthzMonthMixin.get_next_montha   s    dDeGLLLLr   c                 (    t          | |dd          S )zGet the previous valid month.Tr4   r$   r'   r)   s     r   get_previous_monthzMonthMixin.get_previous_monthe   s    dDd7KKKKr   c                     |j         dk    rK	 |                    |j        dz   dd          S # t          $ r t	          t          d                    w xY w|                    |j         dz   d          S )r1      r2   r3   r6   r<   )r4   r7   r   r8   r   r   r)   s     r   _get_next_monthzMonthMixin._get_next_monthi   s     :6||QaQ|GGG 6 6 6a 3445556 <<dj1n!<<<<s	   - 'Ac                 .    |                     d          S )z/Return the start date of the previous interval.r2   )r5   r=   r)   s     r   _get_current_monthzMonthMixin._get_current_monthw   s    |||"""r   )r?   r@   rA   rB   rG   r4   rH   rK   rM   rO   rR   rT   rC   r   r   rE   rE   G   s        88LE! ! !  M M ML L L= = =# # # # #r   rE   c                   >    e Zd ZdZdZdZd Zd Zd Zd Z	d Z
d	 ZdS )
DayMixinz,Mixin for views manipulating day-based data.z%dNc                     | j         S )zt
        Get a day format string in strptime syntax to be used to parse the day
        from url variables.
        )
day_formatr   s    r   get_day_formatzDayMixin.get_day_format   s    
 r   c                     | j         }|]	 | j        d         }nN# t          $ rA 	 | j        j        d         }n*# t          $ r t          t          d                    w xY wY nw xY w|S )z7Return the day for which this view should display data.Nr5   zNo day specified)r5   r   r   r   r   r   r   )r   r5   s     r   get_dayzDayMixin.get_day   s    h;9k%( 9 9 99,*51CC 9 9 9!!$6"7"78889 C9
 
r"   c                 (    t          | |dd          S )zGet the next valid day.Fr5   r$   r'   r)   s     r   get_next_dayzDayMixin.get_next_day   s    dDeEJJJJr   c                 (    t          | |dd          S )zGet the previous valid day.Tr5   r$   r'   r)   s     r   get_previous_dayzDayMixin.get_previous_day   s    dDd5IIIIr   c                 2    |t          j        d          z   S )r1   r2   days)datetime	timedeltar)   s     r   _get_next_dayzDayMixin._get_next_day   s     h(a00000r   c                     |S r;   rC   r)   s     r   _get_current_dayzDayMixin._get_current_day   s    r   )r?   r@   rA   rB   rX   r5   rY   r[   r]   r_   re   rh   rC   r   r   rV   rV   |   s        66J
C    K K KJ J J1 1 1    r   rV   c                   D    e Zd ZdZdZdZd Zd Zd Zd Z	d Z
d	 Zd
 ZdS )	WeekMixinz-Mixin for views manipulating week-based data.%UNc                     | j         S )zv
        Get a week format string in strptime syntax to be used to parse the
        week from url variables.
        )week_formatr   s    r   get_week_formatzWeekMixin.get_week_format   r   r   c                     | j         }|]	 | j        d         }nN# t          $ rA 	 | j        j        d         }n*# t          $ r t          t          d                    w xY wY nw xY w|S )z8Return the week for which this view should display data.NweekzNo week specified)rp   r   r   r   r   r   r   )r   rp   s     r   get_weekzWeekMixin.get_week   r!   r"   c                 (    t          | |dd          S )zGet the next valid week.Frp   r$   r'   r)   s     r   get_next_weekzWeekMixin.get_next_week   r,   r   c                 (    t          | |dd          S )zGet the previous valid week.Trp   r$   r'   r)   s     r   get_previous_weekzWeekMixin.get_previous_week   r/   r   c                     	 |t          j        d|                     |          z
            z   S # t          $ r t	          t          d                    w xY w)r1      ra   r6   )rc   rd   _get_weekdayOverflowErrorr   r   r)   s     r   _get_next_weekzWeekMixin._get_next_week   se    	2(,!d6G6G6M6M2MNNNNN 	2 	2 	2!/00111	2s	   -0 'Ac                 V    |t          j        |                     |                    z
  S rg   )rc   rd   rx   r)   s     r   _get_current_weekzWeekMixin._get_current_week   s&    h():):4)@)@AAAAr   c                     |                                  }|dv r|                                S |dk    r|                                dz   dz  S t          d|z            )z
        Return the weekday for a given date.

        The first day according to the week format is 0 and the last day is 6.
        >   %V%Wrk   r2   rw   zunknown week format: %s)rn   weekdayr8   )r   r*   rm   s      r   rx   zWeekMixin._get_weekday   se     **,,,&&<<>>!D  LLNNQ&!++6DEEEr   )r?   r@   rA   rB   rm   rp   rn   rq   rs   ru   rz   r|   rx   rC   r   r   rj   rj      s        77KD       L L LK K K	2 	2 	2B B BF F F F Fr   rj   c                   H    e Zd ZdZdZdZd Zd Zed             Z	d Z
d ZdS )		DateMixinz3Mixin class for views manipulating date-based data.NFc                 V    | j         t          d| j        j        z            | j         S )z7Get the name of the date field to be used to filter by.Nz%s.date_field is required.)
date_fieldr   	__class__r?   r   s    r   get_date_fieldzDateMixin.get_date_field   s3    ?"&,t~/FF   r   c                     | j         S )zi
        Return `True` if the view should be allowed to display objects from
        the future.
        )allow_futurer   s    r   get_allow_futurezDateMixin.get_allow_future   rI   r   c                     | j         |                                 j         n| j         }|j                            |                                           }t          |t          j                  S )zq
        Return `True` if the date field is a `DateTimeField` and `False`
        if it's a `DateField`.
        )modelget_queryset_meta	get_fieldr   
isinstancer   DateTimeField)r   r   fields      r   uses_datetime_fieldzDateMixin.uses_datetime_field  sZ     .2Z-?!!##))TZ%%d&9&9&;&;<<%!5666r   c                     | j         rOt          j                            |t          j        j                  }t
          j        rt          j        |          }|S )z
        Convert a date into a datetime when the date field is a DateTimeField.

        When time zone support is enabled, `date` is assumed to be in the
        current time zone, so that displayed items are consistent with the URL.
        )	r   rc   combinetimeminr   USE_TZr   
make_aware)r   values     r   _make_date_lookup_argzDateMixin._make_date_lookup_arg  sK     # 	3%--eX]5FGGE 3 +E22r   c                     |                                  }| j        rL|                     |          }|                     |t          j        d          z             }d|z  |d|z  |iS ||iS )z
        Get the lookup kwargs for filtering on a single date.

        If the date field is a DateTimeField, we can't just filter on
        date_field=date because that doesn't take the time into account.
        r2   ra   %s__gte%s__lt)r   r   r   rc   rd   )r   r*   r   sinceuntils        r   _make_single_date_lookupz"DateMixin._make_single_date_lookup  s     ((**
# 		&..t44E..th6Ha6P6P6P/PQQEJ&:%u  %%r   )r?   r@   rA   rB   r   r   r   r   r   r   r   r   rC   r   r   r   r      s{        ==JL  ! ! ! 7 7 _7  & & & & &r   r   c                   @    e Zd ZdZdZdZd Zd Zd Zd Z	d Z
ddZd	S )BaseDateListViewzFAbstract base class for date-based views displaying a list of objects.Fr   c                     |                                  \  | _        | _        } | j        d| j        | j        d|}|                     |          S )N)object_list	date_listrC   )get_dated_itemsr   r   get_context_datarender_to_response)r   r   argsr   extra_contextcontexts         r   getzBaseDateListView.get4  se    :>:N:N:P:P7(-'$' 
(DN
 
FS
 
 &&w///r   c                      t          d          )z#Obtain the list of dates and items.z>A DateView must provide an implementation of get_dated_items())NotImplementedErrorr   s    r   r   z BaseDateListView.get_dated_items;  s    !L
 
 	
r   c                 L    | j         d|                                 z  n| j         S )zu
        Return the field or fields to use for ordering the queryset; use the
        date field by default.
        N-%s)orderingr   r   s    r   get_orderingzBaseDateListView.get_orderingA  s)    
 150Eut**,,,,4=Xr   c                     |                                  j        di |}|                                 }|                                 }|                                 }|                     |          }|s:| j        rt          j                    nt                      } |j        di d|z  |i}|sL|| n|
                                 }|r0t          t          d          d|j        j        j        iz            |S )zs
        Get a queryset properly filtered according to `allow_future` and any
        extra lookup kwargs.
        %s__lteN$No %(verbose_name_plural)s availableverbose_name_pluralrC   )r   filterr   r   get_allow_emptyget_paginate_byr   r   nowtimezone_todayexistsr   r   r   r   r   )	r   lookupqsr   r   allow_emptypaginate_byr   is_emptys	            r   get_dated_querysetz#BaseDateListView.get_dated_querysetH  s   
 (T  '11&11((**
,,..**,,**2.. 	<$($<R(,....BRBRC;;i*4c:;;B 
	 "-!42vvbiikk/H <==-rx~/Q   	r   c                     | j         S )zf
        Get the aggregation period for the list of dates: 'year', 'month', or
        'day'.
        )date_list_periodr   s    r   get_date_list_periodz%BaseDateListView.get_date_list_periode      
 $$r   NASCc                 Z   |                                  }|                                 }||                                 }| j        r|                    |||          }n|                    |||          }|4|s2|s0t          t          d          d|j        j	        j
        iz            |S )z
        Get a date list by calling `queryset.dates/datetimes()`, checking
        along the way for empty lists that aren't allowed.
        Nr   r   )r   r   r   r   	datetimesdatesr   r   r   r   r   )r   queryset	date_typer   r   r   r   s          r   get_date_listzBaseDateListView.get_date_listl  s    
 ((**
**,,1133I# 	H **:y(KKII z9hGGI  ; 899)8>+?+S   r   )Nr   )r?   r@   rA   rB   r   r   r   r   r   r   r   r   rC   r   r   r   r   .  s        PPK0 0 0
 
 
Y Y Y  :% % %     r   r   c                       e Zd ZdZdZd ZdS )BaseArchiveIndexViewzQ
    Base class for archives of date-based items. Requires a response mixin.
    latestc                     |                                  }|                     |d          }|s|                                }||i fS ):Return (date_list, items, extra_context) for this request.DESC)r   )r   r   none)r   r   r   s      r   r   z$BaseArchiveIndexView.get_dated_items  sM    $$&&&&rF&;;	 	B2r""r   N)r?   r@   rA   rB   context_object_namer   rC   r   r   r   r     s5          ## # # # #r   r   c                       e Zd ZdZdZdS )ArchiveIndexViewz&Top-level archive of date-based items._archiveNr?   r@   rA   rB   template_name_suffixrC   r   r   r   r     s        00%r   r   c                   &    e Zd ZdZdZdZd Zd ZdS )BaseYearArchiveView*List of objects published in a given year.r4   Fc                    |                                  }|                                 }t          ||                                           }|                     |          }|                     |                     |                    }d|z  |d|z  |i} | j        di |}|                     |          }|                                 s|	                                }|||| 
                    |          |                     |          dfS )r   r   r   )r   	next_yearprevious_yearrC   )r    r   _date_from_stringr   r   r9   r   r   get_make_object_listr   r+   r.   )	r   r   r   r*   r   r   lookup_kwargsr   r   s	            r   r   z#BaseYearArchiveView.get_dated_items  s   }}((**
 t';';'='=>>**400**4+>+>t+D+DEE
"Ez!5

 %T$55}55&&r**	((** 	 B !//55!%!7!7!=!= 
 	
r   c                     | j         S )zo
        Return `True` if this view should contain the full list of objects in
        the given year.
        )make_object_listr   s    r   r   z(BaseYearArchiveView.get_make_object_list  r   r   N)r?   r@   rA   rB   r   r   r   r   rC   r   r   r   r     sE        44
 
 
@% % % % %r   r   c                       e Zd ZdZdZdS )YearArchiveViewr   _archive_yearNr   rC   r   r   r   r             44*r   r   c                       e Zd ZdZdZd ZdS )BaseMonthArchiveView+List of objects published in a given month.r5   c                    |                                  }|                                 }|                                 }t          ||                                 ||                                           }|                     |          }|                     |                     |                    }d|z  |d|z  |i} | j        di |}| 	                    |          }	|	||| 
                    |          |                     |          dfS )r   r   r   )r4   
next_monthprevious_monthrC   )r    rK   r   r   r   rH   r   rR   r   r   rM   rO   )
r   r   r4   r   r*   r   r   r   r   r   s
             r   r   z$BaseMonthArchiveView.get_dated_items  s   }}  ((**
 $&&((%1F1F1H1H
 
 **400**4+?+?+E+EFF
"Ez!5

 %T$55}55&&r**	 "11$77"&"9"9$"?"? 
 	
r   N)r?   r@   rA   rB   r   r   rC   r   r   r   r     s/        55
 
 
 
 
r   r   c                       e Zd ZdZdZdS )MonthArchiveViewr   _archive_monthNr   rC   r   r   r   r     s        55+r   r   c                       e Zd ZdZd ZdS )BaseWeekArchiveView*List of objects published in a given week.c                    |                                  }|                                 }|                                 }|                                 }dddd}	 ||         }nC# t          $ r6 t          d|dd                    t          |                              w xY w|                                 }|dk    r|dk    rt          d	|d
|d          t          |||d||          }| 
                    |          }	| 
                    |                     |                    }
d|z  |	d|z  |
i} | j        di |}d|||                     |          |                     |          dfS )r   10)r   rk   r~   zUnknown week format z. Choices are: z, r~   z%GzISO week directive 'z+' is incompatible with the year directive 'z!'. Use the ISO year '%G' instead.z%wr   r   N)rp   	next_weekprevious_weekrC   )r    rq   r   rn   r   r8   joinsortedr   r   r   rz   r   rs   ru   )r   r   rp   r   rm   week_choices
week_startr   r*   r   r   r   r   s                r   r   z#BaseWeekArchiveView.get_dated_items  s   }}}}((**
**,,!C88		%k2JJ 	 	 	*  KKIIf\22333  	 **,,$;$#6#6*  KKKK	   !{JdKXX**400**4+>+>t+D+DEE
"Ez!5

 %T$55}55 !//55!%!7!7!=!= 
 	
s   A! !A B!Nr?   r@   rA   rB   r   rC   r   r   r   r     s)        44.
 .
 .
 .
 .
r   r   c                       e Zd ZdZdZdS )WeekArchiveViewr   _archive_weekNr   rC   r   r   r  r  /  r   r   r  c                       e Zd ZdZd Zd ZdS )BaseDayArchiveView)List of objects published on a given day.c           	      8   |                                  }|                                 }|                                 }t          ||                                 ||                                 ||                                           }|                     |          S r   )r    rK   r[   r   r   rH   rY   _get_dated_items)r   r   r4   r5   r*   s        r   r   z"BaseDayArchiveView.get_dated_items8  s    }}  llnn   ""!!##!!
 
 $$T***r   c           	          |                      |          } | j        di |}d|||                     |          |                     |          |                     |          |                     |          dfS )z
        Do the actual heavy lifting of getting the dated items; this accepts a
        date object so that TodayArchiveView can be trivial.
        N)r5   previous_daynext_dayr   r   rC   )r   r   r_   r]   rO   rM   )r   r*   r   r   s       r   r  z#BaseDayArchiveView._get_dated_itemsI  s    
 55d;;$T$55}55  $ 5 5d ; ; --d33"&"9"9$"?"?"11$77 

 
	
r   N)r?   r@   rA   rB   r   r  rC   r   r   r  r  5  s8        33+ + +"
 
 
 
 
r   r  c                       e Zd ZdZdZdS )DayArchiveViewr  _archive_dayNr   rC   r   r   r  r  ^  s        33)r   r  c                       e Zd ZdZd ZdS )BaseTodayArchiveView List of objects published today.c                 d    |                      t          j                                                  S r  )r  rc   r*   todayr   s    r   r   z$BaseTodayArchiveView.get_dated_itemsg  s$    $$X]%8%8%:%:;;;r   Nr   rC   r   r   r  r  d  s)        **< < < < <r   r  c                       e Zd ZdZdZdS )TodayArchiveViewr  r  Nr   rC   r   r   r  r  l  s        **)r   r  c                   $     e Zd ZdZd fd	Z xZS )BaseDateDetailView
    Detail view of a single object on a single date; this differs from the
    standard DetailView by accepting a year/month/day in the URL.
    Nc           	         |                                  }|                                 }|                                 }t          ||                                 ||                                 ||                                           }||                                 n|}|                                 s]|t          j
                                        k    r;t          t          d          |j        j        j        | j        j        dz            |                     |          } |j        di |}t+                                          |          S )z%Get the object this request displays.NzZFuture %(verbose_name_plural)s not available because %(class_name)s.allow_future is False.)r   
class_name)r   rC   )r    rK   r[   r   r   rH   rY   r   r   rc   r*   r  r   r   r   r   r   r   r?   r   r   super
get_object)	r   r   r   r4   r5   r*   r   r   r   s	           r   r  zBaseDateDetailView.get_objectx  sH   }}  llnn   ""!!##!!
 
 %-$4T   ($$&& 
	4(-2E2E2G2G+G+G< 
 ,.8>+M"&."9 		 	 	 55d;;RY''''ww!!2!...r   )N)r?   r@   rA   rB   r  __classcell__)r   s   @r   r  r  r  sG         
#/ #/ #/ #/ #/ #/ #/ #/ #/ #/r   r  c                       e Zd ZdZdZdS )DateDetailViewr  _detailNr   rC   r   r   r  r    s"         
 %r   r   __c                 N   ||z   |z   |z   |z   }t          |           |z   t          |          z   |z   t          |          z   }	 t          j                            ||                                          S # t          $ r# t          t          d          ||dz            w xY w)z
    Get a datetime.date object given a format string and a year, month, and day
    (only year is mandatory). Raise a 404 for an invalid date.
    uC   Invalid date string “%(datestr)s” given format “%(format)s”)datestrformat)strrc   strptimer*   r8   r   r   )	r   r   r4   rG   r5   rX   delimr%  r$  s	            r   r   r     s     5 </%7*DF$ii%#e**,u4s3xx?G	
 ))'6::??AAA 
 
 
STT"  
 
 	

s   1A7 7-B$c                    |                                  }|                                 }|                                 }t          | d|z            }t          | d|z            } ||           ||          }
}	|r>|r" ||	t	          j        d          z
            }n|
}|s|t                      k    r|S dS |r d|z  |                     |	          i}d|z  }nd|z  |                     |
          i}|}|s1| j        rt          j
                    }nt                      }||d	|z  <    |                                 j        di |                    |          }	 t          |d
         |          }n# t          $ r Y dS w xY w| j        r4t          j        rt          j        |          }|                                } ||          S )aV  
    Get the next or the previous valid date. The idea is to allow links on
    month/day views to never be 404s by never providing a date that'll be
    invalid for the given view.

    This is a bit complicated since it handles different intervals of time,
    hence the coupling to generic_view.

    However in essence the logic comes down to:

        * If allow_empty and allow_future are both true, this is easy: just
          return the naive result (just the next/previous day/week/month,
          regardless of object existence.)

        * If allow_empty is true, allow_future is false, and the naive result
          isn't in the future, then return it; otherwise return None.

        * If allow_empty is false and allow_future is true, return the next
          date *that contains a valid object*, even if it's in the future. If
          there are no next objects, return None.

        * If allow_empty is false and allow_future is false, return the next
          date that contains a valid object. If that date is in the future, or
          if there are no next objects, return None.
    z_get_current_%sz_get_next_%sr2   ra   Nr   r   r   r   r   rC   )r   r   r   getattrrc   rd   r   r   r   r   r   r   r   order_by
IndexErrorr   r   	localtimer*   )generic_viewr*   r%   r&   r   r   r   get_currentget_nextstartendresultr   r   r   r   s                   r   r(   r(     s#   4 ,,..J..00K0022L,(9F(BCCK|^f%<==H T""HHTNN3E  2# 	 [);)C)C)C!CDDFFF 	6^%5%555M4  	"+\-O-OPU-V-VWFz)HH*,l.P.PQT.U.UVF!H  	1 / 'lnn$&&-0F9z)*/\&&((/99&99BB8LL	RUJ//FF 	 	 	44	 + 	# 4!+F33[[]]F {6"""s   E4 4
FFc                  |    t           j        rt          j                    S t          j                                        S )z1Return the current date in the current time zone.)r   r   r   	localdaterc   r*   r  rC   r   r   r   r     s/     %!###}""$$$r   )r!  r!  r!  r!  r"  )/rc   django.confr   django.core.exceptionsr   	django.dbr   django.httpr   django.utilsr   django.utils.functionalr   django.utils.translationr	   r   django.views.generic.baser
   django.views.generic.detailr   r   django.views.generic.listr   r   r   rE   rV   rj   r   r   r   r   r   r   r   r   r   r  r  r  r  r  r  r  r   r(   r   rC   r   r   <module>r@     s                7 7 7 7 7 7             ! ! ! ! ! ! 3 3 3 3 3 3 1 1 1 1 1 1 * * * * * *              /, /, /, /, /, /, /, /,d2# 2# 2# 2# 2# 2# 2# 2#j, , , , , , , ,^=F =F =F =F =F =F =F =F@@& @& @& @& @& @& @& @&FT T T T T*It T T Tn# # # # #+ # # #$& & & & &:<P & & &+% +% +% +% +%)%5 +% +% +%\+ + + + +9;N + + +!
 !
 !
 !
 !
9j2B !
 !
 !
H, , , , ,:<P , , ,1
 1
 1
 1
 1
)Y0@ 1
 1
 1
h+ + + + +9;N + + +&
 &
 &
 &
 &
J:J &
 &
 &
R* * * * *8:L * * *< < < < <- < < <* * * * *:<P * * *)/ )/ )/ )/ )/J)^ )/ )/ )/X% % % % %68J % % % PT
 
 
 
*W# W# W#t% % % % %r   