+
    >UÂj’=  ã                   óN  € R t ^ RIt^ RIt^ RIt^ RIt]P
                  ! R4      t^ RIHt ^ RI	H	t	H
t
Ht ^ RIHt ^ RIHt ^ RIHtHtHtHtHt ^ RIHtHtHtHt ^ R	IHt ^ R
IHtHt R R ltR R ltR R ltR R ltR R lt R R lt!R R lt"R R lt#R R lt$R R lt%R# )a¬  Periodic live-status reconciliation for Billing, customers and hotspot vouchers.

Voucher lifecycle rules (independent triggers, either one is enough):
  1. Duration/jatah habis  -> hapus dari RouterOS + database.
  2. Masa berlaku habis   -> hapus dari RouterOS + database.
Status juga disinkronkan LIVE dari RouterOS (uptime / limit-uptime / active /
disabled) supaya DataTables voucher selalu mencerminkan kondisi perangkat.
Nzbestweb.voucher_monitor)Úselect)ÚdatetimeÚtimezoneÚ	timedelta©ÚAsyncSessionLocal)Úrefresh_customer_online_status)ÚVoucherÚVoucherBatchÚCustomerÚMikrotikDeviceÚHotspotProfile)r   ÚDeviceCredentialr   r	   )ÚRealMikrotikAdapter)Údecrypt_secret_strictÚSecretDecryptionErrorc                ó$   € V ^8„  d   QhR\         /# ©é   Úreturn©Úint)Úformats   "Ú0/var/www/html/bestweb/app/core/status_monitor.pyÚ__annotate__r   !   s   € ÷ ñ ”sñ ó    c            	      ó|   €  \        ^
\        \        P                  ! RR4      4      4      #   \         d     ^# i ; i)é
   ÚBESTWEB_STATUS_POLL_SECONDSÚ30©Úmaxr   ÚosÚgetenvÚ
ValueError© r   r   Úpoll_intervalr&   !   s7   € ðÜ�2”sœ2Ÿ9š9Ð%BÀDÓIÓJÓKÐKøÜô Úðúó   ‚), ¬;º;c                ó$   € V ^8„  d   QhR\         /# r   r   )r   s   "r   r   r   (   s   € ÷ ñ œsñ r   c            	      ó|   €  \        ^\        \        P                  ! RR4      4      4      #   \         d     ^
# i ; i)é   ÚBESTWEB_VOUCHER_POLL_SECONDSÚ10r    r%   r   r   Úvoucher_poll_intervalr-   (   s7   € ðÜ�1”cœ"Ÿ)š)Ð$BÀDÓIÓJÓKÐKøÜô Úðúr'   c                ó>   € V ^8„  d   QhR\         R,          R\        /# ©r   ÚvalueNr   )Ústrr   )r   s   "r   r   r   /   s   € ÷ 'ñ '¤ d¥
ð '¬sñ 'r   c                óB  € \        T ;'       g    R4      P                  4       P                  4       pV'       g   ^ # RV9   Ed   ^ pTp\        P                  ! RV4      pV'       d,   \        VP                  ^4      4      pVP                  ^4      pVP                  R4      p V Uu. uF  p\        \        V4      4      NK  	  pp\        T4      ^8  d   TP                  ^ ^ 4       K$  \        T4      ^8¼  d   Y'^ ,          ,          pTR
R pTR,          T^ ,          R,          ,           T^,          ^<,          ,           T^,          ,           # \        P                  ! RV4      pV'       du   \        VP                  4       4      '       dV   R VP                  4        4       w  ršr¼pV	R	,          V
R,          ,           VR,          ,           V^<,          ,           V,           #  \        \        V4      4      # u upi   \         d     ^ # i ; i  \         d     ^ # i ; i)ztParse RouterOS uptime/limit-uptime into seconds.

Accepts 1d02:03:04, 02:03:04, 3h04m, 2w, 5m, 45s and bare digits.
Ú Ú:z^(\d+)d(.*)$Ni€Q i  z7(?:(\d+)w)?(?:(\d+)d)?(?:(\d+)h)?(?:(\d+)m)?(?:(\d+)s)?c              3   óJ   "  € T F  q'       d   \        V4      M^ x € K  	  R# 5i)é    Nr   )Ú.0Úgs   & r   Ú	<genexpr>Ú'parse_uptime_seconds.<locals>.<genexpr>P   s   é € ÐD±^°¦1œ˜Qœ¨!Ô+³^ùs   ‚!#i€:	 éýÿÿÿ)r1   ÚstripÚlowerÚreÚmatchr   ÚgroupÚsplitÚfloatr$   ÚlenÚinsertÚ	fullmatchÚanyÚgroups)r0   ÚrawÚdaysÚbodyÚ	day_matchÚpartsÚpÚnumsr?   ÚwÚdÚhÚmÚss   &             r   Úparse_uptime_secondsrT   /   s¯  € ô
 ˆe�kˆk�rÓ
×
 Ñ
 Ó
"×
(Ñ
(Ó
*€CßÙð ˆc…zØˆØˆÜ—H’H˜_¨cÓ2ˆ	ßÜ�y—‘ qÓ)Ó*ˆDØ—?‘? 1Ó%ˆDØ—
‘
˜3“ˆð	Ù+0Ó1©5 a”Cœ˜a›–M©5ˆDÐ1ô �$‹i˜!ŒmØ�K‰K˜˜1ÖÜˆt‹9˜Œ>Ø˜•G�OˆDØ˜˜�9ˆDØ�e�|˜d 1�g¨�nÕ,¨t°A­w¸­|Õ;¸dÀ1½gÕEÐEä�LŠLØBÀCó€E÷ ”�U—\‘\“^×$Ò$ÙD°U·\±\´^ÓD‰ˆˆa�AØ�6�z˜A �IÕ%¨¨D­Õ0°1°rµ6Õ9¸AÕ=Ð=ðÜ”5˜“:‹Ðùò% 2øÜô 	Úð	ûô$ ô Úðús6   Â$G= Â(G8ÃG= Ç$H Ç8G= Ç=HÈHÈHÈHc                óL   € V ^8„  d   QhR\         R,          R\         R,          /# r/   )r   )r   s   "r   r   r   Y   s"   € ÷ *ñ *”(˜T•/ð *¤h°¥oñ *r   c                ó¨   € V f   R# V P                   f!   V P                  \        P                  R7      # V P	                  \        P                  4      # )zGSQLite drops tzinfo, so treat naive timestamps as UTC before comparing.N)Útzinfo)rW   Úreplacer   ÚutcÚ
astimezone)r0   s   &r   Úas_utcr[   Y   s>   € à‚}ÙØ‡|�|ÒØ�}‰}¤H§L¡Lˆ}Ó1Ð1Ø×ÑœHŸL™LÓ)Ð)r   c                óF   € V ^8„  d   QhR\         \        \        3,          /# r   )Údictr   r   )r   s   "r   r   r   b   s   € ÷ ñ ¤$¤sÔ,?Ð'?Õ"@ñ r   c              ƒ  ón  "  € V P                  \        \        4      P                  \        P                  R8H  4      4      G Rj  x€L
 P                  4       P                  4       p/ pV FÂ  pVP                  '       g   K  V P                  \        VP                  4      G Rj  x€L
 pV'       d   VP                  '       g   K[  \        VP                  RVP                   2R7      p\        VP                  VP                  TVP                   ;'       g    RR7      W#P"                  &   KÄ  	  V#  Lì L�5i)a  Build one adapter per active MikroTik device that has valid credentials.

Raises SecretDecryptionError when a stored secret cannot be decrypted with
the active encryption key, so the caller can surface it instead of silently
pushing ciphertext to the device.
TNzKredensial )Úlabelé"  )ÚhostÚusernameÚpasswordÚapi_port)Úexecuter   r   ÚwhereÚ	is_activeÚscalarsÚallÚcredential_idÚgetr   r   Úencrypted_secretÚnamer   ra   rb   rd   Úid)ÚdbÚdevicesÚadaptersÚmkÚcredrc   s   &     r   Ú_device_adaptersrt   b   sô   é € ð —Z‘ZÜŒ~Ó×$Ñ$¤^×%=Ñ%=ÀÑ%EÓFó÷ ç�wƒy—‘“ð ð 02€HÛˆØ××ÐÙØ—V‘VÔ,¨b×.>Ñ.>Ó?×?ˆß˜ŸŸ˜ÙÜ(Ø×!Ñ!¨;°t·y±y°kÐ)Bô
ˆô .Ø—‘Ø—]‘]ØØ—[‘[×(Ð( Dô	
ˆ—‘‹ñ ð €Oñ'ñ @ùs8   ‚AD5ÁD1ÁAD5Â#D3Â$D5Â0D5ÃAD5ÄD5Ä3D5c                ó$   € V ^8„  d   QhR\         /# r   r   )r   s   "r   r   r      s   € ÷ ñ œcñ r   c                ó  € V R9   d   ^ # \        V 4      P                  4       pVP                  4       '       d   \        V4      # RRRRRRRRR	RR
R/pVP	                  4       P                  RR4      pVP                  4        FG  w  rEVP                  V4      '       g   K   \        \        VR\        V4      )  4      V,          4      u # 	   \        \        V4      4      #   \         d      ^ # i ; i  \         d     ^ # i ; i)zDParse RouterOS byte counters like '123456' or '1.2MiB' -> int bytes.Nr3   Úkibi   ÚmibÚgibÚkbiè  ÚmbÚgbÚ )Nr3   r   i   i   @i@B i Êš;)r1   r<   Úisdigitr   r=   rX   ÚitemsÚendswithrB   rC   r$   )r0   ÚtextÚunitsÚloweredÚsuffixÚmults   &     r   Ú_routeros_bytesr†      sò   € à�ÔÙÜˆu‹:×ÑÓ€DØ‡|�|‡~‚~Ü�4‹yÐØ�D˜% ¨E°9Ø�4˜˜y¨$°	ð;€Eà�j‰j‹l×"Ñ" 3¨Ó+€GØŸ™ž‰ˆØ×Ñ˜F×#Ô#ðÜœ5 ¨¬C°«K¨<Ð!8Ó9¸DÕ@ÓAÒAñ &ðÜ”5˜“>Ó"Ð"øô ô Ûðûô ô Úðús$   Â!'C"ÃC5 Ã"C2Ã1C2Ã5DÄDc                ó   € V ^8„  d   QhRR/# ©r   r   Nr%   )r   s   "r   r   r   •   s   € ÷ [ñ [ $ñ [r   c               ƒ  ó  "  € \        4       ;_uu_4       GRj  x€L
 p \        P                  ! \        P                  4      pV P                  \        \        4      P                  \        P                  R8g  4      4      G Rj  x€L
 P                  4       P                  4       pV'       g    RRR4      GRj  x€L
  R#  \        V 4      G Rj  x€L
 p/ p/ pRpTP#                  4        FŒ  w  r‰ \$        P&                  ! T	P(                  4      G Rj  x€L
 p
T
 Uu/ uF  q»R,          TbK  	  upYX&   RYh&   T P+                  \,        T4      G Rj  x€L
 pTe   TP.                  T8w  d   Yn        RpKŠ  KŒ  KŽ  	  T EFï  pTP2                  ;'       g    TP4                  ;'       g    RP7                  4       pTP8                  pT P+                  \:        TP<                  4      G Rj  x€L
 pT'       d"   TP+                  T/ 4      P+                  T4      MRpTP+                  TR4      p\?        TP@                  4      pTPB                  '       d   \E        T;'       d    TT8*  4      pMRpRpT'       dù   \G        TP+                  R	4      4      p\G        TP+                  R
4      4      ;'       g    \G        TPH                  4      pTTPJ                  ;'       g    ^ 8  d   ^ Tn%        TTPJ                  ;'       g    ^ ,
          pT^ 8”  d5   \M        TPN                  ;'       g    ^ 4      T,           Tn'        TTn%        RpT^ 8”  d'   \M        TPN                  ;'       g    ^ 4      T8¼  d   RpT;'       d    TRJ ;'       d    TP                  R8H  p\Q        T;'       d    TP+                  R4      4      ;'       g%    \Q        T;'       d    TP+                  R4      4      pT'       Ed   TP+                  R4      '       g(   \G        TP+                  R	4      4      ^ 8”  g	   T'       dà   TP                  R9   dÏ   RTn	        TPB                  ;'       g    TTn!        T'       d2   TPR                  '       d    \U        \M        TPR                  4      R7      M:T'       d2   TPV                  '       d    \U        \M        TPV                  4      R7      MRpT'       d   TPB                  T,           Tn         Rp\        PY                  RT4       T'       g   T'       g   T'       g   EK§  T'       d   TP+                  T4      MRp	T	'       d3   T'       d+    \$        P&                  ! T	PZ                  T4      G Rj  x€L
  ^ RI.H/p T'       d   RMT'       d   RMRpT Pa                  T! TPb                  TP4                  TP2                  TPd                  TPf                  TP                  TPh                  TPB                  \M        TPN                  ;'       g    ^ 4      TTTP<                  TPj                  R7      4       \        PY                  RTT4       T Pm                  T4      G Rj  x€L
  RpEKò  	  T'       d   T Po                  4       G Rj  x€L
  RRR4      GRj  x€L
  R#  ELˆ EL! ELï ELÜ  \         d   p\        P                  RT4       h Rp?i\          d     RRR4      GRj  x€L 
  R# i ; i ELãu upi  EL®  \          d$    / YX&   RYh&   \        P1                  RT4        EKD  i ; i ELK ELÂ  \          d    \        P1                  RT4        ELäi ; i Lû LÖ LÈ  + GRj  x€L 
 '       g   i     R# ; i5i)z9Sync voucher status/deletion against live RouterOS state.NÚreservedzvoucher reconcile stopped: %sFrm   Tz5voucher reconcile: RouterOS read failed for device %sr3   ÚuptimeÚlimit_uptimeÚusedÚbytes_inÚ	bytes_outÚactive)Úseconds)rI   z/voucher %s marked used (live RouterOS activity)z"voucher %s: RouterOS delete failed)ÚVoucherArchiveÚexpiredÚduration_exhaustedÚgone_from_device)Ú
voucher_idÚcoderb   ÚprofileÚpriceÚstatusÚsold_atÚused_atÚused_secondsÚ
deleted_atÚreasonÚbatch_idÚagent_idz*voucher %s removed (%s) from DB and device)ÚsoldÚ	available)8r   r   Únowr   rY   re   r   r	   rf   rš   rh   ri   rt   r   Ú_logÚerrorÚ	Exceptionr   ÚasyncioÚ	to_threadÚlist_hotspot_usersrk   r   Úlast_sync_atÚwarningrb   r—   r<   Ú	device_idr
   r    r[   Ú
expires_atrœ   ÚboolrT   rŒ   Úlast_poll_uptimer   r�   r†   Úduration_secondsr   Úduration_daysÚinfoÚdelete_hotspot_userÚapp.models.modelsr’   Úaddrn   r˜   r™   r›   r¡   ÚdeleteÚcommit)ro   r¤   Úvouchersrq   ÚexcÚremote_by_deviceÚdevice_syncedÚchangedr­   ÚadapterÚremote_rowsÚrowÚdeviceÚvrb   ÚbatchÚremoteÚ	is_syncedr®   r“   r”   Úsession_secondsÚlimit_secondsÚdeltar•   Úhas_trafficÚvalidityr’   rŸ   s                                r   Úreconcile_vouchersrË   •   sñ  é € ä ×"×"Ô" bÜ�lŠlœ8Ÿ<™<Ó(ˆð —*‘*œV¤G›_×2Ñ2´7·>±>ÀZÑ3OÓPÓQ×Qß
‰'‹)—C‘C“Eð 	÷ Ø÷ #×"Ñ"ð	Ü-¨bÓ1×1ˆHð 8:ÐØ)+ˆØˆØ"*§.¡.Ö"2ÑˆIð#Ü$+×$5Ò$5°g×6PÑ6PÓ$Q×Q�ÙKVÓ.WÉ;ÀC°6­{¸CÒ/?É;Ñ.WÐ Ñ+Ø+/�Ñ(ð  "Ÿv™v¤n°iÓ@×@�ØÒ%¨&×*=Ñ*=ÀÔ*DØ*-Ô'Ø"’Gñ +EÑ%ñ #3ô& ˆAØŸ
™
×2Ð2 a§f¡f×2Ð2°×9Ñ9Ó;ˆHØŸ™ˆIØŸ&™&¤¨q¯z©zÓ:×:ˆEßJSÐ%×)Ñ)¨)°RÓ8×<Ñ<¸XÔFÐY]ˆFØ%×)Ñ)¨)°UÓ;ˆIô
   §¡Ó-ˆJà�y�yˆyÜ˜z×?Ð?¨j¸CÑ.?Ó@‘à�ð "'ÐßÜ"6°v·z±zÀ(Ó7KÓ"L�Ü 4°V·Z±ZÀÓ5OÓ P× xÐ xÔThÐij×iwÑiwÓTx�à" a×&8Ñ&8×&=Ð&=¸AÔ>ð *+�AÔ&à'¨1×+=Ñ+=×+BÐ+BÀÕC�Ø˜1”9Ü%(¨¯©×)<Ð)<¸1Ó%=ÀÕ%E�A”NØ)8�AÔ&Ø"�Gà  1Ô$¬¨Q¯^©^×-@Ð-@¸qÓ)AÀ]Ô)RØ)-Ð&ð  )×RÐR¨V°t¨^×RÐRÀÇÁÈFÑ@RÐô *¨&×*KÐ*K°V·Z±ZÀ
Ó5KÓL÷ ð ÔP_Ø×2Ð2˜6Ÿ:™: kÓ2óQˆK÷ ˆvØ—:‘:˜h×'Ò'Ô+?ÀÇ
Á
È8Ó@TÓ+UÐXYÔ+Y×]hØ—x‘xÐ#8Ô8Ø#)˜œØ$%§I¡I×$4Ð$4°˜œ	÷ # u×'=×'=Ð'=ô $-Ü$'¨×(>Ñ(>Ó$?õ$÷ # u×':×':Ð':ô DMÜ!$ U×%8Ñ%8Ó!9õDà@Dð	 !÷
 $Ø+,¯9©9°xÕ+?˜AœLØ"&˜ÜŸ	™	ØMÈxô÷ ×1×5EÚç1:�h—l‘l 9Ô-ÀˆGßŸ8ðQÜ!×+Ò+¨G×,GÑ,GÈÓR×RÐRõ
 9ç$‘	ß.@Ñ*ÐFXð ð �F‰FÙØ Ÿt™t¨!¯&©&¸1¿:¹:ÈqÏyÉyØŸ'™'¨!¯(©(¸A¿I¹IÈqÏyÉyÜ!$ Q§^¡^×%8Ð%8°qÓ!9Ø"¨6ØŸZ™Z°!·*±*ôôô �I‰IÐBÀHÈfÔUØ—)‘)˜A“,×ÐØ‹GñQ ÷Z Ø—)‘)“+×Ð÷s #×"Ô"ò Rò #ò 2øÜ$ô 	Ü�J‰JÐ6¸Ô<ØûÜô 	Ø÷% #×"Ò"ð"	úò RùÚ.Wò Aøô ô ð /1Ð Ñ+Ø+0�Ñ(Ü—‘ØKÈY÷ð ðúò" ;ò` SøÜ ô QÜ—L‘LÐ!EÀx×PðQúñ& ñ ÷s #×"×"Ó"üsZ  ‚^™Z!š^�A&]%ÂZ$Â']%Â,]%Â-^Â8Z'Â9^Ã Z-ÃZ*ÃZ-Ã]%Ã/#\ Ä[5
Ä\ Ä[8
Ä-	\ Ä6]%Å[=
ÅA]%Æ]%Æ&A ]%Ç&\1
Ç']%Ç3A)]%É]%É4:]%Ê/)]%Ë!]%Ë;']%Ì#:]%Í]%Í5]%Î]%Î]%Î<]%Ï]%Ï*]%Ð&]%Ð(*]%Ñ]%Ñ#]%Ñ5&]%Ò]%Ò.(]%Ó7]%Ô]%Ô]%Ô
]%Ô*]%Õ]%Õ$\7Õ2\4
Õ3\7Õ7]%Ö	]%ÖB ]%ØA]%Ù#]
Ù$]%Ù7]%Ú
]!Ú]%Ú^Ú]#Ú^Ú$]%Ú'^Ú*Z-Ú-[2Ú8[Û[2Û[2Û]%Û^Û)[,Û*^Û1[2Û2]%Û5\ Û8\ Û=]%Ü )\.	Ü)]%Ü-\.	Ü.]%Ü4\7Ü7!]	Ý]%Ý]	Ý]%Ý!]%Ý#^Ý%]?	Ý+].Ý,
]?	Ý7]?	Ý9	^c                ó   € V ^8„  d   QhRR/# rˆ   r%   )r   s   "r   r   r   3  s   € ÷ -ñ -˜Dñ -r   c               ƒ  óX  "  €   \        4       ;_uu_4       GRj  x€L
 p V P                  \        \        4      P	                  \        P
                  R8H  \        P                  P                  R4      \        P                  P                  R4      \        P                  P                  R4      4      4      G Rj  x€L
 P                  4       P                  4       pV F  p \        W 4      G Rj  x€L
  K  	  RRR4      GRj  x€L
  \        P"                  ! \%        4       4      G Rj  x€L
  EK/   EL Ly LF  \         d    T P                  4       G Rj  x€L 
   K‚  i ; i L_  + GRj  x€L 
 '       g   i     Lv; i  \        P                    d    h \         d     L›i ; i L}5i)zMKeep billing status aligned with live OLT/MikroTik state and expire vouchers.NF)r   re   r   r   rf   Úis_archivedÚpppoe_usernameÚis_notÚmikrotik_device_idÚolt_device_idrh   ri   r   r§   Úrollbackr¨   ÚCancelledErrorÚsleepr&   )ro   Ú	customersÚcustomers      r   Úmonitor_looprØ   3  s>  é € à
ð	Ü(×*×*Ô*¨bØ#%§:¡:Üœ8Ó$×*Ñ*Ü ×,Ñ,°Ñ5Ü ×/Ñ/×6Ñ6°tÓ<Ü ×3Ñ3×:Ñ:¸4Ó@Ü ×.Ñ.×5Ñ5°dÓ;ó	ó$÷ ÷ ‘7“9ŸS™S›Uð ó !*�Hð,Ü<¸XÓJ×JÒJñ !*÷ +×*ô$ �mŠmœM›OÓ,×,Ó,ò% +ññ KøÜ$ô ,Ø Ÿk™k›m×+Ô+ð,ú÷ +×*×*Ò*ûô ×%Ñ%ô 	ØÜô 	Ùð	úá,ùsæ   ‚F*…F ›D2œF ŸBE&Â;D5Â<%E&Ã"D9Ã0D7
Ã1D9Ã5E&Ã9F ÄE$ÄF Ä	!F*Ä*F(Ä+F*Ä2F Ä5E&Ä7D9Ä9E!	ÅEÅE!	ÅE&Å E!	Å!E&Å$F Å&E?	Å,E/Å-
E?	Å8E?	Å:F Å>F*Å?F ÆF%Æ!F%Æ"F*Æ$F%Æ%F*c                ó   € V ^8„  d   QhRR/# rˆ   r%   )r   s   "r   r   r   L  s   € ÷ 	5ñ 	5 Dñ 	5r   c               ƒ  ó   "  €   \        4       G Rj  x€L
  \        P                  ! \        4       4      G Rj  x€L
  K<   L,  \        P                   d    h \         d    \        P                  R4        Lai ; i LC5i)zDFast lane voucher reconciliation so UI reflects RouterOS state live.Nzvoucher reconcile cycle failed)rË   r¨   rÔ   r§   r¥   Ú	exceptionrÕ   r-   r%   r   r   Úvoucher_monitor_looprÜ   L  sf   é € à
ð	=Ü$Ó&×&Ð&ô
 �mŠmÔ1Ó3Ó4×4Ò4ñ 'øÜ×%Ñ%ô 	ØÜô 	=Ü�N‰NÐ;Ö<ð	=úá4ùsE   ‚A>…A ’?“A —!A>¸A<¹A>¿A ÁA9Á A9Á6A>Á8A9Á9A>c                ó$   € V ^8„  d   QhR\         /# r   )r]   )r   s   "r   r   r   X  s   € ÷ *ñ *¤$ñ *r   c                 ó@  aa€ ^ RI o^ RIHo VV3R lp  SP                  V ! 4       4      pRT'       d?   \        ;QJ d"    R T 4       F  '       d   K   RRT/# 	  R	RT/# ! R T 4       4       RT/# RRT/#   \         d   pRRR\        T4      R. /u Rp?# Rp?ii ; i)
zFReport whether live voucher reconciliation can actually reach devices.Nr   c               “   óh  <"  € S	! 4       ;_uu_4       GR j  x€L
 p V P                  \        \        4      P                  \        P                  R8H  4      4      G R j  x€L
 P                  4       P                  4       p. pV FÉ  pRVP                  RVP                  RVP                  ;'       g    RRR RRR	R /p \        V 4      G R j  x€L
 pVP                  VP                  4      pVf   R
VR	&   MFS
P                  VP                  4      G R j  x€L
 pVP                  VR&   RVR&   \!        V4      VR&    VP'                  V4       KË  	  TuuR R R 4      GR j  x€L
  #  ELL EL	 Lž LX  \"         d   p\%        T4      TR	&    R p?LQR p?ii ; i L5  + GR j  x€L 
 '       g   i     R # ; i5i)NTrÁ   ra   Úportr`   Ú
credentialÚokFr¦   z)Kredensial tidak aktif / belum ditugaskanÚusers)re   r   r   rf   rg   rh   ri   rm   ra   rd   rt   rk   rn   r©   rª   rb   rC   r§   r1   Úappend)ro   rp   Úreportrr   Úitemrq   r¾   Úrowsrº   Ú_SessionÚ_asyncios            €€r   ÚprobeÚ'voucher_reconcile_health.<locals>.probe]  sc  øé € Ù—:—:”: ØŸZ™ZÜ”~Ó&×,Ñ,¬^×-EÑ-EÈÑ-MÓNó÷ ç‰w‹yŸ™›ð ð ˆFÛ�à˜bŸg™gØ˜BŸG™GØ˜BŸK™K×/Ð/¨4Ø  $Ø˜%Ø˜Tð�ð-Ü%5°bÓ%9×9�HØ&Ÿl™l¨2¯5©5Ó1�GØ’Ø(S˜˜Wšà%-×%7Ñ%7¸×8RÑ8RÓ%S×S˜Ø-4×-=Ñ-=˜˜\Ñ*Ø%)˜˜T™
Ü(+¨D«	˜˜Wšð —‘˜dÖ#ñ+ ð, ÷7 —:•:òñ  :ñ
  Tøô !ô -Ü$'¨£H�D˜–Mûð-ú÷1 —:—:“:üs¾   ƒF2—E#˜F2›AFÁE&ÁAFÂ1
FÂ<E-Ã
E)
Ã(E-Ã3FÃ4E-ÄE+
Ä&E-Ä9FÅF2ÅFÅF2Å&FÅ)E-Å+E-Å-F	Å8F	ÆFÆF	ÆFÆF2ÆF/	ÆFÆ
F/	Æ'F/	Æ)	F2râ   Fr¦   rp   c              3   ó2   "  € T F  qR ,          x € K  	  R# 5i)râ   Nr%   )r7   rP   s   & r   r9   Ú+voucher_reconcile_health.<locals>.<genexpr>€  s   é € Ð+¡7˜a�D—'’'£7ùs   ‚T)r¨   Úapp.core.databaser   Úrunr§   r1   ri   )rê   rp   rº   rè   ré   s      @@r   Úvoucher_reconcile_healthrð   X  s³   ù€ ãÝ?öð<?Ø—,‘,™u›wÓ'ˆð 	¯w�c‹cÑ+¡7Ó+�cŒcØ�7ðð ÚØ�7ðð ØÑ+¡7Ó+Ô+Ø�7ðð Ø<AØ�7ðð øô ô ?Ø�e˜W¤c¨#£h°	¸2Ð>Õ>ûð?ús   •A7 Á7BÂBÂBÂB)&Ú__doc__r¨   Úloggingr"   r>   Ú	getLoggerr¥   Ú
sqlalchemyr   r   r   r   rî   r   Úapp.core.onboardingr   rµ   r	   r
   r   r   r   r   Úapp.core.mikrotikr   Úapp.core.secretsr   r   r&   r-   rT   r[   rt   r†   rË   rØ   rÜ   rð   r%   r   r   Ú<module>rø      s…   ðñó Û Û 	Û 	à×ÒÐ2Ó3€å ß 2Ñ 2å /Ý >ß ]Õ ]÷ó õ 2ß Iõõõ'õT*õõ:õ,[õ|-õ2	5÷*r   