
    Oj	^                        S r SSKrSSKrSSKrSSKrSSKrSSKrSSKrSSK	r	SSK
JrJr  \R                  R                  \R                  R                  \5      5      r\" \R&                  R)                  S5      =(       d'    \" \R,                  5      S:  a  \R,                  S   OS5      r\R                  R1                  \S5      r\R                  R1                  \S5      r\R                  R1                  \S	5      rS
r\R&                  R)                  S5      =(       d    Sr1 SkrSrSr Sr!\RD                  " 5       r#SS0 / 0 / S.r$S r%Sq&S r'S r(S r)S r*S r+S r,S r-S r.0 r/S r0SSSSS.r1S r2 " S  S!\Rf                  Rh                  5      r5 " S" S#\Rf                  Rl                  5      r7S$ r8\9S%:X  a  \8" 5         gg)&a  
draft_server.py -- LAN relay for the "Betta Bring It" draft board.

Run this INSTEAD of `python -m http.server 8777`. It does two jobs:

  1. Serves the static files (draftboard.html, board.html, pick.html, lobby.html, players.json, ...)
     exactly like the old file server.
  2. Bridges phone clients to the control browser so managers can draft from their own devices:
       * holds a MIRROR of the draft state (the control browser pushes it on every change),
       * holds the CLAIMS registry (which device owns which team),
       * holds a pick-request MAILBOX (phone asks -> control browser ratifies -> result comes back).

Design guarantees:
  * The control browser stays the single brain / single writer. This server never runs draft
    logic; it only relays. So there is no split-brain and phones can never double-pick
    (the control browser ratifies every request through its normal doPick, checking turn +
    availability + staleness).
  * Privileged endpoints (/push /timer /pending /resolve /claims /release /bootstrap) are
    LOOPBACK-ONLY, so only the control browser on the host PC can call them. Phones (LAN IPs)
    can only reach the player endpoints. => Open the control/board/pick screens via
    http://localhost:8777 ON THE HOST PC; phones use http://<reserved-ip>:8777/lobby.html
  * State + claims are written to disk atomically on every change, so a crash / reboot recovers.

Stdlib only. No dependencies. Python 3.7+.
    N)urlparseparse_qsPORT   iI"  zserver_state.jsonzguide_data.jsonzguide_stats.json2026	ADMIN_PIN2060>   /guide_data.json/.fantasypros.env/guide_stats.json/server_state.json/server_state.json.tmp   x   Z   )statetimerclaimsqueueresultsgtokensc                  ,    [         R                   " 5       $ N)time     HC:\Users\Matth\OneDrive\Projects\AI\FantasyFootball\2026\draft_server.py_nowr   6   s    99;r   c                     [         co  [        R                  " [        R                  [        R                  5      n  U R	                  S5        U R                  5       S   q  U R                  5         [         $ [         $ ! [         a    Sq  N+f = f! [         a     [         $ f = f!  U R                  5         f ! [         a     f f = f= f)u[   This PC's primary LAN IP (the interface with the default route) — for the phone URL / QR.)z8.8.8.8P   r   	127.0.0.1)_lan_ipsocketAF_INET
SOCK_DGRAMconnectgetsockname	Exceptionclose)ss    r   
get_lan_ipr+   ;   s     MM&..&*;*;<		IIo&mmoa(G	 N7N  	"!G	"
  N	 sY   $A= !B =B	B$ BB$ 
B! B!$C&B76C7
CCCCc                      [        [        SS9 n [        R                  " U 5      nS S S 5        WR	                  S5      [
        S'   UR	                  S5      [
        S'   UR	                  S5      =(       d    0 [
        S'   UR	                  S5      =(       d    / [
        S'   [        S[        [
        S   5       S35        g ! , (       d  f       N= f! [         a     g [         a  n[        S	[         S
U 35         S nAg S nAff = f)Nutf-8encodingr   r   r   r   z  recovered z' team claim(s) and last state from diskz  !! could not read : )
open
STATE_FILEjsonloadget_dataprintlenFileNotFoundErrorr(   )fdes      r   
_load_diskr=   M   s    8*w/1		!A 0wgwg%%//Rh55+1riSx122YZ[ 0/   8$ZL1#6778s4   C CBC 
CC 
D	D'DDc                     [         S-   n [        S   [        S   [        S   [        S   S.n [        U SSS	9 n[        R                  " X5        UR                  5         [        R                  " UR                  5       5        S
S
S
5        [        R                  " U [         5        g
! , (       d  f       N*= f! [         a  n[        S[          SU 35         S
nAg
S
nAff = f)zCAtomically persist the durable bits (temp file -> fsync -> rename).z.tmpr   r   r   r   )r   r   r   r   wr-   r.   Nz  !! could not write r0   )r2   r6   r1   r3   dumpflushosfsyncfilenoreplacer(   r7   )tmppayloadr:   r<   s       r   
_save_diskrH   \   s    
v
Cgw5QY?	*,G9#sW-IIg!GGIHHQXXZ  . 	

3
#	 .-
  9%j\A37889s/   B9 AB(#B9 (
B62B9 9
C"CC"c                  b    [         S   =(       d    0 n U R                  S5      =(       d    [        $ )Nr   joinPin)r6   r5   JOIN_PIN_DEFAULT)sts    r   	_join_pinrM   k   s%    	w	2B66)0 00r   c            
          [        5       n [        S   R                  5        VVs0 s H*  u  p[        U5      XR	                  SS5      -
  [
        :  _M,     snn$ s  snnf )z2teamId(int) -> connected(bool) for anyone to read.r   lastSeenr   )r   r6   itemsintr5   CONN_WINDOW)ttidcs      r   _conns_summaryrV   p   sO    AMRS[_MbMbMdeMd63CHq55Q//+==Mdeees   1Ac                     U (       d  g[         S   R                  5        H+  u  pUR                  S5      U :X  d  M  [        5       US'   Us  $    g)zPBump last-seen for the claim holding this token; return its teamId(str) or None.Nr   tokenrO   )r6   rP   r5   r   )rX   rT   rU   s      r   _touchrY   v   sF    /'')55>U" FAjMJ * r   c            
      6   [         S   =(       d    0 R                  S/ 5      =(       d    / n [        [         S   R                  5       5      nU  Vs/ s H<  nUS   UR                  SS5      UR                  SS5      [	        US   5      U;   S.PM>     sn$ s  snf )	Nr   teamsr   idname mgr)r\   r]   r_   claimed)r6   r5   setkeysstr)r[   r`   rS   s      r   
_team_listrd      s    7^!r&&w39rE%/&&()G:?A:?Q T7AEE&"$5aeeE2>NAdG/1:?A A As   ABc                     U =(       d    0 R                  S/ 5      =(       d    / n[        U5      nUS:X  a  gUS-
  U-  S-   nUS-
  U-  nU R                  SS5      (       a  US-  S:X  a  US-
  U-
  nX%   S   $ )	zSSnake math mirror of orderForPick(): the teamId on the clock at `overall`, or None.r[   r   Nr   snakeT   r\   )r5   r8   )rL   overallr[   nrndidxs         r   _order_teamrl      s    X2NN7B'-2EE
AAvQ;1
q
 CQ;!
C	vvgtqA!eck:dr   c           	          [        5       nU[        R                  U S5      -
  S:  a  gU[        U '   [        SU  S[	        5        S[
         S35        g)zHOne friendly line per device per minute instead of a wall of tracebacks.r   <   Nz  !! z' tried HTTPS. Tell them to use  http://:z$/lobby.html  (http://, not https://))r   _https_warnedr5   r7   r+   r   )ipnows     r   _warn_httpsrs      sX    
&C
]r1%%*M"	E"<Z\N!D6 R$ % &r   Fr^   )runningdoneAtokmsgc            
          SS K Jn   SS Kn[        R                  R                  [        S5      n[        USS9 n[        R                  " U5      nS S S 5        WS   n0 nUR                  UR                  5      nUS   S   S   S   S    H  nUS	   n	 UR                  UR                  R                  U	S
   S95      n
U
R                  S/ 5       H  nUR                  S/ 5       Hu  nSnUR                  S5      =(       d    /  H6  nUR                  S5      =(       d    SR                  5       nU(       d  M4  Un  O   X[!        UR                  S
5      5      '   Mw     M     ["        R$                  " S5        M     U H-  n[!        UR                  S
5      5      nUU;   d  M%  UU   US'   M/     U Vs/ s H@  nUR                  SS5      S:  d  M  [!        US
   5      R'                  5       (       d  M>  UPMB     nnU R)                  SS9 nU Vs0 s H#  nUR+                  UR,                  US
   5      U_M%     nnU R/                  U5       H3  nUR1                  5       nU(       d  M  US   US   sUU   S'   UU   S'   M5     S S S 5        ["        R2                  " S5      US'   US-   n[        USSS9 n[        R4                  " XCSS9  UR7                  5         [        R8                  " UR;                  5       5        S S S 5        [        R<                  " UU5        S [>        S!'   S"[A        U5       S#[C        S$ U 5       5       S%3[>        S&'   S'[>        S('   [E        5       [>        S)'   g ! , (       d  f       GN#= f! [         a     GM  f = fs  snf s  snf ! , (       d  f       GN= f! , (       d  f       N= f! [         a%  nS'[>        S!'   [!        U5      [>        S&'    S nANS nAff = f! S'[>        S('   [E        5       [>        S)'   f = f)*Nr   zplayers.jsonr-   r.   playerssportsleaguesr[   teamr\   )rT   athletesrP   r^   injuriesstatusg?injadpg33333?@i     )max_workersnewsnewsDatez%Y-%m-%d %H:%M:%S	generatedz.tmp2r?   r   )indentTrv   znews refreshed for u    ranked players · c              3   T   #    U  H  oR                  S 5      (       d  M  Sv   M      g7f)r   r   N)r5   ).0ps     r   	<genexpr>_do_refresh.<locals>.<genexpr>   s#     Tx`g[\kpkpqvkwUVUV`gs   (	(z injury flagsrw   Frt   ru   )#concurrent.futuresfuturesfetch_playersrB   pathjoinROOTr1   r3   r4   r5   	TEAMS_URL
ROSTER_URLformatr(   striprc   r   sleepisdigitThreadPoolExecutorsubmitplayer_newsas_completedresultstrftimer@   rA   rC   rD   rE   _refreshr8   sumr   )cffpr   r:   datary   inj_maptdatarS   r|   rdatagrpar   jr*   r   pidtargetsexfutsfutresrF   r<   s                            r   _do_refreshr      s~   4$'"ww||D.1$)Q99Q<D *y/r||$x#I.q1':AV9Dr}}33T
3CD yyR0"-ACeeJ/525UU8_299;1"#C!	 6
 14Cd,- . 1 JJsO ;  AaeeDk"Cg~"3<% 
 &^gue)<s)B1s1T7|G[G[G]1g^""q"1RCJK7aBIIbnnag697DKt,jjl3?B6{CPZO<DIf%tCy'< - 2 !MM*=>[Wn#sW-IIda(GGIHHQXXZ  . 	

3/G~=PQTTx`gTxQxPy  zG  H
 $!Va *)  " _K 21 .-  !a&! $!Vs   8N> M-AN> +M? A6N> :A'N> %N> 5NN6N<N> N*N<+N+N1N> 7A
N-AN> -
M<7N> ?
N	N> NN> N
N*%N> -
N;7N> >
O-O(#O0 (O--O0 0Pc                       \ rS rSrSrS rSrg)QuietServer   zPort scans, HTTPS attempts and phones dropping off Wi-Fi are NORMAL on a party LAN.
Log one line instead of a 30-line traceback, so a real problem is still visible.c                     [         R                  " 5       S   n[        U[        [        [
        [        45      (       a  g [        SUS    S[        U5      R                   S35        g )Nr   z&  !! dropped a malformed request from r   z ())
sysexc_info
isinstanceConnectionResetErrorConnectionAbortedErrorBrokenPipeErrorTimeoutErrorr7   type__name__)selfrequestclient_addressr<   s       r   handle_errorQuietServer.handle_error   sY    LLN1a.0FYefgg6~a7H6IDQRGL\L\K]]^_`r   r   N)r   
__module____qualname____firstlineno____doc__r   __static_attributes__r   r   r   r   r      s    Xar   r   c                   n   ^  \ rS rSrU 4S jrS rS rS rU 4S jrSU 4S jjr	S r
U 4S	 jrS
 rSrU =r$ )Handler   c                 2   > [         TU ]  " US[        0UD6  g )N	directory)super__init__r   )r   r   kw	__class__s      r   r   Handler.__init__   s    !2t2r2r   c                 &    U R                   S   S;   $ )Nr   )r!   z::1)r   )r   s    r   _localHandler._local   s    ""1%)===r   c                 x   [         R                  " U5      R                  S5      nU R                  U5        U R	                  SS5        U R	                  S[        [        U5      5      5        U R	                  SS5        U R                  5          U R                  R                  U5        g ! [         a     g f = f)Nr-   zContent-Typezapplication/jsonContent-LengthCache-Controlno-store)r3   dumpsencodesend_responsesend_headerrc   r8   end_headerswfilewriter(   )r   codeobjbodys       r   _replyHandler._reply   s    zz#%%g.4 );<)3s4y>:*5	JJT" 		s   B, ,
B98B9c                      [        U R                  R                  S5      =(       d    S5      n[        R                  " U R
                  R                  U5      =(       d    S5      $ ! [         a    0 s $ f = f)Nr   r   s   {})rQ   headersr5   r3   loadsrfilereadr(   )r   ri   s     r   _readHandler._read   s[    	DLL$$%56;!<A::djjooa09E:: 	I	s   A$A' 'A65A6c                    > [        U SS5      =(       d    SR                  S5      S   nUR                  S5      (       d  US:X  a  U R                  SS5        [        TU ]  5         g )	Nr   r^   ?r   z.html/r   r   )getattrsplitendswithr   r   r   )r   r   r   s     r   r   Handler.end_headers   sX    
 T62&,"33C8;::g!s(_j9r   c                    > [        U SS5      =(       d    SnUS S S:X  a   [        U R                  S   5        SU l        g  [        TU ]  XU5        g ! [         a
    SU l         g f = f)Nraw_requestliner   r      r   T)r   rs   r   close_connectionr   
send_errorr(   )r   r   messageexplainrawr   s        r   r   Handler.send_error
  so     d-s3:sr7d?++A./$(D!	)Gtg6 	)$(D!	)s   A A'&A'c                     g r   r   )r   r   s     r   log_messageHandler.log_message  s    r   c                   >^ [        U R                  5      nUR                  [        UR                  5      p2U[        ;   a  U R                  SSS05      $ US:X  a"  U R                  SSU R                  5       05      $ US:X  a  UR                  S5      =(       d    S /S	   n[           U(       a  U[        S
   ;  a  U R                  SSSS.5      sS S S 5        $  S S S 5         [        [        SS9 nU R                  SS[        R                  " U5      S.5      sS S S 5        $ US:X  a  UR                  S5      =(       d    S /S	   n[           U(       a  U[        S
   ;  a  U R                  SSSS.5      sS S S 5        $  S S S 5         [        [         SS9 nU R                  SS[        R                  " U5      S.5      sS S S 5        $ US:X  a  UR                  S5      =(       d    S /S	   n[           U(       a  U[        S
   ;  a  U R                  SSS05      sS S S 5        $  S S S 5        U R                  SS["        S   ["        S   ["        S   ["        S   S.5      $ US:X  a/  [%        5       nU R                  SU[&        SU S [&         S!3S".5      $ US#:X  a  UR                  S$5      =(       d    S /S	   n[           S n	Ub$  [)        U5      n
U
S LU
(       a  [+        U
5      OS S%.n	U R                  SS[        S&   [        S'   [-        5       U	[/        5       S(.5      sS S S 5        $ US):X  a-  [           U R                  SS[1        5       S*.5      sS S S 5        $ US+:X  a  UR                  S,5      =(       d    S /S	   m[           [        S-   R                  T5      nU(       a  U R                  SU5      sS S S 5        $ [3        U4S. j[        S/    5       5      (       a  U R                  SS0S105      sS S S 5        $ U R                  SS0S205      sS S S 5        $ US3:X  GaB  U R                  5       (       d  U R                  SSS05      $ [           [/        5       [4        -
  n[        S/    Vs/ s H  oS4   U:  d  M  UPM     nnU(       aO  [        S/    Vs/ s H  oS4   U:  d  M  UPM     sn[        S/'   U H  nS5S6[/        5       S7.[        S-   US,   '   M      [/        5       [6        -
  n[        S-   R9                  5        VVs/ s H  u  nnUS4   U:  d  M  UPM     snn H  n[        S-   U	 M     U R                  SS[;        [        S/   5      S8.5      sS S S 5        $ US9:X  a  U R                  5       (       d  U R                  SSS05      $ [           [/        5       nU R                  SS[        S:   R9                  5        V
Vs/ s Ha  u  n
n[+        U
5      UR                  S;S<5      UR                  S=S<5      UR                  S>S	5      UUR                  S>S	5      -
  [<        :  S?.PMc     snn
S@.5      sS S S 5        $ [>        TU ]  5       $ ! , (       d  f       GN= f! , (       d  f       GNW= f! [         a    U R                  SSS SS.5      s $ [         a"  nU R                  SSSU 3S.5      s S nA$ S nAff = f! , (       d  f       GNS= f! , (       d  f       GN#= f! [         a    U R                  SSS SS.5      s $ [         a"  nU R                  SSSU 3S.5      s S nA$ S nAff = f! , (       d  f       GN = f! , (       d  f       GN5= f! , (       d  f       GN= f! , (       d  f       GNf= fs  snf s  snf s  snnf ! , (       d  f       GN?= fs  snn
f ! , (       d  f       GNu= f)AN  rv   Fz/whoami   localz/guide_datagr   r   u   Guide locked — enter the PINrv   reasonr-   r.   T)rv   guidezguide_data.json not found)rv   r  r  zguide_data.json unreadable: z/guide_stats)rv   statsu7   guide_stats.json not found — run fetch_guide_stats.py)rv   r  r  zguide_stats.json unreadable: z/guide_refresh_statusrt   ru   rw   )rv   rt   ru   successrw   z/lanzhttp://ro   /lobby.html)rq   porturlz/staterX   )validteamIdr   r   )rv   r   r   connsme
serverTimez/teamsrv   r[   z/pickresultreqIdr   c              3   2   >#    U  H  oS    T:H  v   M     g7f)r  Nr   )r   xrids     r   r   !Handler.do_GET.<locals>.<genexpr>b  s     A.QzS(.   r   r   pendingunknownz/pendingtsrejectedu   Timed out — try againr   r  r  )rv   r  z/claimsr   deviceIdr^   labelrO   )r  r  r  rO   	connected)rv   r   )!r   r   r   queryPRIVATE_FILESr   r   r5   _lockr6   r1   
GUIDE_FILEr3   r4   r9   r(   GSTATS_FILEr   r+   r   rY   rQ   rV   r   rd   any	QUEUE_TTL
RESULT_TTLrP   listrR   r   do_GET)r   ur   qr  r:   r<   rq   tokr  rT   rcutr  stalercutkvrS   rU   r  r   s                       @r   r*  Handler.do_GET  s   TYY&&(177+a= ;;sT5M229;;sWdkkm$<=== s%vq)AAU9%55;;s5Dd,ef 5 e*w71;;s4$))A,,OP 87 >!s%vq)AAU9%55;;s5Dd,ef 5 f+8A;;s4$))A,,OP 98 **s%vq)AAU9%55;;sT5M: 5  ;;s4HY<O/7/AhW[nemnset%v w w 6>B;;s2tgbTQRSWRXXcDd$eff855>+dVQ/C? +C#&d?#c#hSWXB{{3w%.+-R"&&)   8{{3tjl(KL  = 55>+dVQ/C)$((-;;sA.  A%.AAA;;sXy,AB  {{39(=>  :;;=={{3u66 fy($)'NDNqgmND16w%RAT7c>a%RE'N"BLB[cgci8ki(74 # v
*(-i(8(>(>(@S(@1AdGdN!(@SAi(+ T{{3tU7^@T(UV   9;;=={{3u66F{{3t #(/"7"7"9@; #:Q  #3xQUU:r5JUVUZUZ[bdfUg!"z1!5Qz[\I]E]`kEkn"9@; )< =  w~{  87$ l{{3tdNi(jkk e{{3uB^_`^a@b(cdde
  98$ J{{3td  OH  )I  J  J f{{3uB_`a_b@c(deef
   
 " E%R
 T *@; sA  ()Y%Z  3)Y.	Z  )[[4 )["	[4 8(]A ]<](1]:4]:]:^6^^^ ^0^6A^^#^)9^!2^4A(^.;	^4
Y+.
Y=8Z  =Z    ["	[+[[[
["
[1,[4 1[4 4 ]	]\<6]<]
]
]%(
]7:
^	^
^+.^44
_c           
      x  ^ [        U R                  5      R                  nU R                  5       nUS:X  a  [           [	        UR                  S5      =(       d    S5      [        :w  a  U R                  SSSS.5      sS S S 5        $ [        R                  " S5      n[        S	   U/-   S
S  [        S	'   [        5         U R                  SSUS.5      sS S S 5        $ US:X  a  [           UR                  S5      [        S	   ;  a  U R                  SSS05      sS S S 5        $ [        S   (       a  U R                  SSSS.5      sS S S 5        $ [        R                  SS SS.5        S S S 5        [        R                  " [         SS9R#                  5         U R                  SSSS.5      $ US:X  ah  [           UR                  S5      [%        5       :w  a  U R                  SSSS.5      sS S S 5        $ U R                  SS['        5       S.5      sS S S 5        $ US:X  Ga  [           UR                  S5      [%        5       :w  a  U R                  SSSS.5      sS S S 5        $ [	        UR                  S5      5      m[        S   =(       d    0 R                  S/ 5       Vs1 s H  n[	        US   5      iM     nnTU;  a  U R                  SSSS.5      sS S S 5        $ UR                  SS5      n[        S    R                  T5      nU(       aX  UR                  S5      U:w  aC  [)        5       UR                  S!S"5      -
  [*        :  a  U R                  SSS#S.5      sS S S 5        $ [        R                  " S$5      nX6UR                  S%S5      [)        5       S&.[        S    T'   [        5         U R                  SSU[-        T5      S'.5      sS S S 5        $ US(:X  Ga  [           UR                  S)5      nS m[        S    R/                  5        H+  u  pU
R                  S)5      U:X  d  M  U	m[)        5       U
S!'     O   Tc  U R                  SSS*S.5      sS S S 5        $ [        S   =(       d    0 nUR                  S+5      (       d  U R                  SSS,S.5      sS S S 5        $ [1        UR                  S-/ 5      5      S.-   n[3        X5      nUb-  [-        T5      U:w  a  U R                  SSS/S.5      sS S S 5        $ [5        U4S0 j[        S1    5       5      (       a  U R                  SSS2S.5      sS S S 5        $ [        R                  " S35      n[        S1   R7                  UTUR                  S45      UR                  S55      UR                  S65      [)        5       S7.5        U R                  SSUS8.5      sS S S 5        $ US9:X  ao  U R9                  5       (       d  U R                  SSS05      $ [           UR                  S5      [        S'   [        5         U R                  SSS05      sS S S 5        $ US::X  ae  U R9                  5       (       d  U R                  SSS05      $ [           UR                  S;5      [        S;'   U R                  SSS05      sS S S 5        $ US<:X  Ga  U R9                  5       (       d  U R                  SSS05      $ [           UR                  S=5      n[        S1    Vs/ s H  oS=   U:w  d  M  UPM     sn[        S1'   UR                  S>S?5      UR                  S@S5      [)        5       SA.[        SB   U'   [)        5       [:        -
  n[        SB   R/                  5        V	Vs/ s H  u  n	nUSC   U:  d  M  U	PM     snn	 H  n	[        SB   U		 M     U R                  SSS05      sS S S 5        $ USD:X  a  U R9                  5       (       d  U R                  SSS05      $ [           [	        UR                  S5      5      mUR                  SE5      (       a
  0 [        S '   O[        S    R=                  TS 5        [        5         U R                  SSS05      sS S S 5        $ U R                  SFSS05      $ ! , (       d  f       GN= f! , (       d  f       GN== f! , (       d  f       GN= fs  snf ! , (       d  f       GN= f! , (       d  f       GN"= f! , (       d  f       GN= f! , (       d  f       GNf= fs  snf s  snn	f ! , (       d  f       GNa= f! , (       d  f       N= f)GNz/guide_authpinr^   r  Fz	Wrong PINr  r   r   iT)rv   gtokenz/guide_refreshr  r  rv   rt   )rv   already)rt   rv   rw   )targetdaemon)rv   startedz/joinzWrong join PINr  z/claimr  r   r[   r\   zUnknown teamr  r   rO   r   zThat team is already takenr   r  )rX   r  r  rO   )rv   rX   r  z/pickrX   u   Not signed in — re-join	draftLivezThe draft hasn't started yetpicksr   zNot your turnc              3   2   >#    U  H  oS    T:H  v   M     g7f)r  Nr   )r   r  rT   s     r   r   "Handler.do_POST.<locals>.<genexpr>  s     B>a{c)>r  r   zPick already submitted   playerIdwritein
forOverall)r  r  rA  rB  rC  r  )rv   r  z/pushz/timerr   z/resolver  r   r  r  r  r   r  z/releasealli  )r   r   r   r#  rc   r5   r   r   secrets	token_hexr6   rH   r   update	threadingThreadr   startrM   rd   r   rR   rQ   rP   r8   rl   r&  appendr   r(  pop)r   r   brX   rS   r[   devexistingr-  r2  rU   rL   curonclockr  r  r/  r3  rT   s                     @r   do_POSTHandler.do_POST  sw   		"''JJL= quuU|)r*i7;;s5K,PQ   ))"-$))$4w$>#Di {{3tu(EF  ##55:U9%55;;sT5M:  I&;;s4D,IJ	 
 DR HI  K=CCE;;s4D$ABB7?55<9;.;;s5DT,UV  {{3tjl(KL 
 855<9;.;;s5DT,UV  !%%/*05g0D"/I/I'SU/VW/V!QtW/VWe#;;s5N,ST  eeJ+ ?..s3Z 8C ? FX\\*a%@@;N;;s5D`,ab   ))!,1612w1CQUQW(Yh${{3tesSVx(XY! $ 7?eeGn!(O113DAuuW~,(,*	 4
 ;;;s5D_,`a  7^)rvvk**;;s5Db,cd  "&&"-.2%b.&3s8w+>;;s5O,TU! " B5>BBB;;s5D\,]^% & ''*g%%sPQPUPUV`Pa23%%	2B56UU<5HPTPV'X Y {{3tc(BC/ 4 7?;;=={{3u66!"wg{{3t5 
 8;;=={{3u66!"wg{{3t5  :;;=={{3u66eeGn-27^!Q^zS?P!^!Qg3455:3N345523Fdf)Vi %fz)(-i(8(>(>(@R(@1AdGcM!(@RAi(+ S{{3t5  :;;=={{3u66!%%/*55<<&(E(O(O''T2{{3t5  {{3u..]    X	 & :   "R S  s   A bAb(0b""bb72b/3b/&2c">c c8cA?c'A&c$Ac+*c<c%Ac>5c=A>c:6c*/,c<d8ddA-d;dd(d<A1d+
b
b,/
b>c
c
c'*
c9<
dd
d(+
d9)r   )NN)r   r   r   r   r   r   r   r   r   r   r   r*  rR  r   __classcell__)r   s   @r   r   r      s9    3>
)i Xs/ s/r   r   c                     [        5         [        S[        4[        5      n [	        S5        [	        S[         35        [	        S[         S35        [	        S[         S35        [	        S[         S	35        [	        S
[        5        S[         S35        [	        S[        5        S35        [	        S5         U R                  5         g ! [         a    [	        S5         g f = f)Nz0.0.0.0z@================================================================u1     Betta Bring It — draft relay running on port z/  Control PC (this machine):  http://localhost:z/draftboard.htmlz0                    TV board:  http://localhost:z/board.htmlz0                     TV pick:  http://localhost:z
/pick.htmlz%  Players' phones:            http://ro   r
  z  Lobby join PIN: z(   (set 'joinPin' in Settings to change)z
  stopped.)	r=   r   r   r   r7   r+   rM   serve_foreverKeyboardInterrupt)httpds    r   mainrY    s    LD)73E	(O	=dV
DE	;D6AQ
RS	<TF+
NO	<TF*
MN	1*,qk
RS	y{m+S
TU	(O ns   8C	 	C! C!__main__):r   http.serverhttpr3   rB   rE  r#   r   rH  r   urllib.parser   r   r   dirnameabspath__file__r   rQ   environr5   r8   argvr   r   r2   r$  r%  rK   r   r"  rR   r(  r'  RLockr#  r6   r   r"   r+   r=   rH   rM   rV   rY   rd   rl   rp   rs   r   r   serverThreadingHTTPServerr   SimpleHTTPRequestHandlerr   rY  r   r   r   r   <module>rg     s  2 D C C C +	wwrwwx01
2::>>&!QS]Q5FchhqkDRWW\\$ 34
WW\\$ 12
ggll4!34 JJNN;'16	;
		 $891
fA
 & bA5$pa$++11 aU/dkk22 U/p" zF r   