
    G	/i}                        d dl mZ d dlmZ d dlmZm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mZmZmZmZmZ d d	lmZ d d
lmZ d dlmZ d dlmZ d dlmZ d dl m!Z! d d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l0m1Z1 d dl2m3Z3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9m:Z:m;Z;m<Z<m=Z=m>Z> d dl?m@Z@  G d d      ZAy)    )HTTPException)Session)Environment
BaseLoaderN)datetime)BytesIO)A4)SimpleDocTemplate	ParagraphSpacerTable
TableStyleImage)getSampleStyleSheet)colors)TblCategoriesUnderPromotions)TblCompetitorLoyalty)TblCompetitorPricingAnalysis)TblCustomerEngagement)TblPromotionCompetitorAnalysis)TblRecoveryOfPromotional) TblStoreFormatepricingStrategies)TblCategoryPricingStrategis)TblDefineYourPromotions)
TblSummary)TblGroup)SummaryCreate)CompetitorPricingAnalysisStoreFormatepricingStrategiesCategoryPricingStrategisDefineYourPromotionsPromotionalCalendarPromotionCompetitorAnalysisRecoveryOfPromotionalCategoriesUnderPromotionsCustomerEngagementCompetitorLoyaltySummaryModule6ReportPreview)JWTPayloadSchemac                   l    e Zd ZdedefdZdedefdZdedefdZ	dede
fd	Zdede
fd
Zdede
fdZy)Module6ReportServicedbtokenc                      || _         || _        y N)r-   r.   )selfr-   r.   s      F/var/www/html/retail-simulation-api/app/api/module_6_report/service.py__init__zModule6ReportService.__init__,   s    
    group_idreturnc                 @  K   |st        dd      | j                  j                  t              j	                  |      j                         xs9 | j                  j                  t              j	                  |      j                         xs | j                  j                  t              j	                  |      j                         xs | j                  j                  t              j	                  |      j                         xsy | j                  j                  t              j	                  |      j                         xs9 | j                  j                  t              j	                  |      j                         xs | j                  j                  t              j	                  |      j                         xs | j                  j                  t              j	                  |      j                         xs| | j                  j                  t              j	                  |      j                         xs= | j                  j                  t              j	                  |      j                         }|r| j                  j                  t              j	                  |      j                         }| j                  j                  t              j	                  |      j                         }| j                  j                  t              j	                  |      j                         }| j                  j                  t              j	                  |      j                         }| j                  j                  t              j	                  |      j                         }| j                  j                  t              j	                  |      j                         }| j                  j                  t              j	                  |      j                         }	| j                  j                  t              j	                  |      j                         }
| j                  j                  t              j	                  |      j                         }| j                  j                  t              j	                  |      j                         }t!        ||rt#        j$                  |      nt#        |      |r#|D cg c]  }t'        j$                  |       c}nt'        |      g|r#|D cg c]  }t)        j$                  |       c}nt)        |      g|rt+        j$                  |      nt+        |      t-        |      g|r|D cg c]  }t/        |j0                  |j2                  rt5        |j2                        ndt7        |dd       rt5        t7        |dd             ndt7        |dd       rt5        t7        |dd             ndd|j8                         c}nt/        |      g|rt;        j$                  |      nt;        |      |	rt=        j$                  |	      nt=        |      |
rt?        j$                  |
      nt?        |      |rtA        j$                  |      ntA        |      |rtC        j$                  |      ntC        |      tD        jF                  jI                         	      S | j                  j                  tJ              j	                  |      j                         }|rt!        |t#        |      t'        |      gt)        |      gt+        |      t-        |      gt/        |      gt;        |      t=        |      t?        |      tA        |      tC        |      tD        jF                  jI                         	      S t        d
d      c c}w c c}w c c}w w)Ni  zgroup_id is required)status_codedetail)r5   N/Ayour_store_typethroughout_the_year)promotion_idcompetitor_effortstop_promotion_typestop_categories_for_promotionsspillover_categoriesr5   )r5   competitor_pricing_analysisstore_format_pricing_strategiscategory_pricing_strategisdefine_your_promotions_strategypromotional_calendarpromotion_competitor_analysisrecovery_of_promotionalcategories_under_promotionscustomer_engagementcompetitor_loyaltysummarylast_updatedi  zGroup ID not found in database)&r   r-   queryr   	filter_byfirstr   r   r   r   r   r   r   r   r   allr)   r   model_validater   r    r!   r"   r#   r=   r>   strgetattrr5   r$   r%   r&   r'   r(   pd	Timestampnowr   )r1   r5   module_data_existscompetitor_pricingstore_formatscategory_pricingdefine_promopromo_analysisrecoverycategories_under
engagementloyalty_programrL   scpgroup_existss                    r2   _fetch_module6_dataz(Module6ReportService._fetch_module6_data0   s    C8NOO GGMM67AA8ATZZ\ 	KGGMM:;EExEX^^`	KGGMM56@@(@SYY[	K GGMM12<<h<OUUW	K GGMM89CCXCV\\^		K
 GGMM23==x=PVVX	K GGMM67AA8ATZZ\	K GGMM/0::H:MSSU	K GGMM./9989LRRT	K GGMM*%///BHHJ 	 !%/K!L!V!V`h!V!i!o!o!q GGMM*JKUU_gUhllnM#ww}}-HISS]eSfjjl77==)@AKKU]K^ddfL!WW]]+IJTT^fTgkkmNww}}%=>HHRZH[aacH#ww}}-IJTT^fTgmmo'<=GGQYGZ``bJ"ggmm,@AKKU]K^ddfOggmmJ/9989LRRTG'!l~,E,T,TUg,h  E^  hp  Eq |Iiv/wivde0M0\0\]^0_iv/w  Pm  w  P@  OA vF`p+q`p[\,D,S,STU,V`p+q  Me  ow  Mx  Lyeq0D0S0ST`0a  xL  V^  x_&98&L%M $  .	/  .! 0%&^^HIH\H\3q/C/C+DbgX_`actvzX{C;Ld0S,T  BGfmno  rG  IM  gNc'!EZ\`:a6b  TY-2!"  .	/ +Fx*X)YZb(=(L(LX(Vh}  HP  iQjz,E,T,TUe,f  AZ  dl  AmU_$6$E$Ej$Qew  BJ  fKXg#4#C#CO#Tm~  IQ  nR;B..w7YaHb\\--/- 4  77==2<<h<OUUWL+%0IS[0\4Q[c4d3e0HRZ0[/\4HRZ4[*=x*P)Q3NX`3a2b,A8,T0IS[0\(:H(M'8('K#X6!#!1!1!3 " $<\]]Y 0x+q	/s-   T``:``+A`.B`G`c                 @   K   | j                  |       d {   S 7 wr0   )rf   )r1   r5   s     r2   get_report_previewz'Module6ReportService.get_report_preview   s     --h7777s   datac                 j)   t               }t        |t        dddd      }t               }g }	 t	        ddd      }d|_        |j                  |       |j                  t        dd	             |d
   }d|_        |j                  t        d|             |j                  t        dd             |d   }d|_
        d	|_        |j                  t        d|d                |j                  t        dd	             t        d|      t        d|      gt        d|      t        t        |j                  j                  xs d      |      gt        d|      t        t        |j                  j                  xs d      |      gt        d|      t        t        |j                  j                   xs d      |      gt        d|      t        t        |j                  j"                  xs d      |      gt        d|      t        t        |j                  j$                  xs d      |      gg}	t'        |	      }
|
j)                  t+        ddddt,        j.                  fddddt,        j.                  fddd d!d"d#d$d%d&d'd(g             |j                  |
       |j                  t        dd             |j                  t        d)|d                |j                  t        dd	             t        d*|      t        d+|      t        d,|      t        d-|      g}|g}|j0                  D ]  }t        |j2                  xs d|      t        |j4                  xs d|      t        |j6                  xs d|      t        t        |j8                  xs d      |      g}|j                  |        t'        |d.      }|j)                  t+        ddddt,        j.                  fddddt,        j.                  fddd d!d"d#d$d%d&d'd(g             |j                  |       |j                  t        dd             |j                  t        d/|d                |j                  t        dd	             t        d0|      t        d+|      t        d-|      t        d,|      g}|g}|j:                  D ]  }t        |j<                  xs d|      t        |j>                  xs d|      t        t        |j8                  xs d      |      t        |j6                  xs d|      g}|j                  |        t'        |d.      }|j)                  t+        ddddt,        j.                  fddddt,        j.                  fddd d!d"d#d$d%d&d'd(g             |j                  |       |j                  t        dd             |j                  t        d1|d                |j                  t        dd	             t        d|      t        d|      gt        d|      t        t        |j@                  j                  xs d      |      gt        d2|      t        t        |j@                  jB                  xs d      |      gt        d3|      t        t        |j@                  jD                  xs d      |      gt        d4|      t        t        |j@                  jF                  xs d      |      gt        d5|      t        t        |j@                  jH                  xs d      |      gg}t'        |      }|j)                  t+        ddddt,        j.                  fddddt,        j.                  fddd d!d"d#d$d%d&d'd(g             |j                  |       |j                  t        dd             |j                  t        d6|d                |j                  t        dd	             t        d7|      t        d0|      t        d8|      t        d9|      t        d:|      t        d;|      g}|g}|jJ                  D ]  }t        |jL                  xs d|      t        |j<                  xs d|      t        |jN                  xs d|      t        |jP                  xs d|      t        |jR                  xs d|      t        |jT                  xs d|      g}|j                  |        t'        |d.      }|j)                  t+        ddddt,        j.                  fddddt,        j.                  fdd<d d=d"d#d$d%d&d'd(g             |j                  |       |j                  t        dd             |j                  t        d>|d                |j                  t        dd	             t        d?|      t        d@|      t        dA|      t        dB|      g}|g}|jV                  D ]y  }t        |jX                  xs d|      t        |jZ                  xs d|      t        |j\                  xs d|      t        |j^                  xs d|      g}|j                  |       { t'        |d.      }|j)                  t+        ddddt,        j.                  fddddt,        j.                  fddd d!d"d#d$d%d&d'd(g             |j                  |       |j                  t        dd             |j                  t        dC|d                |j                  t        dd	             t        d|      t        d|      gt        dD|      t        t        |j`                  jb                  xs d      |      gt        dE|      t        t        |j`                  jd                  xs dF      |      gt        dG|      t        t        |j`                  jf                  xs d      |      gg}t'        |      }|j)                  t+        ddddt,        j.                  fddddt,        j.                  fddd d!d"d#d$d%d&d'd(g             |j                  |       |j                  t        dd             |j                  t        dH|d                |j                  t        dd	             t        d|      t        d|      gt        dI|      t        t        |jh                  jj                  xs i       |      gg} t'        |       }!|!j)                  t+        ddddt,        j.                  fddddt,        j.                  fddd d!d"d#d$d%d&d'd(g             |j                  |!       |j                  t        dd             |j                  t        dJ|d                |j                  t        dd	             t        d|      t        d|      gt        dK|      t        t        |jl                  jn                  xs d      |      gt        dL|      t        t        |jl                  jp                  xs d      |      gg}"t'        |"      }#|#j)                  t+        ddddt,        j.                  fddddt,        j.                  fddd d!d"d#d$d%d&d'd(g             |j                  |#       |j                  t        dd             |j                  t        dM|d                |j                  t        dd	             t        d|      t        d|      gt        d|      t        t        |jr                  j                  xs d      |      gt        dN|      t        t        |jr                  jt                  xs d      |      gt        dO|      t        t        |jr                  jv                  xs d      |      gt        dP|      t        t        |jr                  jx                  xs d      |      gt        dQ|      t        t        |jr                  jz                  xs d      |      gt        dR|      t        t        |jr                  j|                  xs d      |      gt        dS|      t        t        |jr                  j~                  xs d      |      gt        dT|      t        t        |jr                  j                  xs dF      |      gt        dU|      t        t        |jr                  j                  xs d      |      gt        dV|      t        t        |jr                  j                  xs d      |      gt        dW|      t        t        |jr                  j                  xs d      |      gt        dX|      t        t        |jr                  j                  xs d      |      gg}$t'        |$      }%|%j)                  t+        ddddt,        j.                  fddddt,        j.                  fddd d!d"d#d$d%d&d'd(g             |j                  |%       |j                  t        dd             |j                  t        dY|d                |j                  t        dd	             t        d|      t        d|      gt        dK|      t        t        |j                  jn                  xs d      |      gt        dL|      t        t        |j                  jp                  xs d      |      gg}&t'        |&      }'|'j)                  t+        ddddt,        j.                  fddddt,        j.                  fddd d!d"d#d$d%d&d'd(g             |j                  |'       |j                  t        dd             |j                  t        dd	             |j                  t        dZ|j                  j                  d[       |d                |j                  |       |j                  dF       t        j                         j                  d\      }(d]|j                   d^|( d_})d`|) }*t        j                  t        j                  j                  |*      dab       t        |*dc      5 }+|+j                  |j                                dddddd       t        j                  j                  de|)      S #  Y 8xY w# 1 sw Y   1xY w)fz(Generate PDF report and return file path2   )pagesize
leftMarginrightMargin	topMarginbottomMarginzTS Logo.png   K   )widthheightLEFT   
   Titlez(Module 7: Marketing &amp; Communications   Normal   zMarketing PlanHeading2z<b>Field</b>z<b>Value</b>zReference Competitorr:   zPricing Strategyz$Which Category Generates Most IncomezKey Observation Around PricingzOther RemarksGRIDr   r   r   g      ?BOX)FONTNAMEr~   r   r   zHelvetica-Bold)FONTSIZEr~   r   r{   )r   r   rv   r   	Helvetica)r   r   r   r{   )LEFTPADDINGr~   r      )RIGHTPADDINGr~   r   r   )
TOPPADDINGr~   r   r   )BOTTOMPADDINGr~   r   r   )VALIGNr~   r   TOP)ALIGNr~   r   ru   )WORDWRAPr~   r   TzIntegrated Marketing ActivitieszStore Format<br/>TypezPricing<br/>StrategiesRationalzOther<br/>Strategy)
repeatRowszBrand JourneyCategoryz!Marketing Communications StrategyzOngoing Key PromotionszAmong Key Various PromotionzWhat Are The Same KeyzOther RemarkzPromotional CalendarMonthzType of<br/>PromotionzSuccess<br/>Metric	ObjectiveRemarks)r   r~   r      )r   r   r   r   zPromotion Competitor AnalysiszCompetitor<br/>EffortszTop Promotion<br/>Typesz!Top Categories<br/>for PromotionszSpillover<br/>CategorieszRecovery of PromotionalzBased UnderstandingzWhat Percentager   zWhat CategoryzCategories Under PromotionszOn Which CategoryzCustomer EngagementzPromotions SubmissionszPromotions SummarisezCompetitor LoyaltyzDo They Have Loyalty ProgramzLoyalty Program TypezKey Observations LoyaltyzIs It Useful For StorezWant Loyalty ProgramzDescribe Loyalty ProgramzBudget AllocatedzBenefits of Loyalty ProgramzPerils of Loyalty ProgramzDifference From CompetitorzOther Notesr(   zLast Updated: z%Y-%m-%d %H:%M:%Sz%Y%m%d_%H%M%Smodule6_complete_report_group__z.pdfzuploaded_files/T)exist_okwbNuploaded_files)Ur   r
   r	   r   r   hAlignappendr   	alignmentr   fontSizeleadingrS   rB   reference_competitorpricing_strategy6which_category_generates_the_most_income_for_the_store+key_observation_around_pricing_in_the_storeother_remarksr   setStyler   r   blackrC   store_format_typechoose_a_pricing_strategiesrationalspecify_other_strategyrD   categorypricing_strategisrE   ongoing_key_promotionsamoung_key_variouse_promotionwhat_are_the_same_keyother_remarkrF   monthtype_of_promotionsuccess_metric	objectiveremarksrG   r>   r?   r@   rA   rH   based_unterstandingwhat_percentagewhat_categoryrI   on_which_categoryrJ   promotions_submissionspromotions_summariserK   do_they_have_a_loyalty_programloyalty_program_typekey_observations_loyaltyis_it_useful_for_storewant_loyalty_programdescribe_loyalty_programbudget_allocatedbenefits_of_loyalty_programperils_of_loyalty_programdifference_from_competitorother_notesrL   rM   strftimebuildseekr   rW   r5   osmakedirspathdirnameopenwritegetvaluejoin),r1   ri   bufferdocstylesstorylogotitle_stylenormal_stylepricing_datapricing_tablestore_headers
store_rowsstorerowstore_tablecategory_headerscategory_rowsr   category_table
promo_datapromo_tablecalendar_headerscalendar_rowscalendarcalendar_tablecomp_analysis_headerscomp_analysis_rowscompcomp_analysis_tablerecovery_datarecovery_tablecategories_datacategories_tableengagement_dataengagement_tableloyalty_dataloyalty_tablesummary_datasummary_table	timestampfilenamefilepathfs,                                               r2   _generate_pdf_reportz)Module6ReportService._generate_pdf_report   s   PR^`oqr$&	c"=D DKLLLL2'
 Wo !YI;WXVAr]#h' !! 	Y/
1CDEVAr]# ~|4iP\6]^-|<iDLlLl  MB  MB  MK  FK  IL  NZ  ?[  \)<8)CHhHhHyHy  IC  ~C  ED  FR  ;S  T=|LiX[\`\|\|  ]t  ]t  ]}  x}  Y~  @L  OM  N7F	RUVZVvVv  Wc  Wc  Wl  gl  Sm  o{  I|  }5yTEeEeEsEsE|w|A}  @L  8M  N
 l+zVXsFLL9FHa6;,7-01/2//0+
   	  	]#VAr]# 	Y@&BTUVVAr]# -|<.=j,/*L9	
 $_
88E%11:ULI%;;DulS%..1E<@#e::CeDlS	C c" 9 J15ZVXsFLL9FHa6;,7-01/2//0)
  	  	[!VAr]# 	Yz0BCDVAr]# j,/.=*L9j,/	
 **77H(++4ulC(44=|L#h==FGV(++4ulC	C   % 8 };
VXsFLL9FHa6;,7-01/2//0,
 ! 	  	^$VAr]# 	YBF:DVWXVAr]# ~|4iP\6]^-|<iDLpLp  MF  MF  MO  JO  IP  R^  ?_  `/>	#dNrNr  OJ  OJ  OS  NS  KT  Vb  Ac  d4lCYsSWSwSw  TV  TV  T_  Z_  P`  bn  Fo  p.=yTMqMq  NH  NH  NQ  LQ  JR  T`  @a  b~|4iDDhDhDuDuD~y~@  BN  7O  P

 J'ZVXsFLL9FHa6;,7-01/2//0)
  	  	[!VAr]# 	Y5vj7IJKVAr]# g|,j,/-|<*L9k<0i.
 **11H(..1E<@(++4ulC(44=|L(11:ULI(,,5|D(**3e\BC   % 2 };
VXsFLL9FHa6;,7-01/2//0,
 ! 	  	^$VAr]# 	Y>z@RSTVAr]# .=/>9<H0,?	!
 4466D$11:ULI$22;e\J$<<E|T$33<ulK	C %%c* 7 $$61E$$ZVXsFLL9FHa6;,7-01/2//01
 & 	  	()VAr]# 	Y8&:LMNVAr]# ~|4iP\6]^,l;Ys4KgKgK{K{  LE  @E  HF  HT  >U  V(,73tGcGcGsGsGxwxCy  |H  :I  J5yTEaEaEoEoExsxAy  |H  8I  J	
 }-
VXsFLL9FHa6;,7-01/2//0,
 ! 	  	^$VAr]# 	Y<fZ>PQRVAr]# ~|4iP\6]^*L99SIiIiI{I{  JB  @B  FC  EQ  <R  S

 !1!!*VXsFLL9FHa6;,7-01/2//0.
 # 	  	%&VAr]# 	Y4fZ6HIJVAr]# ~|4iP\6]^/>	#dNfNfN}N}  OG  BG  KH  JV  AW  X-|<iDLdLdLyLy  MC  ~C  ID  FR  ?S  T
 !1!!*VXsFLL9FHa6;,7-01/2//0.
 # 	  	%&VAr]# 	Y3VJ5GHIVAr]# ~|4iP\6]^-|<iDLcLcLxLx  MB  }B  IC  EQ  ?R  S5|DiPSTXTkTk  UK  UK  UT  OT  QU  Wc  Gd  e-|<iDLcLcLxLx  MB  }B  IC  EQ  ?R  S1<@)CPTPgPg  QA  QA  QJ  EJ  MK  MY  CZ  [/>	#dNeNeN|N|  OF  AF  KG  IU  AV  W-|<iDLcLcLxLx  MB  }B  IC  EQ  ?R  S1<@)CPTPgPg  QA  QA  QJ  EJ  MK  MY  CZ  [)<8)CH_H_HpHpHutuDv  yE  ;F  G4lCYsSWSjSj  TG  TG  TP  KP  PQ  S_  F`  a2LA9SQUQhQh  RC  RC  RL  GL  NM  O[  D\  ]3\BIcRVRiRi  SE  SE  SN  IN  OO  Q]  E^  _}l3Ys4CZCZCfCfCojo?pr~5  A
  l+zVXsFLL9FHa6;,7-01/2//0+
   	  	]#VAr]# 	Yy&*<=>VAr]# ~|4iP\6]^/>	#dllNqNqNzuzJ{  ~J  AK  L-|<iDLLLmLmLvqvHw  zF  ?G  H
 l+zVXsFLL9FHa6;,7-01/2//0+
   	  	]#VAr]# 	VAr]#Y0A0A0J0JK^0_/`acijrcstu		%A LLN++O<	3DMM?!I;dS$XJ/
BGGOOH-=(D!QGGFOO%& " ww||,h77O	F "!s   AAR! Q AR)R!AR&R)AR2c                    K   | j                  |       d{   }| j                  |      }| j                  ||       |S 7 )w)z3Generate PDF and save to database, return file pathN)rf   r   _save_file_path_to_db)r1   r5   report_data	file_paths       r2   generate_and_save_pdfz*Module6ReportService.generate_and_save_pdf9  sD      44X>>--k:	""8Y7 ?s   AA*Ar   c                    	 d| d}t        d|        | j                  j                  t              j	                  t        j
                  |k(        j                         }|rSt        d       ||_        | j                  j                          | j                  j                  |       t        d       yt        d       t        |||      }| j                  j                  |       | j                  j                          | j                  j                  |       t        d|j                          y# t        $ rF}| j                  j                          t        d	|        d
dl}|j                          Y d}~yd}~ww xY w)z;Save or update file path in summary table with group_id_modg_m6z6DEBUG: Looking for existing record with group_id_mod: z5DEBUG: Found existing record, updating uploaded_filesz"DEBUG: Updated record successfullyz1DEBUG: No existing record found, creating new one)r5   group_id_modr   z+DEBUG: Created new record with summary_id: z$ERROR saving file path to database: r   N)printr-   rN   r   filterr  rP   r   commitrefreshadd
summary_id	Exceptionrollback	traceback	print_exc)r1   r5   r   r  existing_summarynew_summaryer  s           r2   r   z*Module6ReportService._save_file_path_to_db@  s:   	"xj,LJ<.YZ#ww}}Z8??
@W@W[g@ghnnpMO2; /  01:<IK(%!-#,
 K( ,CKDZDZC[\] 	"GG8<=!!		"s   B5D: 8BD: :	F	<FF	N)__name__
__module____qualname__r   r*   r3   intr)   rf   rh   rS   r   r  r    r4   r2   r,   r,   +   s    7 +; N^# N^:N N^`8 89M 8t8)= t8# t8lC C "c "c "r4   r,   )Bfastapir   sqlalchemy.ormr   jinja2r   r   pandasrU   r   r   ior   reportlab.lib.pagesizesr	   reportlab.platypusr
   r   r   r   r   r   reportlab.lib.stylesr   reportlab.libr   +app.models.main.categories_under_promotionsr   *app.models.main.competitor_loyalty_programr   +app.models.main.competitor_pricing_analysisr   .app.models.main.customer_engagement_strategiesr   -app.models.main.promotion_competitor_analysisr   'app.models.main.recovery_of_promotionalr   0app.models.main.store_formate_pricing_strategiesr   *app.models.main.category_pricing_strategisr   /app.models.main.define_your_promotions_strategyr   app.models.main.summaryr   app.models.main.groupr   app.api.summary.schemar   app.api.module_6_report.schemar   r   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   app.dependency.authanticationr*   r,   r  r4   r2   <module>r/     sr    ! " *  	   & ] ] 4   T K T P X L ] R S . * 0    ;q" q"r4   