Ë
    +,ÇjP0  ã                   ó  — d Z ddlZddlZddlZddlZddlZddlZddlZddlZddl	Z	ddl
Z
ddlZddlZddlZddlZddlmZ ddlmZ dZdZdZ ej,                  d«      Zd	Zd
„ Zd„ Zdd„Zd„ Zd„ Zd„ Zd„ Zd„ Z e!dk(  r e «        yy)uÒ  
Hosted Checkout page-open load test: CloudLayer (4056) -> MastercardSimulator.

Opens N Hosted Checkout payment pages at the same moment, one per BULKTEST
merchant, exactly as a merchant server + payer browser would â€” and stops
before paying:

  1. POST /pgpayments/pay/init         X-Merchant-Id / X-Public-Key / X-Checksum
  2. GET  <payment_url>                CloudLayer runs INITIATE_CHECKOUT and
                                       returns the checkout page (session id)
  3. GET  simulator /static/checkout/session/<id>/context
                                       what checkout.min.js fetches in the browser

Two subcommands:

  prepare  Reads the bulk merchants' public/secret keys from MySQL (read-only)
           and writes a CSV of merchant_ref, public_key and the checksum for
           one fixed amount. The secret keys never leave memory.

             MYSQL_PWD=... python3 scripts/hosted_checkout_load_test.py prepare

  run      Opens pages in stages, e.g. 10, 50, 100 at once.

             python3 scripts/hosted_checkout_load_test.py run --stages 10,50,100

Every page opened creates a PENDING pg_transactions row for that bulk merchant,
which CloudLayer later marks EXPIRED (nobody pays). Stdlib only.
é    N)ÚThreadPoolExecutor)Údatetimez*/home/priyanka/bulk_checkout_merchants.csvzhttp://localhost:4056zhttp://localhost:4444zsession:\s*\{\s*id:\s*'([^']+)'a�  
SELECT c.user_id, c.merchant_id, m.merchant_refrence_number, u.public_key, u.secret_key
  FROM shukria_transactions.mpgs_merchant_credentials c
  JOIN shukria_mms_demo_local.users u         ON u.id = c.user_id
  JOIN shukria_mms_demo_local.user_metadata m ON m.user_id = c.user_id
 WHERE c.merchant_id LIKE 'BULKTEST%'
   AND c.method = 'hosted-checkout'
   AND c.active = 1
 ORDER BY c.merchant_id
c                 ó´   — |› d|› d|› �}t        j                  | j                  «       |j                  «       t        j                  «      j                  «       S )Nú|)ÚhmacÚnewÚencodeÚhashlibÚsha256Ú	hexdigest)Ú
secret_keyÚmerchant_refÚ
public_keyÚamountÚsources        ú$scripts/hosted_checkout_load_test.pyÚchecksumr   C   sG   € àˆ~˜Q˜z˜l¨!¨F¨8Ð4€FÜ�8‰8�J×%Ñ%Ó'¨¯©«¼'¿.¹.ÓI×SÑSÓUÐUó    c                 ó  — dt         j                  vrt        j                  d«       t         j                  j                  | j                  «      r"t        j                  | j                  › d�«       t        | j                  «      d›}t        j                  dd| j                  d| j                  dd	d
t        g	ddd¬«      }|j                  dk7  r0t        j                  d|j                  j!                  «       › �«       g }|j"                  j%                  «       D ]=  }|j'                  d«      \  }}}}}	|j)                  |||||t+        |	|||«      dœ«       Œ? |st        j                  d«       t        j,                  | j                  t         j.                  t         j0                  z  t         j2                  z  d«      }
t        j4                  |
dd¬«      5 }t7        j8                  |t;        |d   j=                  «       «      ¬«      }|j?                  «        |jA                  |«       d d d «       tC        dtE        |«      › d|d   d   › d|d   d   › d|› d| j                  › d�«       y # 1 sw Y   ŒDxY w) NÚ	MYSQL_PWDzJSet MYSQL_PWD (the MySQL password from CloudLayer's config/dev.exs) first.uA    already exists â€” delete it first if you want to regenerate it.z.2fÚmysqlz-uz-hz-Nz-Bz-eTF)Úcapture_outputÚtextÚcheckr   zmysql failed: ú	)Úuser_idÚmerchant_idr   r   r   r   z3No active hosted-checkout BULKTEST merchants found.i€  ÚwÚ ©Únewline©Ú
fieldnameszWrote z merchants (r   z..éÿÿÿÿz) for amount z to z (mode 600))#ÚosÚenvironÚsysÚexitÚpathÚexistsÚoutÚfloatr   Ú
subprocessÚrunÚdb_userÚdb_hostÚMERCHANT_QUERYÚ
returncodeÚstderrÚstripÚstdoutÚ
splitlinesÚsplitÚappendr   ÚopenÚO_WRONLYÚO_CREATÚO_EXCLÚfdopenÚcsvÚ
DictWriterÚlistÚkeysÚwriteheaderÚ	writerowsÚprintÚlen)Úargsr   ÚresultÚrowsÚliner   r   Úrefr   r   ÚfdÚfr   s                r   ÚpreparerM   I   s  € Øœ"Ÿ*™*Ñ$Ü�‰Ð]Ô^Ü	‡w�w‡~�~�d—h‘hÔÜ�‰�D—H‘H�:Ð^Ð_Ô`ä�d—k‘kÓ" 3Ð'€FÜ�^‰^Ø	�$˜Ÿ™ d¨D¯L©L¸$ÀÀdÌNÐ[Ø $¨eô€Fð ×Ñ˜AÒÜ�‰�> &§-¡-×"5Ñ"5Ó"7Ð!8Ð9Ô:à€DØ—‘×(Ñ(Ó*ò 	ˆØ<@¿J¹JÀtÓ<LÑ9ˆ�˜c :¨zØ�‰ØØ&ØØ$ØÜ  ¨S°*¸fÓEñ
õ 	ð	ñ Ü�‰ÐFÔGä	�‰�—‘œ2Ÿ;™;¬¯©Ñ3´b·i±iÑ?ÀÓ	G€BÜ	�‰�2�s BÔ	'ð ¨1Ü�N‰N˜1¬¨d°1©g¯l©l«nÓ)=Ô>ˆØ	�‰ŒØ	�‰�DÔ÷ô
 
ˆF”3�t“9�+˜\¨$¨q©'°-Ñ*@Ð)AÀÀDÈÁHÈ]ÑD[ÐC\ð ]Ø�x˜t D§H¡H :¨[ð:õ ;÷ð ús   ÇAI5É5I>c                 ó$  — |�#t        j                  |«      j                  «       nd }t        j                  j                  ||| ¬«      }|xs i j                  «       D ]  \  }}|j                  ||«       Œ 	 t        j                  j                  ||¬«      5 }	|	j                  |	j                  «       fcd d d «       S # 1 sw Y   y xY w# t        j                  j                  $ r&}
|
j                  |
j                  «       fcY d }
~
S d }
~
ww xY w)N)ÚdataÚmethod©Útimeout)ÚjsonÚdumpsr	   ÚurllibÚrequestÚRequestÚitemsÚ
add_headerÚurlopenÚstatusÚreadÚerrorÚ	HTTPErrorÚcode)rP   ÚurlÚbodyÚheadersrR   rO   ÚreqÚkÚvÚrÚes              r   Úhttprh   r   sÜ   € Ø(,Ð(8Œ4�:‰:�dÓ×"Ñ"Ô$¸d€DÜ
�.‰.×
 Ñ
  ¨4¸Ð
 Ó
?€CØ’˜B×%Ñ%Ó'ò ‰ˆˆ1Ø�‰�q˜!Õðð Ü�^‰^×#Ñ# C°Ð#Ó9ð 	&¸QØ—8‘8˜QŸV™V›XÐ%÷	&÷ 	&ò 	&ûä�<‰<×!Ñ!ò  Ø�v‰v�q—v‘v“xÐÕûð ús<   Á9!C ÂC Â6	C Ã C	ÃC Ã	C ÃDÃ)D
ÄDÄ
Dc                 ó˜  — d|› d|› d|d   › �}||d   |ddddddddddœ}|j                  «        t        j                  «       }d	}	 t        j                  «       }	t        d
| j                  dz   |d   | j
                  |dddœd|d   |d   |d   dœ| j                  «      \  }
}t        j                  «       |	z
  dz  |d<   |
dk(  rt        j                  |xs d«      ni }|
dk7  s%|j                  d«      dk7  s|j                  d«      s?|j                  |
|j                  d«      xs |d d j                  d¬«      ¬«       t        ‚d }t        j                  «       }	t        d!| j                  |d   z   | j                  ¬"«      \  }
}t        j                  «       |	z
  dz  |d#<   |
dk(  r%t        j                  |j                  d¬«      «      nd }|s |j                  |
|
dk(  rd$nd¬«       t        ‚|j                  d%«      |d&<   d'}t        j                  «       }	t        d!| j                   › d(|d&   › d)�| j                  ¬"«      \  }
}t        j                  «       |	z
  dz  |d*<   |
dk(  rt        j                  |xs d«      ni }|
dk7  s|j                  d+«      s|j                  |
d,¬«       t        ‚d-|d.<   t        j                  «       |z
  dz  |d3<   d4D ]  }t)        ||   d%«      ||<   Œ |S # t        $ r ||d/<   Y ŒHt"        $ r8}|j                  |t%        |«      j&                  › d0|› �d d1 ¬2«       Y d }~Œƒd }~ww xY w)5NÚHCz-Sú-r   Fr   ç        )Ústager   Úorder_idÚokÚfailed_steprh   r]   Ú
session_idÚinit_msÚpage_msÚ
context_msÚtotal_msÚinitÚPOSTz/pgpayments/pay/initr   z	Load Testzloadtest@example.com)r   Úcurrencyrn   Úcustomer_nameÚemailzapplication/jsonr   r   r   )zContent-TypezX-Merchant-IdzX-Public-Keyz
X-Checksumiè  rr   éÈ   s   {}ÚflowÚmpgsÚpayment_urléd   Úreplace)Úerrors)rh   r]   ÚpageÚGETrQ   rs   zno session id in pageé   rq   Úcontextz/static/checkout/session/z/contextrt   ÚsuccessIndicatorz no checkout context at simulatorTro   rp   ú: éx   )rp   r]   ru   )rr   rs   rt   ru   )ÚwaitÚtimeÚperf_counterrh   Úbaserx   rR   rS   ÚloadsÚgetÚupdateÚdecodeÚRuntimeErrorÚ
SESSION_REÚsearchÚgroupÚsimÚ	ExceptionÚtypeÚ__name__Úround)rF   ÚmerchantÚrun_idrm   Úbarrierrn   ÚresÚt0ÚstepÚtr[   ÚrawrO   ÚhtmlÚmatchÚctxrg   rd   s                     r   Ú	open_pager¥   ~   sn  € Ø�F�8˜2˜e˜W A h¨}Ñ&=Ð%>Ð?€HØ¨(°=Ñ*AÈxØ r°2ÀÐRTØ c¸È#ñO€Cð ‡L�L„NÜ	×	Ñ	Ó	€BØ€Dð/Mä×ÑÓˆÜ˜6 4§9¡9Ð/EÑ#EØ˜xÑ(ØŸ™Ø Ø(Ø+ñH
ð /Ø% nÑ5Ø$ \Ñ2Ø" :Ñ.ñ	
ð
 �<‰<ó‰ˆ�ô ×+Ñ+Ó-°Ñ1°TÑ9ˆˆI‰Ø+1°Sª=Œt�z‰z˜#š, Ô'¸bˆØ�SŠ=˜DŸH™H VÓ,°Ò6¸d¿h¹hÀ}Ô>UØ�J‰J˜F¨4¯8©8°FÓ+;Ò+a¸sÀ4ÀC¸y×?OÑ?OÐW`Ð?OÓ?aˆJÔcÜÐð ˆÜ×ÑÓˆÜ˜E 4§9¡9¨t°MÑ/BÑ#BÈDÏLÉLÔY‰ˆ�Ü×+Ñ+Ó-°Ñ1°TÑ9ˆˆI‰ØDJÈcÂM”
×!Ñ! $§+¡+°Y +Ó"?Ô@ÐW[ˆÙØ�J‰J˜FÀVÈsÂ]Ñ*AÐXZˆJÔ[ÜÐØ!ŸK™K¨›NˆˆLÑð ˆÜ×ÑÓˆÜ˜5 T§X¡X JÐ.GÈÈLÑHYÐGZÐZbÐ"cØ#'§<¡<ô1‰ˆ�ä!×.Ñ.Ó0°1Ñ4¸Ñ<ˆˆLÑØ*0°Cª-Œd�j‰j˜š Ô&¸RˆØ�SŠ= §¡Ð(:Ô ;Ø�J‰J˜FÐ*LˆJÔMÜÐàˆˆD‰	ô ×(Ñ(Ó*¨RÑ/°4Ñ7€Cˆ
�OØ=ò "ˆÜ�s˜1‘v˜qÓ!ˆˆAŠð"à€Jøô ò "Ø!ˆˆMÓÜò MØ�
‰
˜t¬d°1«g×.>Ñ.>Ð-?¸rÀ!ÀÐ+EÀdÀsÐ+Kˆ
×LÑLûðMús   ÁI9K9 Ë9M	Ì	M	Ì.MÍM	c                 óœ   — | syt        | «      } | t        t        | «      dz
  t        t	        |dz  t        | «      dz
  z  «      «      «         S )Nrl   r„   r   )ÚsortedÚminrE   Úintr™   )ÚvaluesÚqs     r   Úpctr¬   ¾   sF   € ÙØÜ�F‹^€FØ”#”c˜&“k A‘o¤s¬5°°S±¼CÀ»KÈ!¹OÑ1LÓ+MÓ'NÓOÑPÐPr   c                 ó’  — |D �cg c]
  }|d   sŒ	|‘Œ }}|D �cg c]
  }|d   rŒ	|‘Œ }}t        d| › dt        |«      › d�«       t        dt        |«      › dt        |«      › �«       dD ]i  \  }}|D �cg c]  }||   ‘Œ	 }}|sŒt        d|d	›d
t        |d«      d›dt        |d«      d›dt        |«      d›dt	        j
                  |«      d›�
«       Œk t        d|d›dt        |«      |z  d›d�«       |r¶i }	|D ]P  }d|d   › d|d   xs d› d|d   xs d› �j                  «       }|	j                  |g «      j                  |d   «       ŒR t        d«       t        |	j                  «       d„ ¬ «      D ]5  \  }}
t        d!t        |
«      d"›d#|› d$d%j                  |
d d& «      › �«       Œ7 t        |«      S c c}w c c}w c c}w )'Nro   u   
â”€â”€ Stage r‡   u    pages opened at once â”€â”€z  pages ok     z  |  failed ))Útotalru   )rv   rr   )r‚   rs   )r…   rt   z  z<8z	 ms  p50 é2   ú.0fz  p95 é_   z  max z  mean z  wall time    z.1fzs  ->  z pages/szstep=rp   z http=rh   rk   ú r]   r   r   z  failures:c                 ó    — t        | d   «       S )Nr„   )rE   )Úkvs    r   ú<lambda>zsummarise.<locals>.<lambda>Ø   s   € ÄÀBÀqÁEÃ
¸{€ r   ©Úkeyz    z>4u    Ã— z   e.g. z, é   )rD   rE   r¬   ÚmaxÚ
statisticsÚmeanr4   Ú
setdefaultr8   r§   rX   Újoin)rm   ÚresultsÚwallrf   ro   ÚfailedÚlabelr·   ÚvalsÚgroupsÚmidss              r   Ú	summariserÅ   Å   s  € ØÖ	(�  $£Š!Ð	(€BÐ	(Ø Ö0�A¨¨$«ŠaÐ0€FÐ0ä	ˆO˜E˜7 "¤S¨£\ NÐ2NÐ
OÔPÜ	ˆOœC ›G˜9 L´°V³°Ð
>Ô?Ørò L‰
ˆˆsØ "Ö#˜1��#“Ð#ˆÐ#ÚÜ�B�u˜R�j 	¬#¨d°B«-¸Ð)<¸FÄ3ÀtÈRÃ=ÐQTÐBUð VÜ˜T› 3˜ w¬z¯©¸tÓ/DÀSÐ.IðKõ LðLô
 
ˆO˜D ˜: W¬S°«\¸DÑ-@ÀÐ,EÀXÐ
NÔOáØˆØò 	@ˆAØ˜!˜MÑ*Ð+¨6°!°F±)Ò2B¸sÐ1CÀ1ÀQÀwÁZÒEUÐSUÐDVÐW×]Ñ]Ó_ˆCØ×Ñ˜c 2Ó&×-Ñ-¨a°Ñ.>Õ?ð	@ô 	ˆmÔÜ §¡£Ñ4JÔKò 	O‰IˆC�Ü�Dœ˜T› 2˜ d¨3¨%¨x¸¿	¹	À$ÀrÈÀ(Ó8KÐ7LÐMÕNð	Oäˆv‹;Ðùò) 
)ùÚ0ùò
 $s   …
F:�F:š
F?¥F?Á5Gc                 óB  ‡ ‡‡‡— ‰ j                   j                  d«      D �cg c]  }|j                  «       sŒt        |«      ‘Œ  }}t	        ‰ j
                  d¬«      5 }t        t        j                  |«      d„ ¬«      }d d d «       t        |«      t        «      kD  r;t        j                  dt        |«      › d‰ j
                  › dt        |«      › d	�«       t        d
‰ j                  › d�«       t        d‰ j                  › �«       t        dt        |«      › d‰ j
                  › d|d   d   › d‰ j                   › d�	«       t        d|› dt#        |«      › d‰ j$                  d›d�«       t        d«       ‰ j&                  s?t)        d«      j                  «       j+                  «       dk7  rt        j                  d«       t-        j.                  «       j1                  d«      Š‰ j2                  xs d‰› d�}g }t5        |«      D �]Z  \  }Št7        j8                  ‰«      Št;        j<                  «       }t?        ‰¬ «      5 }	tA        |	jC                  ˆ ˆˆˆfd!„|d ‰ «      «      }
d d d «       t;        j<                  «       |z
  }|jE                  
«       tG        ‰|
|«      }t	        |d"d¬«      5 }t        jH                  |tA        |d   jK                  «       «      ¬#«      }|jM                  «        |jO                  |«       d d d «       |r ‰ jP                  rt        d$‰› d%|› d&�«        n5|t        |«      d'z
  k  s�Œ<t;        jR                  ‰ j$                  «       �Œ] t        d(|› �«       y c c}w # 1 sw Y   �ŒýxY w# 1 sw Y   �Œ xY w# 1 sw Y   ŒŽxY w))Nú,r   r    c                 ó   — | d   S )Nr   © )rf   s    r   rµ   zrun.<locals>.<lambda>à   s   € ¸A¸mÑ<L€ r   r¶   zLargest stage is z but z has z
 merchantszCloudLayer : z"/pgpayments/pay/init -> /pay/startzSimulator  : zMerchants  : z in z	 (amount r   r   r²   ú)zStages     : z  (z pages in total, r°   zs pause between stages)zYEvery page creates a PENDING pg_transactions row for a BULKTEST merchant (later EXPIRED).zProceed? [y/N] ÚyzAborted.z
%m%d%H%M%SÚcheckout_results_z.csv)Úmax_workersc                 ó"   •— t        ‰| ‰‰‰«      S )N)r¥   )ÚmrF   rœ   r›   rm   s    €€€€r   rµ   zrun.<locals>.<lambda>ö   s   ø€ ¬i¸¸aÀÈÐPWÓ.X€ r   r   r"   z
Stopping: stage z had z failed pages (--stop-on-fail).r„   z
Per-page results: )*Ústagesr7   r4   r©   r9   Ú	merchantsr§   r>   Ú
DictReaderr¹   rE   r'   r(   rD   rŒ   r•   rx   ÚsumÚpauseÚyesÚinputÚlowerr   ÚnowÚstrftimer+   Ú	enumerateÚ	threadingÚBarrierrŠ   r‹   r   r@   ÚmapÚextendrÅ   r?   rA   rB   rC   Ústop_on_failÚsleep)rF   ÚsrÐ   rL   rÑ   r+   Úall_resultsÚirž   Úpoolr¾   r¿   Úfailuresr   rœ   r›   rm   s   `             @@@r   r.   r.   Ý   s  û€ Ø"Ÿk™k×/Ñ/°Ó4ÖB˜¸¿¹½	Œc�!�fÐB€FÐBÜ	ˆd�n‰n bÔ	)ð N¨QÜœ3Ÿ>™>¨!Ó,Ñ2LÔMˆ	÷Nô ˆ6ƒ{”S˜“^Ò#Ü�‰Ð$¤S¨£[ M°°t·~±~Ð6FÀeÌCÐPYËNÐK[Ð[eÐfÔgä	ˆM˜$Ÿ)™)˜Ð$FÐ
GÔHÜ	ˆM˜$Ÿ(™(˜Ð
$Ô%Ü	ˆMœ#˜i›.Ð)¨¨d¯n©nÐ-=¸YÀyÐQRÁ|ÐT\ÑG]ÐF^Ð^_Ð`d×`mÑ`mÐ_nÐnoÐ
pÔqÜ	ˆM˜&˜ ¤S¨£[ MÐ1BÀ4Ç:Á:ÈcÐBRÐRiÐ
jÔkÜ	Ð
eÔfà�8Š8œÐ/Ó0×6Ñ6Ó8×>Ñ>Ó@ÀCÒGÜ�‰�Ôä�\‰\‹^×$Ñ$ \Ó2€FØ
�(‰(Ò
6Ð)¨&¨°Ð6€CØ€Kä˜fÓ%ó #‰ˆˆ5Ü×#Ñ# EÓ*ˆÜ×ÑÓ ˆÜ¨EÔ2ð 	n°dÜ˜4Ÿ8™8Ö$XÐZcÐdjÐejÐZkÓlÓmˆG÷	nä× Ñ Ó" RÑ'ˆØ×Ñ˜7Ô#ä˜U G¨TÓ2ˆä�#�s BÔ'ð 	%¨1Ü—‘˜q¬T°+¸a±.×2EÑ2EÓ2GÓ-HÔIˆAØ�M‰MŒOØ�K‰K˜Ô$÷	%ñ
 ˜×)Ò)ÜÐ& u g¨U°8°*Ð<[Ð\Ô]ÙØŒs�6‹{˜Q‰ÔÜ�J‰J�t—z‘zÖ"ð'#ô* 
Ð   Ð
&Õ'ùòS C÷Nñ Nú÷,	nñ 	nú÷	%ð 	%ús/   ¢M6¸M6Á"M;É%NÊ5ANÍ;NÎN	ÎN	c                  ó„  — t        j                  t        t         j                  ¬«      } | j	                  dd¬«      }|j                  dd¬«      }|j                  dt        ¬	«       |j                  d
dd¬«       |j                  dd¬	«       |j                  dd¬	«       |j                  dd¬«      }|j                  dt        ¬	«       |j                  dt        d¬«       |j                  dt        d¬«       |j                  dd¬	«       |j                  dt        d¬«       |j                  dt        d¬«       |j                  d d!¬	«       |j                  d"d#¬$«       |j                  d%d#¬$«       |j                  dd d&¬«       | j                  «       }|j                  dk(  rt        |«       y t        |«       y )'N)ÚdescriptionÚformatter_classÚcmdT)ÚdestÚrequiredrM   zAexport merchant refs, public keys and checksums (needs MYSQL_PWD))Úhelpz--out)Údefaultz--amountz10.00z%amount the checksums are computed for)rí   rì   z	--db-userÚrootz	--db-hostÚ	localhostr.   zopen checkout pages in stagesz--merchantsz--basezCloudLayer 4056 base URLz--simzsimulator base URLz--stagesz	10,50,100z--pauseé   )r—   rí   z	--timeouté<   z
--currencyÚAEDz--stop-on-failÚ
store_true)Úactionz--yesz7results CSV (default: checkout_results_<timestamp>.csv))ÚargparseÚArgumentParserÚ__doc__ÚRawDescriptionHelpFormatterÚadd_subparsersÚ
add_parserÚadd_argumentÚDEFAULT_CSVÚDEFAULT_BASEÚDEFAULT_SIMr,   Ú
parse_argsré   rM   r.   )ÚpÚsubÚppÚprrF   s        r   Úmainr  
  si  € Ü×Ñ¬GÄX×EiÑEiÔj€AØ
×
Ñ
 °Ð
Ó
5€Cà	�‰˜	Ð(kˆÓ	l€BØ‡O�O�G¤[€OÔ1Ø‡O�O�J¨Ð6]€OÔ^Ø‡O�O�K¨€OÔ0Ø‡O�O�K¨€OÔ5à	�‰˜Ð$CˆÓ	D€BØ‡O�O�M¬;€OÔ7Ø‡O�O�H¤lÐ9S€OÔTØ‡O�O�G¤[Ð7K€OÔLØ‡O�O�J¨€OÔ4Ø‡O�O�I¤E°2€OÔ6Ø‡O�O�K¤e°R€OÔ8Ø‡O�O�L¨%€OÔ0Ø‡O�OÐ$¨\€OÔ:Ø‡O�O�G L€OÔ1Ø‡O�O�G TÐ0i€OÔjà�<‰<‹>€DØ—X‘X Ò*„GˆD…M´°Dµ	r   Ú__main__)NNrñ   )"r÷   rõ   r>   r
   r   rS   r%   Úrerº   r-   r'   rÛ   rŠ   Úurllib.errorrU   Úurllib.requestÚconcurrent.futuresr   r   rü   rý   rþ   Úcompiler’   r1   r   rM   rh   r¥   r¬   rÅ   r.   r  r˜   rÉ   r   r   ú<module>r     s¤   ðñó: Û 
Û Û Û Û 	Û 	Û Û Û 
Û Û Û Û Ý 1Ý à:€Ø&€Ø%€ØˆR�Z‰ZÐ:Ó;€
ð	€òVò$;óR	 ò=ò@Qòò0*(òZ:ð4 ˆzÒÙ…Fð r   