
    <iH1                         S r SSKJ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JrJr  SSKr	SSKJrJrJrJrJr  / SQr1 SkrS	 rS
 rS rS rSS jrS rS rg)zSTIX2 core versioning methods.    )MappingN)detect_spec_versionget_timestampis_scoparse_into_datetime   )InvalidValueErrorObjectNotVersionableErrorRevokeErrorTypeNotVersionableErrorUnmodifiablePropertyError)createdcreated_by_refidtype>   r   revokedmodifiedc                     U(       a  X::  a  U [         R                  " SS9-   nU$ [         R                  " SS9nX-
  U:  a  X-   nU$ )a  
Ensures a new modified timestamp is newer than the old.  When they are
too close together, new_modified must be pushed further ahead to ensure
it is distinct and later, after JSON serialization (which may mean it's
actually being pushed a little ways into the future).  JSON serialization
can remove precision, which can cause distinct timestamps to accidentally
become equal, if we're not careful.

:param old_modified: A previous "modified" timestamp, as a datetime object
:param new_modified: A candidate new "modified" timestamp, as a datetime
    object
:param use_stix21: Whether to use STIX 2.1+ versioning timestamp precision
    rules (boolean).  This is important so that we are aware of how
    timestamp precision will be truncated, so we know how close together
    the timestamps can be, and how far ahead to potentially push the new
    one.
:return: A suitable new "modified" timestamp.  This may be different from
    what was passed in, if it had to be pushed ahead.
r   )microseconds)milliseconds)dt	timedelta)old_modifiednew_modified
use_stix21one_mss       J/home/james-whalen/.local/lib/python3.13/site-packages/stix2/versioning.py_fudge_modifiedr      sQ    ( ''",,A*FFL 	 1-&/'0L    c                 (   Sn[        U [        5      (       az  [        U [        R                  R                  5      (       a  SnU$ [        U [        R
                  R                  5      (       a  SnU$ [        U [        5      (       a  [        U 5      nU$ )a  
Bit of factored out functionality for getting/detecting the STIX version
of the given value.

:param data: An object, e.g. _STIXBase instance or dict
:return: The STIX version as a string in "X.Y" notation, or None if the
    version could not be determined.
N2.02.1)	
isinstancer   stix2v20_STIXBase20v21_STIXBase21dictr   )datastix_versions     r   _get_stix_versionr,   ;   s     L$   dEII1122 L  eii3344 L  d##.t4Lr   c                    SnSn[        U [        5      (       a  [        U 5      n[        U [        R                  R
                  5      (       a"  [        R                  U R                  5      nX4$ [        U [        5      (       aZ  [        R                  R                  U R                  S5      U5      nU(       a"  [        R                  UR                  5      nX4$ SnX4$ )a  
Determine whether type of the given object is versionable.  This check is
done on the basis of support for three properties for the object type:
"created", "modified", and "revoked".  If all three are supported, the
object type is versionable; otherwise it is not.  Dicts must have a "type"
property.  This is used in STIX version detection and to determine a
complete set of supported properties for the type.

If a dict is passed whose "type" is unregistered, then this library has no
knowledge of the type.  It can't determine what properties are "supported".
This function will be lax and treat the type as versionable.

Note that this support check is not sufficient for creating a new object
version.  Support for the versioning properties does not mean that
sufficient properties are actually present on the object.

Also, detect whether it represents a STIX 2.1 or greater spec version.

:param data: The object to check.  Must be either a stix object, or a dict
    with a "type" property.
:return: A 2-tuple: the first element is True if the object is versionable
    and False if not; the second is the STIX version as a string in "X.Y"
    notation.
FNr   T)r#   r   r,   r$   base	_STIXBase_VERSIONING_PROPERTIESissubset_propertiesr)   registryclass_for_typeget)r*   is_versionabler+   clss       r   _is_versionable_typer8   S   s    4 NL$  (. dEJJ00113<<  N* ''# d##
 ..//0@,OC!7!@!@OO" '' "&''r   c                     [        U [        5      (       a^  U R                  5       [        :  a  [	        U 5      nU$ [        U 5      u  p!U(       a  SU ;   nU(       d  [        U 5      e U$ [        U 5      e[        U 5      e)ac  
Determine whether there are or may be sufficient properties present on
an object to allow versioning.  Raises an exception if the object can't be
versioned.

Also detect STIX spec version.

:param data: The object to check, e.g. dict with a "type" property, or
    _STIXBase instance
:return: True if the object is STIX 2.1+, or False if not
:raises TypeNotVersionableError: If the object didn't have the versioning
    properties and the type was found to not support them
:raises ObjectNotVersionableError: If the type was found to support
    versioning but there were insufficient properties on the object
r   )r#   r   keysr0   r,   r8   r
   r   )r*   r+   is_versionable_typer6   s       r   _check_versionable_objectr<      s      $  99;00 -T2L( # 1ET0J-" "+d!2%3D99 &  .d33 &d++r   c           
      D   [        U 5      nU R                  S5      (       a  [        S5      e [        R                  " U R
                  5      n/ n[        U S5      (       a  [        R                  " U S   SS 5      nUR                  [        R                  :X  av  UR                  S:X  af  [        U [        R                  R                   5      (       a  U R"                  nO$[        R$                  R'                  U S   US	5      nUR(                  n[+        5       n[,        R.                  " [0        U5       H  n	X;   d  M
  UR3                  U	5        M     U(       a  [5        U5      eUS:X  a  S
OSn
U R                  S5      =(       d    U R                  S5      n[7        USU
S9n[9        U 5      nSU;   a!  [7        US   SU
S9nX::  a  [;        USS5      eO[=        5       n[?        XUS:g  5      nXS'   URA                  U5        [        U [        R                  RB                  5      (       a  Uc  U RD                  US'   OXS'   U" S0 URG                  5        VVs0 s H  u  pUc  M
  X_M     snnD6$ ! [         a    [        R                  " U 5      n GNJf = fs  snnf )as  
Create a new version of a STIX object, by modifying properties and
updating the ``modified`` property.

:param data: The object to create a new version of.  Maybe a stix2 object
    or dict.
:param allow_custom: Whether to allow custom properties on the new object.
    If True, allow them (regardless of whether the original had custom
    properties); if False disallow them; if None, auto-detect from the
    object: if it has custom properties, allow them in the new version,
    otherwise don't allow them.
:param kwargs: The properties to change.  Setting to None requests property
    removal.
:return: The new object.
r   new_versionr"   r   iN   r   observablesminexactr   r   millisecond)	precisionprecision_constrainta  The new modified datetime cannot be before than or equal to the current modified datetime.It cannot be equal, as according to STIX 2 specification, objects that are different but have the same id and modified timestamp do not have defined consumer behavior.r!   allow_custom )$r<   r5   r   copydeepcopy_innerAttributeErrorr   uuidUUIDvariantRFC_4122versionr#   r$   r.   _Observable	__class__r3   r4   _id_contributing_propertiesset	itertoolschainSTIX_UNMOD_PROPERTIESaddr   r   r   r	   r   r   updater/   
has_customitems)r*   rF   kwargsr+   new_obj_innersco_locked_propsuuid_r7   unchangable_propertiesproprE   r   r   kvs                  r   r>   r>      si   " -T2Lxx	-((,dkk2 dE		$t*ST*+==DMM)emmq.@$

 6 677nnnn33L,  #>> U 57GH>"&&t, I '(>?? %1E$95w88J'>488I+>L&1L
 t*CV*:-!5
 '#Ze  ( %&(=
 *z  $

,,--,0OOM.),8.) K=#6#6#8J#841A$!$#8JKKO  ,d+,N Ks    I5 	J)J5 JJc                     [        U [        5      (       d  [        S5      eU R                  S5      (       a  [	        S5      e[        U SS9$ )zbRevoke a STIX object.

Returns:
    A new version of the object with ``revoked`` set to ``True``.
zWcannot revoke object of this type! Try a dictionary or instance of an SDO or SRO class.r   revokeT)r   )r#   r   
ValueErrorr5   r   r>   )r*   s    r   re   re     sL     dG$$2
 	

 xx	(##tT**r   c                     U S   R                  S5      (       a  gU  Vs0 s H  oR                  S5      (       d  M  US_M     nnU(       a  [        U 4SS0UD6nU$ U $ s  snf )a  Remove any custom STIX objects or properties.

Warnings:
    This function is a best effort utility, in that it will remove custom
    objects and properties based on the type names; i.e. if "x-" prefixes
    object types, and "x\_" prefixes property types. According to the
    STIX2 spec, those naming conventions are a SHOULDs not MUSTs, meaning
    that valid custom STIX content may ignore those conventions and in
    effect render this utility function invalid when used on that STIX
    content.

Args:
    stix_obj (dict OR python-stix obj): a single python-stix object
                                         or dict of a STIX object

Returns:
    A new version of the object with any custom content removed
r   zx-Nx_rF   F)
startswithr>   )stix_objrb   custom_propsnew_objs       r   remove_custom_stixrm   ,  sx    ( ""4(( A\\$/ 	4  
 hKUKlK s
   AA)N) __doc__collections.abcr   rH   datetimer   rU   rL   
stix2.baser$   stix2.registrystix2.utilsr   r   r   r   	stix2.v20
exceptionsr	   r
   r   r   r   rW   r0   r   r,   r8   r<   r>   re   rm   rG   r   r   <module>rv      sn    $ #          D ; B08(v)X^LB+"#r   