
    hK                       S SK Jr  S SKJrJrJrJrJrJr  S SK	r	S SK
Jr  S SKJrJr  S SKJr  S SKJrJr  S SKJrJrJrJrJr  S S	KJrJrJrJrJrJ r J!r!  S S
K"J#r#J$r$J%r%  S SK&J'r'  \(       a   S SK(J)r)  S SKJ*r*J+r+  S SK,J-r-  S SK.J/r/  S SK0J1r1  \	Rd                  " S5      r3SS jr4SS jr5SS jr6\" 5       r7 " S S5      r8g)    )annotations)TYPE_CHECKINGIterableIteratorUnioncastOptionalN)ParseException)Auditor
AuditError)BlockLayout)const	validator)DXFBlockInUseErrorDXFKeyErrorDXFStructureErrorDXFTableEntryErrorDXFTypeError)AttribBlockBlockRecordEndBlkentity_linkerfactoryis_graphic_entity)UVecNULLVECVec3)ARROWS)Drawing)	DXFEntityDXFTagStorage)EntityDB)AbstractTagWriter)Tableezdxfc                
   U R                  5       n [        U 5      (       a  g[        R                  " U 5      (       a  gU R	                  S5      (       a0  [        R
                  " [        R                  " U 5      5      (       a  gg)NT_F)upperis_anonymous_blockr   is_ezdxf_arrow
startswithis_acad_arrow
arrow_namenames    G/var/www/html/env/lib/python3.13/site-packages/ezdxf/sections/blocks.pyis_special_blockr2   .   sd    ::<D $ T""s 1 1$ 788    c                Z    [        U 5      S:  =(       a    U S   S:H  =(       a    U S   S;   $ )N   r   *UEXDAT)lenr/   s    r1   r*   r*   @   s-     t9q=CT!W^CQ80CCr3   c                f   U R                   R                  SS5      nU(       a  U$ U R                   R                  SS5      nU(       d  gU R                  nUbY  UR                  bL  UR                  R                  U5      n[	        U[
        5      (       a  UR                   R                  SS5      $ g)Nr0    owner)dxfgetdocentitydb
isinstancer   )blockr0   r;   r>   block_records        r1   recover_block_namerC   J   s    99==$DIIMM'2&E
))C 3<<3||''.lK00##''33r3   c                  N   \ rS rSrSr  S   SS jjrS r\SS j5       r\	S S j5       r
\	S!S j5       rS"S	 jrS
 rS#S jrS$S jrS%S jrS&S jrS'S jrS(S jrS)S jrS*S'S jjrS+S jr\S4     S,S jjrS\4     S-S jjrS.S jrS/S jrS0S1S jjrS2S jrS3S jrSrg)4BlocksSection^   za
Manages BLOCK definitions in a dict(), block names are case insensitive
e.g. 'Test' == 'TEST'.

Nc                f    Xl         Ub  U R                  U5        U R                  5         SU l        g )Nr   )r>   load#_reconstruct_orphaned_block_records_anonymous_block_counter)selfr>   entitiess      r1   __init__BlocksSection.__init__e   s/    
 IIh002()%r3   c                ,    [        U R                  5      $ N)r8   block_recordsrK   s    r1   __len__BlocksSection.__len__p   s    4%%&&r3   c                d    [        U [        5      (       d  U R                  n U R                  5       $ rP   )r@   strr0   lower)entitys    r1   keyBlocksSection.keys   s$    &#&&[[F||~r3   c                .    U R                   R                  $ rP   )r>   rQ   rR   s    r1   rQ   BlocksSection.block_recordsy   s    xx%%%r3   c                .    U R                   R                  $ rP   )r>   r?   rR   s    r1   r?   BlocksSection.entitydb}   s    xx   r3   c                "  ^^         SU4S jjnSU4S jjnU R                   m[        STS   5      nUR                  5       S:w  d  UR                  S   S:w  a  [	        S5      eTS	 / n[
        nU" 5        GH  n[        U[        5      (       a2  U[
        La  [        R                  S	5        UnUR                  5         MK  [        U[        5      (       Ga  U[
        L a  [        R                  S
5        OUR                  R                  SS5      nUR                  R                  SS5      n	U(       d>  [        U5      nU(       a,  [        R                  SU SU	 S35        XR                  l        U(       aJ  U" XgU5      n
[        U
["        5      (       a  U R%                  U
5        O3[        R                  SU	 S35        O[        R                  SU	 S35        [
        nUR                  5         GM  UR'                  U5        GM     g)zt
Load DXF entities into BlockLayouts. `entities` is a list of
entity tags, separated by BLOCK and ENDBLK entities.

c           	       >  [        STR                  U R                  R                  5      5      nUR                  X5        U H  nUR                  U5        M     U$ ! [         a3    [        STR                  U R                  R                  SS0S95      n Ni[         a#    [        SU R                  R                   35      ef = f)Nr   scaler   )
dxfattribsz"Invalid or missing name of BLOCK #)r   r=   r<   r0   r   newr   r   handle	set_block
add_entity)rA   endblkblock_entitiesrB   rX   rQ   s        r1   load_block_record-BlocksSection.load.<locals>.load_block_record   s    
#M=3D3DUYY^^3TU ""51(''/ ) & #!!%%eiinn'1%N    '89I9I8JK s   /A :C,Cc               3  Z   >#    [        5       n T H  nU " U5      (       a  M  Uv   M     g 7frP   )r   )linkedrX   rL   s     r1   link_entities)BlocksSection.load.<locals>.link_entities   s'     "_F" f~~ L #s   +	+r"   r   SECTIONr5   )   BLOCKSz+Critical structure error in BLOCKS section.z*Missing required ENDBLK, ignoring content.z9Found ENDBLK without a preceding BLOCK, ignoring content.r0   r:   rd   z<undefined>zRecovered block name "z" for block #.z#Ignoring invalid BLOCK definition #zIgnoring BLOCK without name #N)rA   r   rg   r   rh   list[DXFEntity]returnzBlockRecord | None)rt   zIterable['DXFEntity'])rQ   r   dxftype
base_classr   _MISSING_BLOCK_r@   r   loggerwarningclearr   r<   r=   rC   infor0   r   addappend)rK   rL   ri   rm   section_headcontentrA   rX   
block_namerd   rB   rQ   s    `         @r1   rH   BlocksSection.load   s   	 	 	  ,	   		 2	! **OXa[9!Y.,2I2I!2L Q
 3
 $$QRRQK#%&#oF&%((/NN#OPFF++O+NNS "'vr!:J"YY]]8]CF%%7%>
%"KK"8MRXQYYZ [ .8IIN!'8'P%lK@@ HH\2"NN"EfXQ O )Fvha'PQ+E v&I &r3   c                :   U R                    H  nUR                  b  M  [        R                  " SUR                  R
                  SS.U R                  S9n[        R                  " S0 U R                  S9nUR                  X#5        U R                  U5        M     g)zFind BLOCK_RECORD entries without block definition in the blocks
section and create block definitions for this orphaned block records.

NBLOCK)r   r   r   )r0   
base_point)rb   r>   ENDBLK)	rQ   rA   r   create_db_entryr<   r0   r>   re   r|   )rK   rB   rA   rg   s       r1   rI   1BlocksSection._reconstruct_orphaned_block_records   s    
 !..L!!)// , 0 0 5 5&/   !00!
 &&u5&! /r3   c                    UR                  S5        U R                   H+  n[        U[        5      (       d   eUR	                  U5        M-     UR                  SS5        g )Nz  0
SECTION
  2
BLOCKS
r   ENDSEC)	write_strrQ   r@   r   export_block_definition
write_tag2)rK   	tagwriterrB   s      r1   
export_dxfBlocksSection.export_dxf   sT    9: ..LlK888800; / 	Q)r3   c                    [        U5      nX!l        U R                  R                  UR                  R
                  5      (       d   eU$ )zQAdd or replace a block layout object defined by its block record.
(internal API)
)r   block_layoutrQ   	has_entryr<   r0   )rK   rB   r   s      r1   r|   BlocksSection.add   sC     #<0$0!!!++L,<,<,A,ABBBBr3   c                (    S U R                    5       $ )z<Iterable of all :class:`~ezdxf.layouts.BlockLayout` objects.c              3  8   #    U  H  oR                   v   M     g 7frP   )r   ).0rB   s     r1   	<genexpr>)BlocksSection.__iter__.<locals>.<genexpr>  s     Q>Pl))>Ps   )rQ   rR   s    r1   __iter__BlocksSection.__iter__  s    Qd>P>PQQr3   c                8    U R                   R                  U5      $ )zFReturns ``True`` if :class:`~ezdxf.layouts.BlockLayout` `name`
exist.
)rQ   r   rK   r0   s     r1   __contains__BlocksSection.__contains__  s     !!++D11r3   c                     [        SU R                  R                  U5      5      nUR                  $ ! [         a    [        U5      ef = f)zeReturns :class:`~ezdxf.layouts.BlockLayout` `name`,
raises :class:`DXFKeyError` if `name` not exist.
r   )r   rQ   r=   r   r   r   )rK   r0   rB   s      r1   __getitem__BlocksSection.__getitem__  sJ    	$t/A/A/E/Ed/KLL,,,! 	$d##	$s	   03 A	c                b    X;   a  U R                   R                  U5        g[        SU S35      e)z|Deletes :class:`~ezdxf.layouts.BlockLayout` `name` and all of
its content, raises :class:`DXFKeyError` if `name` not exist.
Block "" does not exist.N)rQ   remover   r   s     r1   __delitem__BlocksSection.__delitem__  s2     <%%d+v->?@@r3   c                p    [        U R                  R                  R                  R	                  5       5      $ )z"Returns a list of all block names.)listr>   rQ   entrieskeysrR   s    r1   block_namesBlocksSection.block_names  s&    DHH**22779::r3   c                J     U R                  U5      $ ! [         a    Us $ f = f)z[Returns :class:`~ezdxf.layouts.BlockLayout` `name`, returns
`default` if `name` not exist.
)r   r   )rK   r0   defaults      r1   r=   BlocksSection.get#  s,    	##D)) 	N	s    ""c                H    U R                   R                  U   R                  $ )z=Returns a block layout by block record handle. (internal API))r>   r?   r   )rK   block_record_handles     r1   get_block_layout_by_handle(BlocksSection.get_block_layout_by_handle,  s    xx  !45BBBr3   c                   U R                   c   e[        [        U R                   R                  R	                  U5      5      nU=(       d    0 nUR
                  R                  US'   XS'   [        U5      US'   [        R                  " SX0R                   5      n[        R                  " SSUR
                  R                  0U R                   S9nUR                  XV5        U R                  U5      $ )zCreate and add a new :class:`~ezdxf.layouts.BlockLayout`, `name`
is the BLOCK name, `base_point` is the insertion point of the BLOCK.
r;   r0   r   r   r   )r>   )r>   r   r   rQ   rc   r<   rd   r   r   r   re   r|   )rK   r0   r   rb   rB   headtails          r1   rc   BlocksSection.new0  s     xx###K)?)?)C)CD)IJ%2
*..55
7!6#'
#3
< &&w
HHE&&w 0 0 7 78dhh
 	t*xx%%r3   Uc                l    U R                  U5      nU R                  X2S[        R                  05      nU$ )aA  Create and add a new anonymous :class:`~ezdxf.layouts.BlockLayout`,
`type_char` is the BLOCK type, `base_point` is the insertion point of
the BLOCK.

    ========= ==========
    type_char Anonymous Block Type
    ========= ==========
    ``'U'``   ``'*U###'`` anonymous BLOCK
    ``'E'``   ``'*E###'`` anonymous non-uniformly scaled BLOCK
    ``'X'``   ``'*X###'`` anonymous HATCH graphic
    ``'D'``   ``'*D###'`` anonymous DIMENSION graphic
    ``'A'``   ``'*A###'`` anonymous GROUP
    ``'T'``   ``'*T###'`` anonymous block for ACAD_TABLE content
    ========= ==========

flags)anonymous_block_namerc   r   BLK_ANONYMOUS)rK   	type_charr   r   rA   s        r1   new_anonymous_block!BlocksSection.new_anonymous_blockG  s4    & ..y9
'5;N;N1OPr3   c                     U =R                   S-  sl         SU U R                    3nU R                  R                  U5      (       d  U$ MJ  )aJ  Create name for an anonymous block. (internal API)

Args:
    type_char: letter

        U = *U### anonymous blocks
        E = *E### anonymous non-uniformly scaled blocks
        X = *X### anonymous hatches
        D = *D### anonymous dimensions
        A = *A### anonymous groups
        T = *T### anonymous ACAD_TABLE content

r5   r6   )rJ   rQ   r   )rK   r   r   s      r1   r   "BlocksSection.anonymous_block_name^  sQ     ))Q.)YK(E(E'FGJ%%//
;;!!	 r3   c                    [        [        U R                  R                  U5      5      nUR	                  U5        U R                  R                  X5        U R                  U5        g)zRename :class:`~ezdxf.layouts.BlockLayout` `old_name` to `new_name`

.. warning::

    This is a low-level tool and does not rename the block references,
    so all block references to `old_name` are pointing to a non-existing
    block definition!

N)r   r   rQ   r=   renamereplacer|   )rK   old_namenew_namerB   s       r1   rename_blockBlocksSection.rename_blockr  sO     K););)?)?)IJH%""8:r3   c                @   U(       a  U R                   c   S5       eU R                   R                  R                  U5      nUc  [        SU S35      eUR                  (       d  gUR
                  (       a  [        SU S35      e[        U5      (       a  [        SU S35      eSU S	3n U R                   R                  U5      n[        U5      (       a  [        SU S35      eU R                  U5        g! [         a    [        R                  S
U S35         gf = f)a  Delete block.

Applies some safety checks when `safe` is ``True``.
A :class:`DXFBlockInUseError` will be raised for:

    - blocks with active references
    - blocks representing existing layouts
    - special blocks used internally

Args:
    name: block name (case-insensitive)
    safe: apply safety checks

Raises:
    DXFKeyError: if block not exists
    DXFBlockInUseError: when safe is ``True`` and block is in use
Nzvalid DXF document requiredr   r   z " represents an existing layout.zSpecial block "z," maybe used without explicit INSERT entity.zINSERT[name=="z"]iz Parsing error in query string: ""z" is still in use.)r>   blocksr=   r   is_aliveis_any_layoutr   r2   queryr
   rx   errorr8   r   )rK   r0   saferA   query_string
block_refss         r1   delete_blockBlocksSection.delete_block  s"   $ 88'F)FF'HHOO''-E}!GD61B"CDD>>""(dV#CD   %%(%dV+WX  ,D65L!XX^^L9

 :(74&8J)KLL " ?~QOPs   +C7 7#DDc                  ^ U R                   c   e[        S U R                   R                  S5       5       5      mSU4S jjn[        5       nU  HV  n[        R                  " UR
                  5      nUR                  (       a  M6  U" U5      (       d  ME  UR                  U5        MX     U H  nU R                  U5        M     g)a  Delete all blocks without references except modelspace- or
paperspace layout blocks, special arrow- and anonymous blocks
(DIMENSION, ACAD_TABLE).

.. warning::

    There could exist references to blocks which are not documented in the DXF
    reference, hidden in extended data sections or application defined data,
    which could invalidate a DXF document if these blocks will be deleted.

Nc              3  v   #    U  H/  n[         R                  " UR                  R                  5      v   M1     g 7frP   )r   make_table_keyr<   r0   )r   rX   s     r1   r   2BlocksSection.delete_all_blocks.<locals>.<genexpr>  s-       
2 $$VZZ__552s   79INSERTc                0   > [        U 5      (       a  gU T;  $ )NF)r2   )r0   active_referencess    r1   is_safe0BlocksSection.delete_all_blocks.<locals>.is_safe  s    %%000r3   r0   rV   rt   bool)	r>   setr   r   r   r0   r   r|   r   )rK   r   trashrA   r0   r   s        @r1   delete_all_blocksBlocksSection.delete_all_blocks  s     xx###  
((..2 
 

	1
 E++EJJ7D&&&74==		$ 
 DT" r3   c                H   U R                   UR                   L d   S5       eU R                   GH  n[        U[        5      (       d   eUR                  R
                  n/ nUR                  nU GHl  n[        U5      (       dT  UR                  [        R                  S[        U5       SUR                  R                   S3S9  UR                  U5        Oh[        U[        5      (       aS  UR                  [        R                  S[        U5       SUR                  R                   S3S9  UR                  U5        UR                   (       d  M  UR                  R"                  U:w  d  M  UR                  [        R$                  S[        U5       S	UR                  R"                   S
U SUR                  R                   S3	S9  UR'                  U5        GMo     U H(  nUR                   (       d  M   UR)                  U5        M*     GM     g! [*         a     M?  f = f)a  Audit and repair BLOCKS section.

.. important::

    Do not delete entities during the auditing process as this will alter
    the entity database while iterating it, instead use::

        auditor.trash(entity)

    to delete invalid entities after auditing automatically.

z#Auditor for different DXF document.zRemoved invalid DXF entity z from BLOCK 'z'.)codemessagezRemoved standalone z entity from BLOCK 'zRemoved DXF entity z with invalid owner handle (#z != #z) from BLOCK 'N)r>   rQ   r@   r   r<   rd   entity_spacer   fixed_errorr   REMOVED_INVALID_GRAPHIC_ENTITYrV   r0   r   r    REMOVED_STANDALONE_ATTRIB_ENTITYr   r;   (REMOVED_ENTITY_WITH_INVALID_OWNER_HANDLEr}   r   
ValueError)rK   auditorrB   r   unlink_entitiesesrX   s          r1   auditBlocksSection.audit  s    xx7;;&M(MM& ..LlK8888'3'7'7'>'>/1O**B(00'''FF"=c&k] K##/#3#3#8#8"9!= ( 
 MM&)// '''HH"5c&k] C##/#3#3#8#8"9!= ( 
 MM&)::##'::'''PP"5c&k] C$$*JJ$4$4#5U;N:O P''3'7'7'<'<&=R!A (  $**62; > *???		&) *K /R & s   8H
H! H!)rJ   r>   )NN)r>   zOptional[Drawing]rL   zOptional[list[DXFEntity]])rX   zUnion[str, BlockLayout]rt   rV   )rt   r%   )rt   r#   )rL   rs   rt   None)r   r$   rt   r   )rB   r   rt   r   )rt   zIterator[BlockLayout]r   )r0   rV   rt   r   )r0   rV   rt   r   )rt   z	list[str]rP   )r   rV   rt   r   )r0   rV   r   r   rt   r   )r   rV   r   r   rt   r   )r   rV   rt   rV   )r   rV   r   rV   rt   r   )T)r0   rV   r   r   rt   r   )rt   r   )r   r   rt   r   ) __name__
__module____qualname____firstlineno____doc__rM   rS   staticmethodrY   propertyrQ   r?   rH   rI   r   r|   r   r   r   r   r   r=   r   r   rc   r   r   r   r   r   r   __static_attributes__ r3   r1   rE   rE   ^   s    "&.2	*	* ,	*'  
 & & ! !X't'.*R2$A;C #	&& &
 
&0  #w04	."(*X#@9r3   rE   r   )rA   r   rt   rV   )9
__future__r   typingr   r   r   r   r   r	   logging	pyparsingr
   ezdxf.auditr   r   ezdxf.layouts.blocklayoutr   ezdxf.lldxfr   r   ezdxf.lldxf.constr   r   r   r   r   ezdxf.entitiesr   r   r   r   r   r   r   
ezdxf.mathr   r   r   ezdxf.render.arrowsr   ezdxf.documentr    r!   r"   ezdxf.entitydbr#   ezdxf.lldxf.tagwriterr$   ezdxf.sections.tabler%   	getLoggerrx   r2   r*   rC   rw   rE   r   r3   r1   <module>r     s    #   $ + 1 (    + * &&7'7*			7	#$D" 'h hr3   