o
    Սdh3z                     @   s  d Z ddlmZ ddlmZmZ ddlmZ ddlm	Z	 ddl
mZmZmZ ddlmZ ddlmZ dd	lmZ dd
lmZ 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m Z m!Z!m"Z"m#Z#m$Z$m%Z% ddl&m'Z'm(Z( G dd deZ)G dd deZ*G dd deZ+G dd deZ,G dd deZ-G dd deZ.G dd dej/Z0G dd  d ej/Z1G d!d" d"ej/Z2G d#d$ d$ej/Z3G d%d& d&ej/Z4e5eG d'd( d(ej6Z7e5eG d)d* d*ej6Z8e5e!G d+d, d,ej6Z9e5e"G d-d. d.ej6Z:e5e#G d/d0 d0ej6Z;e5eG d1d2 d2ej6Z<e5e G d3d4 d4ej6Z=e5e$G d5d6 d6ej6Z>e5eG d7d8 d8ej6Z?d9ej@_Ad:ej@_Bd;ej@_CdS )<a  Creative Management Admin Configuration

Django admin interface for creative asset management.
Provides comprehensive admin functionality for all creative-related models.

Features:
- Custom admin interfaces for all models
- Inline editing for related models
- Custom filters and search
- Bulk actions and operations
- Custom display methods
- File upload handling
- Performance metrics display
- Approval workflow management

Admin Classes:
- CreativeAdmin: Main creative management
- CreativeTemplateAdmin: Template administration
- CreativeApprovalAdmin: Approval workflow
- CreativePerformanceAdmin: Performance data
- CreativeVersionAdmin: Version management
- CreativeAssetAdmin: Asset management
- CreativeComplianceAdmin: Compliance tracking
- CreativeTagAdmin: Tag management

Customizations:
- Rich text editing
- Image previews
- Performance charts
- Bulk approval actions
- Export functionality
- Advanced filtering
    )admin)format_html	mark_safe)timezone)reverse)CountSumAvg)SimpleListFilter)HttpResponse)render)messages)ValidationErrorN)datetime	timedelta   )
CreativeCreativeVersionCreativeFormatCreativeTemplateCreativeAssetCreativeApprovalCreativePerformanceCreativeTagCreativeComplianceCreativeVariant)process_creative_filecheck_compliancec                   @   (   e Zd ZdZdZdZdd Zdd ZdS )	CreativeTypeFilterzFilter creatives by type.zCreative Typecreative_typec                 C      t jS N)r   CREATIVE_TYPESselfrequestmodel_admin r(   HC:\Users\vibe-look\OneDrive\Desktop\Adtlas_V\src\apps\creatives\admin.pylookups@      zCreativeTypeFilter.lookupsc                 C      |   r|j|   dS |S )N)r    valuefilterr%   r&   querysetr(   r(   r)   r1   C      zCreativeTypeFilter.querysetN__name__
__module____qualname____doc__titleparameter_namer*   r1   r(   r(   r(   r)   r   ;       r   c                   @   r   )	CreativeStatusFilterzFilter creatives by status.zCreative Statuscreative_statusc                 C   r!   r"   )r   CREATIVE_STATUSr$   r(   r(   r)   r*   N   r+   zCreativeStatusFilter.lookupsc                 C   r,   )N)r<   r-   r0   r(   r(   r)   r1   Q   r2   zCreativeStatusFilter.querysetNr3   r(   r(   r(   r)   r;   I   r:   r;   c                   @   r   )	CampaignFilterzFilter creatives by campaign.Campaigncampaignc                 C   s,   ddl m} |j d d }dd |D S )Nr   )r?      c                 S   s   g | ]}|j |jfqS r(   )idname).0cr(   r(   r)   
<listcomp>_       z*CampaignFilter.lookups.<locals>.<listcomp>)apps.campaigns.modelsr?   objectsall)r%   r&   r'   r?   	campaignsr(   r(   r)   r*   \   s   zCampaignFilter.lookupsc                 C   r,   )N)campaign_idr-   r0   r(   r(   r)   r1   a   r2   zCampaignFilter.querysetNr3   r(   r(   r(   r)   r>   W   s    r>   c                   @   r   )	HasFileFilterz"Filter creatives by file presence.zHas FileZhas_filec                 C      dS )N))yesYes)noNor(   r$   r(   r(   r)   r*   l      zHasFileFilter.lookupsc                 C   s4   |   dkr|jddS |   dkr|jddS |S )NrO    )primary_filerQ   )r.   excluder/   r0   r(   r(   r)   r1   r   s
   zHasFileFilter.querysetNr3   r(   r(   r(   r)   rM   g   s    rM   c                   @   r   )	ComplianceFilterz&Filter creatives by compliance status.
Compliance
compliancec                 C   rN   )N))	compliant	Compliant)non_compliantzNon-Compliant)not_checkedzNot Checkedr(   r$   r(   r(   r)   r*      rS   zComplianceFilter.lookupsc                 C   sL   |   dkr|jddS |   dkr|jddS |   dkr$|jddS |S )NrZ   T)is_compliantr\   Fr]   )Zcompliance_score__isnullr-   r0   r(   r(   r)   r1      s   zComplianceFilter.querysetNr3   r(   r(   r(   r)   rW   z   s    rW   c                   @   r   )	PerformanceFilterz Filter creatives by performance.PerformanceZperformancec                 C   rN   )N))highzHigh Performance)mediumzMedium Performance)lowzLow Performance)no_datazNo Performance Datar(   r$   r(   r(   r)   r*      rS   zPerformanceFilter.lookupsc                 C   sf   |   dkr|jddS |   dkr|jdddS |   dkr%|jddS |   d	kr1|jd
dS |S )Nra   i  )clicks__gterb   d   )re   
clicks__ltrc   )rg   rd   r   impressionsr-   r0   r(   r(   r)   r1      s   zPerformanceFilter.querysetNr3   r(   r(   r(   r)   r_      s    r_   c                   @   s2   e Zd ZdZeZdZg dZg dZdddZ	dS )	CreativeVersionInlinez#Inline admin for creative versions.r   version_number	file_size
created_at)rl   filerm   changes
created_byrn   Nc                 C      |r| j dg S | j S )Nrq   readonly_fieldsr%   r&   objr(   r(   r)   get_readonly_fields      z)CreativeVersionInline.get_readonly_fieldsr"   )
r4   r5   r6   r7   r   modelextrart   fieldsrw   r(   r(   r(   r)   rj          rj   c                   @   s(   e Zd ZdZeZdZddgZg dZdS )CreativeAssetInlinez!Inline admin for creative assets.r   rm   rn   )
asset_typerC   ro   rm   orderrn   N)	r4   r5   r6   r7   r   ry   rz   rt   r{   r(   r(   r(   r)   r}      s    r}   c                   @   s2   e Zd ZdZeZdZddgZg dZd	ddZ	dS )
CreativeApprovalInlinez$Inline admin for creative approvals.r   rn   reviewed_at)reviewerapproval_statuscommentsr   rn   Nc                 C   rr   )Nr   rs   ru   r(   r(   r)   rw      rx   z*CreativeApprovalInline.get_readonly_fieldsr"   )
r4   r5   r6   r7   r   ry   rz   rt   r{   rw   r(   r(   r(   r)   r      r|   r   c                   @   &   e Zd ZdZeZdZdgZg dZdS )CreativePerformanceInlinez&Inline admin for creative performance.r   rn   )dateri   clicksconversionsspendrevenuern   N)	r4   r5   r6   r7   r   ry   rz   rt   r{   r(   r(   r(   r)   r          r   c                   @   r   )CreativeVariantInlinez#Inline admin for creative variants.r   rn   )variant_nameZvariant_dataZ
is_controltraffic_allocationrn   N)	r4   r5   r6   r7   r   ry   rz   rt   r{   r(   r(   r(   r)   r      r   r   c                
       s  e Zd ZdZg dZeeeee	e
dddg	Zg dZg dZdd	d
ifdd	difddddfddddfddddfddddfddddffZdgZeeeeegZg dZ fddZdd Zde_d e_d!d" Zd#e_d$e_d%d& Zd'e_d(e_d)d* Zd+e_d,d- Zd.e_d/d0 Zde_d1d2 Z de _d3d4 Z!d5e!_de!_d6d7 Z"d8e"_d9d: Z#d;e#_d<d= Z$d>e$_d?d@ Z%dAe%_dBdC Z&dDe&_dEdF Z'dGe'_dHdI Z(dJe(_  Z)S )KCreativeAdminzCreative admin interface.)
rC   creative_type_displaycreative_status_displaycampaign_linkfile_previewcompliance_displayperformance_summarypriority_displayrq   rn   priorityrn   deadline)rC   descriptioncampaign__nameZcreated_by__first_nameZcreated_by__last_name)rm   duration
dimensionsr^   compliance_scoreri   r   r   rn   
updated_atfile_preview_largeperformance_chartBasic Informationr{   )rC   r   r    r@   r   zFile Information)rU   r   	thumbnailrm   r   r   rX   )r^   r   collapser{   classesr`   )ri   r   r   r   Z
Scheduling)r   Tags)tagsMetadata)rq   
updated_byrn   r   r   )approve_creativesreject_creativesprocess_filescheck_compliance_bulkexport_creativesduplicate_creativesc                    s    t  |ddddddS )z&Optimize queryset with select_related.r@   rq   r   r   versions	approvalsN)superget_querysetselect_relatedprefetch_related)r%   r&   	__class__r(   r)   r   &  s
   
zCreativeAdmin.get_querysetc                 C   s4   dddddd}| |jd}td| || S )	z Display creative type with icon.   🖼️   🎥   🎵   📄   📰imagevideoaudiohtmlbannerz<span title="{}">{} {}</span>N)getr    r   get_creative_type_displayr%   rv   ZiconsZiconr(   r(   r)   r   ,  s   z#CreativeAdmin.creative_type_displayTyper    c                 C   s0   ddddddd}| |jd}td|| S )	z*Display creative status with color coding.#6c757d#ffc107z#17a2b8#28a745#dc3545)draft
processingpending_reviewapprovedrejectedarchived5<span style="color: {}; font-weight: bold;">{}</span>N)r   r<   r   get_creative_status_displayr%   rv   colorscolorr(   r(   r)   r   ?  s   z%CreativeAdmin.creative_status_displayStatusr<   c                 C   s,   |j rtd|j jgd}td||j jS dS )z#Display campaign as clickable link.zadmin:campaigns_campaign_changeargs<a href="{}">{}</a>-N)r@   r   pkr   rC   r%   rv   urlr(   r(   r)   r   R  s   zCreativeAdmin.campaign_linkr?   r   c                 C   s&   |j r
td|j jS |jrtdS dS )zDisplay file preview thumbnail.zX<img src="{}" style="width: 50px; height: 50px; object-fit: cover; border-radius: 4px;">ub   <span style="padding: 10px; background: #f8f9fa; border-radius: 4px; font-size: 12px;">📄</span>r   N)r   r   r   rU   r%   rv   r(   r(   r)   r   [  s   zCreativeAdmin.file_previewPreviewc                 C   sD   |j r
td|j jS |jr td|jjr|jjdd S dS dS )zDisplay large file preview.O<img src="{}" style="max-width: 300px; max-height: 300px; border-radius: 8px;">u   <div style="padding: 20px; background: #f8f9fa; border-radius: 8px; text-align: center;"><span style="font-size: 48px;">📄</span><br><small>{}</small></div>/FilezNo file uploadedN)r   r   r   rU   rC   splitr   r(   r(   r)   r   i  s   z CreativeAdmin.file_preview_largezFile Previewc                 C   s8   |j du r	tdS |j rtd|jpdS td|jpdS )zDisplay compliance status.Nz0<span style="color: #6c757d;">Not Checked</span>u7   <span style="color: #28a745;">✓ Compliant ({})</span>zN/Au;   <span style="color: #dc3545;">✗ Non-Compliant ({})</span>)r^   r   r   r   r(   r(   r)   r   z  s   
z CreativeAdmin.compliance_displayc                 C   s>   |j dkr|j r|j|j  d nd}td|j |j|S tdS )zDisplay performance summary.r   rf   u/   <small>👁 {} | 👆 {} | CTR: {:.1f}%</small>z.<small style="color: #6c757d;">No data</small>N)ri   r   r   r%   rv   ctrr(   r(   r)   r     s   
z!CreativeAdmin.performance_summaryc                 C   s.   dddddd}| |jd}td|| S )
z'Display priority with visual indicator.r   z#fd7e14r   z#20c997r   )r               r   u9   <span style="color: {}; font-weight: bold;">● {}</span>N)r   r   r   get_priority_displayr   r(   r(   r)   r     s   zCreativeAdmin.priority_displayPriorityc                 C   sn   |j r5|j dd }|r5dd |D dd |D dd |D dd |D d}td	|j |j t|S d
S )zDisplay performance chart.N   c                 S   s   g | ]}|j d qS )z%m/%d)r   strftimerD   pr(   r(   r)   rF     rG   z3CreativeAdmin.performance_chart.<locals>.<listcomp>c                 S      g | ]}|j qS r(   rh   r   r(   r(   r)   rF         c                 S   r   r(   )r   r   r(   r(   r)   rF     r   c                 S   r   r(   )r   r   r(   r(   r)   rF     r   )labelsri   r   r   aC  <div id="performance-chart-{}" style="width: 100%; height: 200px;"></div><script>if (typeof Chart !== "undefined") {{  var ctx = document.getElementById("performance-chart-{}").getContext("2d");  new Chart(ctx, {{    type: "line",    data: {},    options: {{ responsive: true, maintainAspectRatio: false }}  }});}}</script>zNo performance data available)r   performance_datarJ   r   jsondumps)r%   rv   r   Z
chart_datar(   r(   r)   r     s   zCreativeAdmin.performance_chartzPerformance Chartc                 C   d   d}|D ] }|j dkr$tjj||jddt d d|_ |  |d7 }q| || dt	j
 dS )	zBulk approve creatives.r   r   r   zBulk approved by admincreativer   r   r   r   r   z& creatives were successfully approved.N)r<   r   rI   createuserr   nowsavemessage_userr   SUCCESSr%   r&   r1   countr   r(   r(   r)   r     &   
zCreativeAdmin.approve_creativeszApprove selected creativesc                 C   r   )	zBulk reject creatives.r   r   r   zBulk rejected by adminr   r   z creatives were rejected.N)r<   r   rI   r   r   r   r   r   r   r   WARNINGr  r(   r(   r)   r     r  zCreativeAdmin.reject_creativeszReject selected creativesc                 C   sD   d}|D ]}|j rt|j |d7 }q| |d| dtj dS )zBulk process creative files.r   r   zProcessing started for  creatives.N)rU   r   delayrB   r   r   INFOr  r(   r(   r)   r     s   
zCreativeAdmin.process_fileszProcess selected creative filesc                 C   s>   d}|D ]}t |j |d7 }q| |d| dtj dS )zBulk check compliance.r   r   zCompliance check started for r  N)r   r  rB   r   r   r  r  r(   r(   r)   r     s   

z#CreativeAdmin.check_compliance_bulkz'Check compliance for selected creativesc                 C   s~   t dd}d|d< t|}|g d |D ]%}||j| | |jr*|jjnd| |j	|j
|j|jdg	 q|S )	zExport creatives to CSV.ztext/csv)content_typez$attachment; filename="creatives.csv"zContent-Disposition)	Namer   r   r?   r   ImpressionsClicksConversionsz
Created AtrT   z%Y-%m-%d %H:%M:%SN)r   csvwriterwriterowrC   r   r   r@   r   ri   r   r   rn   r   )r%   r&   r1   responser  r   r(   r(   r)   r     s"   


zCreativeAdmin.export_creativesz Export selected creatives to CSVc              
   C   sp   d}|D ]&}t jj|j d|j|j|j|j|j|jd}|j	
|j	  |d7 }q| || dtj dS )zDuplicate selected creatives.r   z (Copy))rC   r   r    r@   r   rq   r   r   z creatives were duplicated.N)r   rI   r   rC   r   r    r@   r   r   r   setrJ   r   r   r  )r%   r&   r1   r  original	duplicater(   r(   r)   r   -  s$   

z!CreativeAdmin.duplicate_creativeszDuplicate selected creatives)*r4   r5   r6   r7   list_displayr   r;   r>   rM   rW   r_   list_filtersearch_fieldsrt   	fieldsetsfilter_horizontalrj   r}   r   r   r   inlinesactionsr   r   short_descriptionadmin_order_fieldr   r   r   r   r   r   r   r   r   r   r   r   r   r   __classcell__r(   r(   r   r)   r      s    r   c                   @   s   e Zd ZdZg dZg dZddgZg dZddd	ifd
ddifdddifddddfddddffZdd Z	de	_
de	_dd Zde_
dS )CreativeTemplateAdminz"Creative template admin interface.)rC   template_type_displayusage_count	is_activerq   rn   )template_typer"  rn   rC   r   )r!  rn   r   preview_displayr   r{   )rC   r   r#  r"  zTemplate Data)Ztemplate_data	variablesr   )preview_imager$  zUsage Statistics)r!  r   r   r   )rq   rn   r   c                 C   s.   dddddd}| |jd}td|| S )	z Display template type with icon.r   r   r   r   r   r   z{} {}N)r   r#  r   get_template_type_displayr   r(   r(   r)   r   k  s   z+CreativeTemplateAdmin.template_type_displayr   r#  c                 C   s   |j r
td|j jS dS )zDisplay template preview.r   zNo preview availableN)r&  r   r   r   r(   r(   r)   r$  y  s   z%CreativeTemplateAdmin.preview_displayN)r4   r5   r6   r7   r  r  r  rt   r  r   r  r  r$  r(   r(   r(   r)   r  H  s:    
r  c                   @   sV   e Zd ZdZg dZg dZg dZdgZdd Zde_	d	e_
d
d Zde_	de_
dS )CreativeApprovalAdminz"Creative approval admin interface.)creative_linkapproval_status_displayr   r   rn   )r   r   rn   )creative__nameZreviewer__first_nameZreviewer__last_namer   rn   c                 C   "   t d|jjgd}td||jjS z#Display creative as clickable link.zadmin:creatives_creative_changer   r   Nr   r   r   r   rC   r   r(   r(   r)   r)       z#CreativeApprovalAdmin.creative_linkr   r+  c                 C   *   dddd}| |jd}td|| S )z*Display approval status with color coding.r   r   r   )pendingr   r   r   r   N)r   r   r   get_approval_status_displayr   r(   r(   r)   r*       z-CreativeApprovalAdmin.approval_status_displayr   r   N)r4   r5   r6   r7   r  r  r  rt   r)  r  r  r*  r(   r(   r(   r)   r(    s    
r(  c                   @   sl   e Zd ZdZg dZddgZdgZg dZdd Zd	e_	de_
d
d Zde_	dd Zde_	dd Zde_	dS )CreativePerformanceAdminz%Creative performance admin interface.)r)  r   ri   r   r   ctr_displayr   r   r   rn   r+  )rn   r5  conversion_rate_displayroas_displayc                 C   r,  r-  r.  r   r(   r(   r)   r)    r/  z&CreativePerformanceAdmin.creative_linkr   c                 C   *   |j dkr|j|j  d }|ddS dS )zDisplay click-through rate.r   rf   .2f%0.00%N)ri   r   r   r(   r(   r)   r5       
z$CreativePerformanceAdmin.ctr_displayZCTRc                 C   r8  )zDisplay conversion rate.r   rf   r9  r:  r;  N)r   r   )r%   rv   rater(   r(   r)   r6    r<  z0CreativePerformanceAdmin.conversion_rate_displayz
Conv. Ratec                 C   s*   |j dkrt|j|j  }|ddS dS )zDisplay return on ad spend.r   r9  xz0.00xN)r   floatr   )r%   rv   roasr(   r(   r)   r7    r<  z%CreativePerformanceAdmin.roas_displayZROASN)r4   r5   r6   r7   r  r  r  rt   r)  r  r  r5  r6  r7  r(   r(   r(   r)   r4    s    
r4  c                   @   s<   e Zd ZdZg dZddgZdd Zde_dd	 Zd
e_dS )CreativeTagAdminzCreative tag admin interface.)rC   color_displayusage_count_displayr   rC   r   c                 C   s   t d|j|jS )z$Display color with visual indicator.z<span style="display: inline-block; width: 20px; height: 20px; background-color: {}; border-radius: 50%; margin-right: 8px;"></span>{}N)r   r   r   r(   r(   r)   rB    s   zCreativeTagAdmin.color_displayColorc                 C   s   |j  }td|S )zDisplay tag usage count.zd<span style="background: #e9ecef; padding: 2px 8px; border-radius: 12px; font-size: 12px;">{}</span>N)Zcreative_setr  r   )r%   rv   r  r(   r(   r)   rC    s
   
z$CreativeTagAdmin.usage_count_displayzUsage CountN)	r4   r5   r6   r7   r  r  rB  r  rC  r(   r(   r(   r)   rA    s    
rA  c                   @   sP   e Zd ZdZg dZdgZddgZg dZdd Zd	e_	de_
d
d Zde_	dS )CreativeVersionAdminz!Creative version admin interface.)r)  rl   file_size_displayrq   rn   rn   r+  rp   rk   c                 C   r,  r-  r.  r   r(   r(   r)   r)    r/  z"CreativeVersionAdmin.creative_linkr   c                 C      |j r| S dS z!Display human-readable file size.r   Nrm   get_file_size_displayr   r(   r(   r)   rF       z&CreativeVersionAdmin.file_size_display	File SizeNr4   r5   r6   r7   r  r  r  rt   r)  r  r  rF  r(   r(   r(   r)   rE    s    
rE  c                   @   sR   e Zd ZdZg dZddgZddgZddgZdd	 Zd
e_	de_
dd Zde_	dS )CreativeAssetAdminzCreative asset admin interface.)rC   r)  r~   rF  r   rn   r~   rn   rC   r+  rm   c                 C   r,  r-  r.  r   r(   r(   r)   r)  %  r/  z CreativeAssetAdmin.creative_linkr   c                 C   rG  rH  rI  r   r(   r(   r)   rF  ,  rK  z$CreativeAssetAdmin.file_size_displayrL  NrM  r(   r(   r(   r)   rN    s    
rN  c                   @   sV   e Zd ZdZg dZg dZdgZddgZdd Zd	e_	de_
d
d Zde_	de_
dS )CreativeComplianceAdminz$Creative compliance admin interface.)r)  compliance_status_displayr   
checked_atrn   )compliance_statusrQ  rn   r+  rQ  rn   c                 C   r,  r-  r.  r   r(   r(   r)   r)  C  r/  z%CreativeComplianceAdmin.creative_linkr   c                 C   r0  )z,Display compliance status with color coding.r   r   r   )rZ   r\   r1  r   r   N)r   rR  r   get_compliance_status_displayr   r(   r(   r)   rP  J  r3  z1CreativeComplianceAdmin.compliance_status_displayr   rR  N)r4   r5   r6   r7   r  r  r  rt   r)  r  r  rP  r(   r(   r(   r)   rO  4  s    
rO  c                   @   sX   e Zd ZdZg dZddgZddgZdgZdd Zd	e_	d
d Z
de
_	dd Zde_	dS )CreativeFormatAdminz Creative format admin interface.)rC   dimensions_displaymax_file_size_displaysupported_types_displayr"  rn   r"  rn   rC   r   c                 C   s   |j  d|j S )zDisplay format dimensions.u    × N)widthheightr   r(   r(   r)   rU  j  s   z&CreativeFormatAdmin.dimensions_display
Dimensionsc                 C   s    |j r|j d }|ddS dS )z/Display max file size in human-readable format.i   z.1fz MBr   N)max_file_size)r%   rv   Zsize_mbr(   r(   r)   rV  o  s   
z)CreativeFormatAdmin.max_file_size_displayzMax Sizec                 C   s6   |j rd|j dd t|j dkrd S d S dS )zDisplay supported file types.z, Nr   z...rT   r   )Zsupported_typesjoinlenr   r(   r(   r)   rW  w  s   ,z+CreativeFormatAdmin.supported_types_displayzSupported TypesN)r4   r5   r6   r7   r  r  r  rt   rU  r  rV  rW  r(   r(   r(   r)   rT  [  s    
rT  zAdtlas Creative ManagementzAdtlas Creative AdminzCreative Management Dashboard)Dr7   Zdjango.contribr   django.utils.htmlr   r   django.utilsr   django.urlsr   django.db.modelsr   r   r	   django.contrib.adminr
   django.httpr   django.shortcutsr   r   django.core.exceptionsr   r  r   r   r   modelsr   r   r   r   r   r   r   r   r   r   tasksr   r   r   r;   r>   rM   rW   r_   TabularInlinerj   r}   r   r   r   register
ModelAdminr   r  r(  r4  rA  rE  rN  rO  rT  sitesite_header
site_titleindex_titler(   r(   r(   r)   <module>   sd    "0	  l;).&$