+
    #j                         R t ^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt ^ RI	H
t
 RtR R ltR R	 ltR
 t]R8X  d
   ]! 4        R# R#   ] d&    ]! R4       ]! R4       ]P                  ! ^4        LNi ; i)a  
Upload an .excalidraw file to excalidraw.com and print a shareable URL.

No account required. The diagram is encrypted client-side (AES-GCM) before
upload -- the encryption key is embedded in the URL fragment, so the server
never sees plaintext.

Requirements:
    pip install cryptography

Usage:
    python upload.py <path-to-file.excalidraw>

Example:
    python upload.py ~/diagrams/architecture.excalidraw
    # prints: https://excalidraw.com/#json=abc123,encryptionKeyHere
N)AESGCMz5Error: 'cryptography' package is required for upload.z)Install it with: pip install cryptographyz(https://json.excalidraw.com/api/v2/post/c                0    V ^8  d   QhR\         R\         /# )   buffersreturn)bytes)formats   "c/opt/hermes-venv/lib/python3.14/site-packages/../../../skills/creative/excalidraw/scripts/upload.py__annotate__r
   '   s      U u     c            	         \         P                  ! R^4      .pV  FC  pVP                  \         P                  ! R\        V4      4      4       VP                  V4       KE  	  RP	                  V4      # )z
Build the Excalidraw v2 concat-buffers binary format.

Layout: [version=1 (4B big-endian)] then for each buffer:
        [length (4B big-endian)] [data bytes]
z>Ir   )structpackappendlenjoin)r   partsbufs   *  r	   concat_buffersr   '   sX     [[q!"EV[[s3x01S  88E?r   c                0    V ^8  d   QhR\         R\         /# )r   excalidraw_jsonr   )str)r   s   "r	   r
   r
   5   s     0? 0?C 0?C 0?r   c                   \         P                  ! / 4      P                  R4      pV P                  R4      p\        W4      p\        P
                  ! V4      p\        P                  ! ^4      p\        P                  ! ^4      p\        V4      pVP                  WdR4      p\         P                  ! R^RRRR/4      P                  R4      p	\        WV4      p
\        P                  P                  \        V
RR	7      p\        P                  P                  V^R
7      ;_uu_ 4       pVP                  ^8w  d   \!        RVP                   24      h\         P"                  ! VP%                  4       P'                  R4      4      pRRR4       XP)                  R4      pV'       g   \!        RV 24      h\*        P,                  ! V4      P/                  R4      P'                  R4      pRV RV 2#   + '       g   i     Ls; i)z
Encrypt and upload Excalidraw JSON to excalidraw.com.

Args:
    excalidraw_json: The full .excalidraw file content as a string.

Returns:
    Shareable URL string.
utf-8Nversioncompressionzpako@1
encryptionzAES-GCMPOST)datamethod)timeoutzUpload failed with HTTP idz&Upload returned no file ID. Response:    =asciizhttps://excalidraw.com/#json=,)jsondumpsencoder   zlibcompressosurandomr   encrypturllibrequestRequest
UPLOAD_URLurlopenstatusRuntimeErrorloadsreaddecodegetbase64urlsafe_b64encoderstrip)r   file_metadata
data_bytesinner_payload
compressedraw_keyivaesgcm	encryptedencoding_metapayloadreqrespresultfile_idkey_b64s   &               r	   uploadrJ   5   s    JJrN))'2M ''0J"==M }-J jjnG	BBG_Frt4I JJ1xi   vg	  ]	:G ..
 
 '&
 
IC			R		0	0D;;#!9$++GHHDIIK..w78 
1
 jjGCF8LMM &&w/66t<CCGLG*7)1WI>> 
1	0s   'AG//G?	c                     \        \        P                  4      ^8  d"   \        R4       \        P                  ! ^4       \        P                  ^,          p \
        P                  P                  V 4      '       g%   \        RV  24       \        P                  ! ^4       \        V RRR7      ;_uu_ 4       pVP                  4       pRRR4        \        P                  ! X4      pRX9  d   \        R	4       \        X4      p\        V4       R#   + '       g   i     LQ; i  \        P                   d/   p\        RT 24       \        P                  ! ^4        Rp?L{Rp?ii ; i)
r   z1Usage: python upload.py <path-to-file.excalidraw>zError: File not found: rr   )encodingNzError: File is not valid JSON: elementszCWarning: File does not contain an 'elements' key. Uploading anyway.)r   sysargvprintexitr*   pathisfileopenr5   r%   r4   JSONDecodeErrorrJ   )	file_pathfcontentdoceurls         r	   mainr]   h   s    
388}qABI77>>)$$'	{34	iw	/	/1&&( 
0jj!
 ST
/C	#J 
0	/  /s34s$   6DD# D 	#E&8$E!!E&__main__)__doc__r%   r*   r   rO   r(   r8   urllib.requestr-   +cryptography.hazmat.primitives.ciphers.aeadr   ImportErrorrQ   rR   r0   r   rJ   r]   __name__ r   r	   <module>re      s   $  	  
   B 8
0?f8 zF M  	
AB	
56HHQKs   A	 	)A54A5