
    h=                        S SK Jr  S SKJrJrJrJr  S SKJr  S SK	J
r
  S SKJr  S SKJr  S SKJr  S SKJrJr  S S	KJr  S S
KJr  S SKJr  S SKJr  \(       a  S SKJr  1 Skr " S S5      r " S S5      r g)    )annotations)OptionalIterableTYPE_CHECKINGIterator)contextmanager)HandleGenerator)is_valid_handle)	DXFEntity)	DXFObject)
AuditErrorAuditor)DXFInternalEzdxfError)factory)EntityQuery)default_copy)AbstractTagWriter>   EOFCLASSTABLEENDSECENDTABSECTION
ACDSRECORD
ACDSSCHEMAc                      \ rS rSrSr " S S5      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 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 jrS+S jrS,S jrS-S jr\S-S j5       rSS jrS.S jrS/S jrS0S1S jjrSrg)2EntityDB$   zA simple key/entity database.

Every entity/object, except tables and sections, are represented as
DXFEntity or inherited types, these entities are stored in the
DXF document database, database-key is the `handle` as string.

c                  2    \ rS rSrSrSS jrS	S jrS rSrg)
EntityDB.Trashcan-   z8Store handles to entities which should be deleted later.c                D    UR                   U l         [        5       U l        g N)	_databaseset_handles)selfdbs     @/var/www/html/env/lib/python3.13/site-packages/ezdxf/entitydb.py__init__EntityDB.Trashcan.__init__0   s    \\DN&)eDM    c                :    U R                   R                  U5        g)zzPut handle into trashcan to delete the entity later, this is
required for deleting entities while iterating the database.
N)r&   addr'   handles     r)   r.   EntityDB.Trashcan.add4   s     MMf%r,   c                    U R                   nU R                   HE  nUR                  U5      nU(       a!  UR                  (       a  UR	                  5         X!;   d  MC  X	 MG     U R                  R                  5         g)zNRemove handles in trashcan from database and destroy entities if
still alive.
N)r$   r&   getis_alivedestroyclear)r'   r(   r0   entitys       r)   r6   EntityDB.Trashcan.clear:   sW     B--fooNN$<
 ( MM!r,   )r$   r&   N)r(   r   )r0   str)	__name__
__module____qualname____firstlineno____doc__r*   r.   r6   __static_attributes__ r,   r)   Trashcanr    -   s    F	,	&	"r,   rA   c                >    0 U l         [        5       U l        SU l        g )NF)r$   r	   handleslockedr'   s    r)   r*   EntityDB.__init__I   s    /1&(!r,   c                     U R                   U   $ )zYGet entity by `handle`, does not filter destroyed entities nor
entities in the trashcan.
)r$   r/   s     r)   __getitem__EntityDB.__getitem__O   s     ~~f%%r,   c                f   [        U[        5      (       d   [        U5      5       e[        U[        5      (       d   [        U5      5       eUR                  (       d   S5       eU R
                  (       a  [        S5      eUS:X  d  [        U5      (       d  [        SU S35      eX R                  U'   g)zSet `entity` for `handle`.zCan not store destroyed entity.Locked entity database.0zInvalid handle .N)

isinstancer9   typer   r4   rD   r   r
   
ValueErrorr$   )r'   r0   r7   s      r)   __setitem__EntityDB.__setitem__U   s    &#&&4V4&&),,:d6l:,A AA;;'(ABBS= 7 7vha899!'vr,   c                V    U R                   (       a  [        S5      eU R                  U	 g)z[Delete entity by `handle`. Removes entity only from database, does
not destroy the entity.
rK   N)rD   r   r$   r/   s     r)   __delitem__EntityDB.__delitem__a   s#     ;;'(ABBNN6"r,   c                p    Uc  g[        U[        5      (       d   [        U5      5       eXR                  ;   $ )z'``True`` if database contains `handle`.F)rN   r9   rO   r$   r/   s     r)   __contains__EntityDB.__contains__i   s3    >&#&&4V4&''r,   c                ,    [        U R                  5      $ )zCount of database items.)lenr$   rE   s    r)   __len__EntityDB.__len__p   s    4>>""r,   c                "    U R                  5       $ )zZIterable of all handles, does filter destroyed entities but not
entities in the trashcan.
)keysrE   s    r)   __iter__EntityDB.__iter__t   s     yy{r,   c                8    U R                   R                  U5      $ )z_Returns entity for `handle` or ``None`` if no entry exist, does
not filter destroyed entities.
)r$   r3   r/   s     r)   r3   EntityDB.getz   s     ~~!!&))r,   c                ^     U R                   R                  5       nXR                  ;  a  U$ M-  )zReturns next unique handle.)rC   nextr$   r/   s     r)   next_handleEntityDB.next_handle   s+    \\&&(F^^+ r,   c                0    S U R                  5        5       $ )z8Iterable of all handles, does filter destroyed entities.c              3  *   #    U  H	  u  pUv   M     g 7fr#   r@   .0r0   r7   s      r)   	<genexpr> EntityDB.keys.<locals>.<genexpr>        :\>6\   itemsrE   s    r)   r^   EntityDB.keys       :TZZ\::r,   c                0    S U R                  5        5       $ )z9Iterable of all entities, does filter destroyed entities.c              3  *   #    U  H	  u  pUv   M     g 7fr#   r@   ri   s      r)   rk   "EntityDB.values.<locals>.<genexpr>   rm   rn   ro   rE   s    r)   valuesEntityDB.values   rr   r,   c                D    S U R                   R                  5        5       $ )zJIterable of all (handle, entities) pairs, does filter destroyed
entities.
c              3  R   #    U  H  u  pUR                   (       d  M  X4v   M     g 7fr#   r4   ri   s      r)   rk   !EntityDB.items.<locals>.<genexpr>   s%      
"8 V"8s   '
')r$   rp   rE   s    r)   rp   EntityDB.items   s!    
"&.."6"6"8
 	
r,   c                V   UR                  5       [        ;   a0  UR                  R                  b  XUR                  R                  '   gUR                  R                  nUc!  U R	                  5       nUR                  U5        XU'   [        US5      (       a  UR                  U 5        gg)zAdd `entity` to database, assigns a new handle to the `entity`
if :attr:`entity.dxf.handle` is ``None``. Adding the same entity
multiple times is possible and creates only a single database entry.

Nadd_sub_entities_to_entitydb)dxftypeDATABASE_EXCLUDEdxfr0   re   update_handlehasattrr~   r'   r7   r0   s      r)   r.   EntityDB.add   s     >>//zz  , +1VZZ&&'jj''>%%'F  (V 69:://5 ;r,   c                t    UR                   (       a'  XR                  R                  	 UR                  5         gg)z7Remove `entity` from database and destroy the `entity`.N)r4   r   r0   r5   r'   r7   s     r)   delete_entityEntityDB.delete_entity   s(    ??ZZ&&'NN r,   c                   ^  UR                   (       a\  [        US5      (       a  UR                  U 4S j5        UR                  R                  n T R
                  U	 SUR                  l        gg! [         a     gf = f)z?Discard `entity` from database without destroying the `entity`.process_sub_entitiesc                &   > TR                  U 5      $ r#   )discard)er'   s    r)   <lambda>"EntityDB.discard.<locals>.<lambda>   s    dll1or,   N)r4   r   r   r   r0   r$   KeyErrorr   s   `  r)   r   EntityDB.discard   sl    ??v566++,EFZZ&&FNN6*$(

!   s   A0 0
A=<A=c                $   UR                   nUc   S5       eU R                  5       nUR                  [        S9nX4R                  l        [        R                  " XB5        [        U[        5      (       a  UR                  R                  U5        U$ )a  Duplicates `entity` and its sub entities (VERTEX, ATTRIB, SEQEND)
and store them with new handles in the entity database.
Graphical entities have to be added to a layout by
:meth:`~ezdxf.layouts.BaseLayout.add_entity`. DXF objects will
automatically added to the OBJECTS section.

A new owner handle will be set by adding the duplicated entity to a
layout.

Raises:
    CopyNotSupported: copying of `entity` is not supported

zvalid DXF document required)copy_strategy)docre   copyr   r   r0   r   bindrN   r   objects
add_object)r'   r7   r   
new_handle
new_entitys        r)   duplicate_entityEntityDB.duplicate_entity   sv     jj= ==%%'
 &, G
 *Z%j),,KK"":.r,   c           
     t   U R                   SL d   S5       e/ nU R                  5        nU R                  5        H  u  pE[        U5      (       dD  UR	                  [
        R                  SUR                  5        SU S3S9  UR                  U5        XER                  R                  S5      :w  d  My  SU R                  U'   UR                  U5        UR                  U5        M     SSS5        U R                  5         U H  nUR                  R                  S5      nUc2  UR	                  [
        R                  SUR                  5        S	3S9  MS  [        U5      (       a  US
:X  a5  UR	                  [
        R                  SUR                  5        SU S3S9  M  XPU'   M     g! , (       d  f       N= f)zRestore database integrity:

- restore database entries with modified handles (key != entity.dxf.handle)
- remove entities with invalid handles
- empty trashcan - destroy all entities in the trashcan
- removes destroyed database entries (purge)

FzDatabase is locked!Removed entity z with invalid handle "z" from entity database.)codemessager0   Nz% without handle from entity database.rL   )rD   trashcanrp   r
   fixed_errorr   INVALID_ENTITY_HANDLEr   r.   r   r3   r$   appendpurge)r'   auditoradd_entitiestrashr0   r7   s         r)   auditEntityDB.audit   s    {{e#:%::#]]_"&**,&v..'''=="1&..2B1C D##)(*A!C ( 
 IIf%ZZ^^H55 .2DNN6*IIf% ''/ #/ $ 	

"FZZ^^H-F~###99-fnn.>-? @, - $ 
 "6**fm###99-fnn.>-? @%h&=? $ 
 !L! #) _s   BF)35F))
F7c                ,    [         R                  U 5      $ )zOReturns a new trashcan, empty trashcan manually by: :
func:`Trashcan.clear()`.
)r   rA   rE   s    r)   new_trashcanEntityDB.new_trashcan  s       &&r,   c              #  T   #    U R                  5       nUv   UR                  5         g7f)z_Returns a new trashcan in context manager mode, trashcan will be
emptied when leaving context.
N)r   r6   )r'   	trashcan_s     r)   r   EntityDB.trashcan  s&     
 %%'	 	s   &(c                    U R                   nUR                  5        VVs/ s H  u  p#UR                  (       a  M  UPM     nnnU H  nX	 M     gs  snnf )zNRemove all destroyed entities from database, but does not empty the
trashcan.
N)r$   rp   r4   )r'   r(   r0   r7   dead_handless        r)   r   EntityDB.purge  sD    
 ^^57XXZWZ>6vZW"F
 # Xs
   AAc                B    [        S U R                  5        5       5      $ )Nc              3  @   #    U  H  oR                  5       v   M     g 7fr#   )r   )rj   r7   s     r)   rk   ,EntityDB.dxf_types_in_use.<locals>.<genexpr>*  s     @->>##-s   )r%   rv   rE   s    r)   dxf_types_in_useEntityDB.dxf_types_in_use)  s    @$++-@@@r,   c                    X R                   ;   a  gU R                  U5        X!R                  l        U R	                  U5        g)zlTry to reset the entity handle to a certain value.
Returns ``True`` if successful and ``False`` otherwise.

FT)r$   r   r   r0   r.   r   s      r)   reset_handleEntityDB.reset_handle,  s6    
 ^^#V"

r,   c                X    [        S U R                  R                  5        5       U5      $ )zEntity query over all entities in the DXF document.

Args:
    query: query string

.. seealso::

    :ref:`entity query string` and :ref:`entity queries`

c              3  J   #    U  H  oR                   (       d  M  Uv   M     g 7fr#   rz   rj   r   s     r)   rk   !EntityDB.query.<locals>.<genexpr>C  s     M'>!**AA'>   #	#)r   r$   rv   )r'   querys     r)   r   EntityDB.query8  s$     Mt~~'<'<'>MuUUr,   )r$   rC   rD   NreturnNone)r0   r9   r   r   )r0   r9   r7   r   r   r   )r0   r9   r   r   r0   r9   r   boolr   int)r   zIterator[str])r0   r9   r   zOptional[DXFEntity])r   r9   )r   zIterable[str])r   Iterable[DXFEntity])r   zIterable[tuple[str, DXFEntity]]r7   r   r   r   )r7   r   r   r   )r   r   )r   r    )r   zset[str])r7   r   r0   r9   r   r   )*)r   r9   r   r   )r:   r;   r<   r=   r>   rA   r*   rH   rQ   rT   rW   r[   r_   r3   re   r^   rv   rp   r.   r   r   r   r   r   r   r   r   r   r   r   r?   r@   r,   r)   r   r   $   s    " "8"&
(#(#*;;
6.20"d'  A
V Vr,   r   c                      \ rS rSrSrSSS jjrSS jrSS jrSS j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S jjrSS jrS S jrSrg)!EntitySpaceiF  a\  
An :class:`EntitySpace` is a collection of :class:`~ezdxf.entities.DXFEntity`
objects, that stores only  references to :class:`DXFEntity` objects.

The :class:`~ezdxf.layouts.Modelspace`, any :class:`~ezdxf.layouts.Paperspace`
layout and :class:`~ezdxf.layouts.BlockLayout` objects have an
:class:`EntitySpace` container to store their entities.

Nc                P    U(       a  [        S U 5       5      U l        g / U l        g )Nc              3  J   #    U  H  oR                   (       d  M  Uv   M     g 7fr#   rz   r   s     r)   rk   'EntitySpace.__init__.<locals>.<genexpr>S  s     3Hq

Hr   listentities)r'   r   s     r)   r*   EntitySpace.__init__Q  s#    7?D3H33 	EG 	r,   c                (    S U R                    5       $ )z5Iterable of all entities, filters destroyed entities.c              3  J   #    U  H  oR                   (       d  M  Uv   M     g 7fr#   rz   r   s     r)   rk   'EntitySpace.__iter__.<locals>.<genexpr>X  s     7=aJJ=r   r   rE   s    r)   r_   EntitySpace.__iter__V  s    74==77r,   c                     U R                   U   $ )a^  Get entity at index `item`

:class:`EntitySpace` has a standard Python list like interface,
therefore `index` can be any valid list indexing or slicing term, like
a single index ``layout[-1]`` to get the last entity, or an index slice
``layout[:10]`` to get the first 10 or fewer entities as
``list[DXFEntity]``. Does not filter destroyed entities.

r   r'   indexs     r)   rH   EntitySpace.__getitem__Z  s     }}U##r,   c                ,    [        U R                  5      $ )z/Count of entities including destroyed entities.)rZ   r   rE   s    r)   r[   EntitySpace.__len__f  s    4==!!r,   c                x   ^ [        T[        5      (       d   [        T5      5       e[        U4S jU  5       5      $ )z@``True`` if `handle` is present, does filter destroyed entities.c              3  T   >#    U  H  oR                   R                  T:H  v   M     g 7fr#   )r   r0   )rj   r   r0   s     r)   rk   )EntitySpace.has_handle.<locals>.<genexpr>m  s     84a55<<6)4s   %()rN   r9   rO   anyr/   s    `r)   
has_handleEntitySpace.has_handlej  s0    &#&&4V4&84888r,   c                $    [        U 5      U l        g)z0Remove all destroyed entities from entity space.Nr   rE   s    r)   r   EntitySpace.purgeo  s    T
r,   c                    [        U[        5      (       d   [        U5      5       eUR                  (       d   S5       eU R                  R                  U5        g)zAdd `entity`.z Can not store destroyed entitiesN)rN   r   rO   r4   r   r   r   s     r)   r.   EntitySpace.adds  sB    &),,:d6l:,B BBV$r,   c                8    U H  nU R                  U5        M     g)zAdd multiple `entities`.N)r.   )r'   r   r7   s      r)   extendEntitySpace.extendy  s    FHHV r,   c                J    [        U 5       H  nUR                  U5        M     g)zBExport all entities into DXF file by `tagwriter`.

(internal API)
N)iter
export_dxf)r'   	tagwriterr7   s      r)   r   EntitySpace.export_dxf~  s     
 4jFi( !r,   c                :    U R                   R                  U5        g)zRemove `entity`.N)r   remover   s     r)   r   EntitySpace.remove  s    V$r,   c                "    [        5       U l        g)zRemove all entities.Nr   rE   s    r)   r6   EntitySpace.clear  s     r,   c                8    U R                   R                  U5      $ r#   )r   popr   s     r)   r   EntitySpace.pop  s    }}  ''r,   c                :    U R                   R                  X5        g r#   )r   insert)r'   r   r7   s      r)   r   EntitySpace.insert  s    U+r,   c                l   UR                   R                  n/ nU  HZ  nUR                  R                  nXB" U5      Ld  M%  UR	                  [
        R                  SU S35        UR                  U5        M\     U(       d  g U H.  nU R                  R                  U5        UR                  5         M0     g )Nr   z8 with a conflicting handle and without a database entry.)entitydbr3   r   r0   r   r   REMOVED_INVALID_DXF_OBJECTr   r   r   _silent_kill)r'   r   db_getr   r7   r0   s         r)   r   EntitySpace.audit  s    !!%%!# FZZ&&FVF^+ ##99%fX .& '
 V$   FMM  ( !	 r,   r   r#   )r   zOptional[Iterable[DXFEntity]])r   zIterator[DXFEntity])r   r   r   r   r   )r   r   r   r   )r   r   r   r   r   ))r   r   r   r   )r   r   r7   r   r   r   )r   r   r   r   )r:   r;   r<   r=   r>   r*   r_   rH   r[   r   r   r.   r   r   r   r6   r   r   r   r?   r@   r,   r)   r   r   F  sM    

8
$"9
#%
)%
(,"r,   r   N)!
__future__r   typingr   r   r   r   
contextlibr   ezdxf.tools.handler	   ezdxf.lldxf.typesr
   ezdxf.entities.dxfentityr   ezdxf.entities.dxfobjr   ezdxf.auditr   r   ezdxf.lldxf.constr   ezdxf.entitiesr   ezdxf.queryr   ezdxf.entities.copyr   ezdxf.lldxf.tagwriterr   r   r   r   r@   r,   r)   <module>r     s]    #  & . - . + + 3 " # ,7	 _V _VD	j" j"r,   