
    >Tf{f                        d dl Z d dlmZ d dlmZ d dlmZ d dlmZ d dl	m
Z
 d dlmZmZ d dlmZ d d	lmZ d d
lmZ d dlmZ d dlT d dlT d dlmZ d dlmZ d dlmZmZ d dl m!Z!m"Z" d dl#m$Z$ d dl%m&Z&m'Z' d dl(m)Z)m*Z* ddl+m,Z, ddl-m.Z.m/Z/ ddl0m1Z1 ddl2m3Z3 dZ4 G d de1e          Z5 G d de5          Z6 G d de          Z7 G d  d!e!e"e5          Z8 G d" d#e          Z9dS )$    N)cached_property)settings)GenericRelation)
ArrayField)ValidationError)MaxValueValidatorMinValueValidator)models)Count)reverse)gettext_lazy)*)RackElevationSVG)ColorChoices)OrganizationalModelPrimaryModel)ContactsMixinImageAttachmentsMixin)to_grams)array_to_stringdrange)
ColorFieldNaturalOrderingField   )	PowerPort)DeviceModule)WeightMixin)	PowerFeed)RackRackReservationRackRoleRackTypec                   .   e Zd ZdZ ej        eej         ed           ed                    Z	 ej        e
 ed           ed           ee          g ed                    Z ej        e ed	           ed          g ed
                    Z ej        d ed           ed                    Z ej         ed          dd ed                    Z ej         ed          dd ed                    Z ej         ed          ded          Z ej         ed          dd ed                    Z ej         ed          dd ed                    Z ej        dd          Z G d d          ZdS ) RackBasez/
    Base class for RackType & Rack. Holds
    widthzRail-to-rail width)choicesdefaultverbose_name	help_textz
height (U)r   zHeight in rack units)r(   r)   
validatorsr*   zstarting unitzStarting unit for rackFzdescending unitsz Units are numbered top-to-bottom)r(   r)   r*   zouter widthTzOuter dimension of rack (width))r)   blanknullr*   zouter depthzOuter dimension of rack (depth)z
outer unit2   r)   
max_lengthr'   r,   zmounting depthz~Maximum depth of a mounted device, in millimeters. For four-post racks, this is the distance between the front and rear rails.z
max weightz"Maximum load capacity for the rack)r,   r-   c                       e Zd ZdZdS )RackBase.MetaTN)__name__
__module____qualname__abstract     6/var/www/html/netbox-4.1.3/netbox/dcim/models/racks.pyMetar2   q   s        r8   r:   N)r3   r4   r5   __doc__r
   PositiveSmallIntegerFieldRackWidthChoices
WIDTH_19IN_r&   RACK_U_HEIGHT_DEFAULTr	   r   RACK_U_HEIGHT_MAXu_heightRACK_STARTING_UNIT_DEFAULTstarting_unitBooleanField
desc_unitsouter_widthouter_depth	CharFieldRackDimensionUnitChoices
outer_unitmounting_depthPositiveIntegerField
max_weightPositiveBigIntegerField_abs_max_weightr:   r7   r8   r9   r%   r%   (   s         -F,  +QwZZ!())	  E 0v/%Q|__%%a((*;*;<M*N*NO!*++	  H 5F4*Q''%%a(()!,--	  M %$Q)**!677  J 3&2Q}%%!566	  K 3&2Q}%%!566	  K "!Q|__(	  J 6V5Q'((1$
 
	  N -,Q|__!899	  J 5f4  O
         r8   r%   c                   \    e Zd ZdZ ej        ed ed                    Z ej	        dej
        d          Z ej         ed          d	
          Z ej         ed          d	d          ZdZdZ G d d          Zd Zd Zed             Z fdZ fdZed             Z xZS )r#   
    Devices are housed within Racks. Each rack has a defined height measured in rack units, and a front and rear face.
    Each Rack is assigned to a Site and (optionally) a Location.
    r.   form factor)r'   r0   r)   dcim.Manufacturer
rack_typesto	on_deleterelated_namemodeld   r)   r0   slugT)r)   r0   unique)manufacturerform_factorr&   rB   rF   rG   rH   rK   rL   weightrN   weight_unit)rT   c                       e Zd ZdZ ej        dd           ej        dd          fZ ed          Z ed          Z	dS )	RackType.Metar_   rZ   z1%(app_label)s_%(class)s_unique_manufacturer_modelfieldsname)r_   r]   z0%(app_label)s_%(class)s_unique_manufacturer_slugz	rack typez
rack typesN
r3   r4   r5   orderingr
   UniqueConstraintconstraintsr?   r)   verbose_name_pluralr7   r8   r9   r:   rd      su        ,#F#0H   $F#/G  	
 q~~aoor8   r:   c                     | j         S N)rZ   selfs    r9   __str__zRackType.__str__   s
    zr8   c                 0    t          d| j        g          S )Nzdcim:racktypeargsr   pkrp   s    r9   get_absolute_urlzRackType.get_absolute_url       dgY7777r8   c                 $    | j          d| j         S )N re   rp   s    r9   	full_namezRackType.full_name   s    #22dj222r8   c                    t                                                       | j        | j        #| j        st          t          d                    | j        r#| j        st          t          d                    d S d S )N5Must specify a unit when setting an outer width/depth1Must specify a unit when setting a maximum weight)	supercleanrG   rH   rK   r   r?   rN   rb   )rq   	__class__s    r9   r   zRackType.clean   s     (D,<,HRVRa,H!!$["\"\]]] ? 	Z4#3 	Z!!$W"X"XYYY	Z 	Z 	Z 	Zr8   c                 ~   | j         r'| j        r t          | j         | j                  | _        nd | _        | j        | j        d| _         t                      j        |i | | j	        
                                D ]>}|                                 |                                 |                                 ?d S N )rN   rb   r   rP   rG   rH   rK   r   saveracksallsnapshotcopy_racktype_attrs)rq   ru   kwargsrackr   s       r9   r   zRackType.save   s    ? 	(t/ 	(#+DOT=M#N#ND  #'D  #(8(@ DOd%f%%% JNN$$ 	 	DMMOOO$$&&&IIKKKK	 	r8   c                     | j         r5t          t          j        | j                  | j        | j        z   d          S t          | j        t          j        d          z   | j        z   dz
  d| j        z   dz
  d          S z?
        Return a list of unit numbers, top to bottom.
              ?r   g      ࿩rF   r   decimalDecimalrD   rB   rp   s    r9   unitszRackType.units   {    
 ? 	h'/$*<==t}tOa?acfgggdmgoc&:&::T=OORSSUX[_[mUmpqUqswxxxr8   )r3   r4   r5   r;   r
   rI   RackFormFactorChoicesr?   r`   
ForeignKeyPROTECTr_   rZ   	SlugFieldr]   clone_fieldsprerequisite_modelsr:   rr   rx   propertyr|   r   r   r   __classcell__r   s   @r9   r#   r#   u   s         #&"%Q}%%  K
 %6$.!  L
 FQwZZ  E 6QvYY  DL. . . . . . . .  8 8 8 3 3 X3	Z 	Z 	Z 	Z 	Z    & y y Xy y y y yr8   r#   c                   h    e Zd ZdZ e ed          ej                  Z G d d          Z	d Z
dS )r"   zH
    Racks can be organized by functional role, similar to Devices.
    color)r)   r(   c                   >    e Zd ZdZ ed          Z ed          ZdS )RackRole.Meta)rh   z	rack rolez
rack rolesNr3   r4   r5   rj   r?   r)   rm   r7   r8   r9   r:   r      s0        q~~aoor8   r:   c                 0    t          d| j        g          S )Nzdcim:rackrolert   rv   rp   s    r9   rx   zRackRole.get_absolute_url   ry   r8   N)r3   r4   r5   r;   r   r?   r   
COLOR_GREYr   r:   rx   r7   r8   r9   r"   r"      s~          JQwZZ'  E
. . . . . . . .
8 8 8 8 8r8   r"   c            
           e Zd ZdZdZ ej        edd ed                    Z	 ej
        dej        ddd	          Z ej         ed
          d          Z ed
dd          Z ej        ddd ed           ed                    Z ej
        dej        d          Z ej
        dej        ddd	          Z ej
        dej        ddd	          Z ej         ed          deej                  Z ej
        dej        ddd ed                    Z ej        dd ed                    Z ej        dddd ed           ed                    Z ej         ed          ded           Z ed!d"d#d$%          Zd&Zd'Z  G d( d)          Z!d* Z"d+ Z# fd,Z$ fd-Z%d. Z&e'd/             Z(d0 Z)d1e*j+        d1dfd2Z,d<d5Z-d6 Z.e*j+        d1d1d1e/e0dd1d1f	d7Z1d8 Z2d9 Z3d: Z4e5d;             Z6 xZ7S )=r    rR   )r`   r&   rB   rD   rF   rG   rH   rK   rL   ra   rb   rN   r.   TrS   )r'   r0   r,   r)   zdcim.RackTyper   rW   rX   rY   r,   r-   rh   r[   r\   )target_fieldr0   r,   zfacility IDzLocally-assigned identifier)r0   r,   r-   r)   r*   	dcim.SiterV   zdcim.Locationtenancy.Tenantstatus)r)   r0   r'   r(   zdcim.RackRolezFunctional role)rW   rX   rY   r,   r-   r*   zserial number)r0   r,   r)   z	asset tagz'A unique tag used to identify this rack)r0   r,   r-   r^   r)   r*   airflowr/   zipam.VLANGroup
scope_typescope_idr   )rW   content_type_fieldobject_id_fieldrelated_query_name)sitelocationtenantr   roler`   r&   r   rB   rF   rG   rH   rK   rL   ra   rN   rb   )r   c                       e Zd ZdZ ej        dd           ej        dd          fZ ed          Z ed          Z	d	S )
	Rack.Meta)r   r   _namerw   )r   rh   z,%(app_label)s_%(class)s_unique_location_namerf   )r   facility_idz3%(app_label)s_%(class)s_unique_location_facility_idr   r   Nri   r7   r8   r9   r:   r   Z  sw        6 $F#+C   $F#2J  

 qyyajjr8   r:   c                 B    | j         r| j         d| j          dS | j        S )Nz ())r   rh   rp   s    r9   rr   zRack.__str__j  s1     	7i664#36666yr8   c                 0    t          d| j        g          S )Nz	dcim:rackrt   rv   rp   s    r9   rx   zRack.get_absolute_urlo  s    {$'3333r8   c                    t                                                       | j        rQ| j        rJ| j        j        | j        k    r5t	          t          d                              | j                            | j        | j        #| j	        st	          t          d                    | j
        r#| j        st	          t          d                    | j        j        sft          j                            |                               d                              d          }|                                x}rY|j        |j        j        z   | j        z
  }| j        |k     r2t	          d	t          d
                              |          i          |                                x}rG| j        |j        k    r7t	          dt          d                              |j                  i          | j        rN| j        j        | j        k    r;t	          dt          d                              | j                  i          d S d S d S )Nz6Assigned location must belong to parent site ({site}).)r   r~   r   r   T)position__isnullpositionrB   zNRack must be at least {min_height}U tall to house currently installed devices.)
min_heightrD   zZRack unit numbering must begin at {position} or less to house currently installed devices.r   r   z,Location must be from the same site, {site}.)r   r   r   r   r   r?   formatrG   rH   rK   rN   rb   _stateaddingr   objectsfilterexcludeorder_bylastr   device_typerB   rD   first)rq   mounted_devices
top_devicer   last_devicer   s        r9   r   z
Rack.cleanr  st    9 	v 	v4=+=+J+J!!$\"]"]"d"djnjs"d"t"tuuu (D,<,HRVRa,H!!$["\"\]]] ? 	Z4#3 	Z!!$W"X"XYYY{! 	$n333>>FFX\F]]ffgqrrO -11333z '0:3I3RRUYUgg
=:--)"A&v$w$w$~$~  KU$~  %V  %V+   
 .33555{ %(<<<)' ,J *K *KKQ6[f[o6KpKp+    } =%22)"A&T$U$U$\$\bfbk$\$l$l+   -	 	( 22r8   c                     |                                   | j        r'| j        r t          | j        | j                  | _        nd | _        | j        | j        d| _         t                      j	        |i | d S r   )
r   rN   rb   r   rP   rG   rH   rK   r   r   )rq   ru   r   r   s      r9   r   z	Rack.save  s      """ ? 	(t/ 	(#+DOT=M#N#ND  #'D  #(8(@ DOd%f%%%%%r8   c           	      t    | j         r.| j        D ](}t          | |t          | j         |                     'dS dS )zO
        Copy physical attributes from the assigned RackType (if any).
        N)	rack_typeRACKTYPE_FIELDSsetattrgetattr)rq   
field_names     r9   r   zRack.copy_racktype_attrs  s\     > 	O"2 O O
j'$.**M*MNNNN	O 	OO Or8   c                     | j         r5t          t          j        | j                  | j        | j        z   d          S t          | j        t          j        d          z   | j        z   dz
  d| j        z   dz
  d          S r   r   rp   s    r9   r   z
Rack.units  r   r8   c                 J    t           j                            | j                  S ro   )RackStatusChoicescolorsgetr   rp   s    r9   get_status_colorzRack.get_status_color  s     '++DK888r8   Nc                    i }| j         D ]5}|dz  sd|                     d          d         nd| }|||ddd||<   6| j        j        skt          j                            dd	d
                              t          d                    	                    |          
                    | dd          
                    t          |          t          d          z            }g }	|0| j                            |d                              dd          }	|D ]}
|rMt          |
j        |
j        |
j        j        z   d          D ]#}|	|
j        |	v r|
||         d<   d||         d<   $Q|	|
j        |	v r|
||
j                 d<   d||
j                 d<   |
j        j        ||
j                 d<   d |                                D             S )a3  
        Return a list of rack units as dictionaries. Example: {'device': None, 'face': 0, 'id': 48, 'name': 'U48'}
        Each key 'device' is either a Device or None. By default, multi-U devices are repeated for each U they occupy.

        :param face: Rack face (front or rear)
        :param user: User instance to be used for evaluating device view permissions. If None, all devices
            will be included.
        :param exclude: PK of a Device to exclude (optional); helpful when relocating a Device within a Rack
        :param expand_devices: When True, all units that a device occupies will be listed with each containing a
            reference to the device. When False, only the bottom most unit for a device is included and that unit
            contains a height attribute for the device
        r   U.r   NF)idrh   facedeviceoccupiedr   device_type__manufacturerr   
devicebays)devicebay_countrw   )r   position__gtdevice_type__u_height__gt)r   T)device_type__is_full_depthviewrw   )flatr   r   r   heightc                     g | ]}|S r7   r7   .0us     r9   
<listcomp>z'Rack.get_rack_units.<locals>.<listcomp>  s    ...a...r8   )r   splitr   r   r   r   prefetch_relatedannotater   r   r   Qdevicesrestrictvalues_listr   r   r   rB   rw   values)rq   userr   r   expand_devices	elevationr   u_namer   permitted_device_idsr   s              r9   get_rack_unitszRack.get_rack_units  sG    	 	 	A23a%DWWW]]3''**WWWF! IaLL {! "	W n55+  h %l 3 3   g   f*+    ftqDAAAA  " $& '+|'<'<T6'J'J'V'VW[bf'V'g'g$! 
W 
W! 	W#FOV_vGYGb5bdghh 8 8<698L+L+L5;IaL237	!Z008
 |vy4H'H'H?E	&/28<=AIfo.z:;A;M;VIfo.x88..9++--....r8   r   Fc           
         | j                             d                              d          }|r|                    d          }||                    |          }t	          | j                  }|D ]l}||j        |k    s|j        j        rQt          |j
        |j
        |j        j        z   d          D ](}	 |                    |           # t          $ r Y %w xY wmg }	|D ]]}t          t          ||t          j        |          z   d                                        |          r|	                    |           ^t	          t'          |	                    S )	a  
        Return a list of units within the rack available to accommodate a device of a given U height (default 1).
        Optionally exclude one or more devices when calculating empty units (needed when moving a device from one
        position to another within a rack).

        :param u_height: Minimum number of contiguous free units required
        :param rack_face: The face of the rack (front or rear) required; 'None' if device is full depth
        :param exclude: List of devices IDs to exclude (useful when moving a device within a rack)
        :param ignore_excluded_devices: Ignore devices that are marked to exclude from utilization calculations
        r   r   )position__gteT)%device_type__exclude_from_utilizationN)pk__inr   )r   r   r   r   listr   r   r   is_full_depthr   r   rB   remove
ValueErrorsetr   r   issubsetappendreversed)
rq   rB   	rack_facer   ignore_excluded_devicesr   r   dr   available_unitss
             r9   get_available_unitszRack.get_available_units  sy    ,//>>EETUEVV" 	RooDoQQGooWo55G TZ    	 	A AFi$7$71=;V$7
AJ9O,OQTUU  AQ%   
  	* 	*A6!Q!:!::C@@AAJJ5QQ *&&q)))H_--...s   ;C
CCc                 `    i }| j                                         D ]}|j        D ]}|||<   |S )zf
        Return a dictionary mapping all reserved units within the rack to their reservation.
        )reservationsr   r   )rq   reserved_unitsreservationr   s       r9   get_reserved_unitszRack.get_reserved_units%  sQ     ,0022 	0 	0K & 0 0$/q!!0r8   c
                 \    t          | ||||||||		  	        }
|
                    |          S )a(  
        Return an SVG of the rack elevation

        :param face: Enum of [front, rear] representing the desired side of the rack elevation to render
        :param user: User instance to be used for evaluating device view permissions. If None, all devices
            will be included.
        :param unit_width: Width in pixels for the rendered drawing
        :param unit_height: Height of each rack unit for the rendered drawing. Note this is not the total
            height of the elevation
        :param legend_width: Width of the unit legend, in pixels
        :param margin_width: Width of the rigth-hand margin, in pixels
        :param include_images: Embed front/rear device images where available
        :param base_url: Base URL for links and images. If none, URLs will be relative.
        )
unit_widthunit_heightlegend_widthmargin_widthr   include_imagesbase_urlhighlight_params)r   render)rq   r   r   r  r  r  r  r  r  r  r   s              r9   get_elevation_svgzRack.get_elevation_svg/  sI    4 %!#%%)-

 

 

	 %%%r8   c                 8    | j                             d          S )Nr   r   )r   r   rp   s    r9   get_0u_deviceszRack.get_0u_devicesW  s    |""A"...r8   c                 R   t          t          | j                            }|                     dd          }|                                 D ]2}t          ||dz   d          D ]}||v r|                    |           3|t          |          z
  }t          |          |z  dz  }|S )z
        Determine the utilization rate of the rack and return it as a percentage. Occupied and reserved units both count
        as utilized.
        r   T)rB   r  r   r[   )lenr  r   r  r  r   r  float)rq   total_unitsr  rur   occupied_unit_count
percentages          r9   get_utilizationzRack.get_utilizationZ  s     $tz**++22CY]2^^ ))++ 	. 	.BBQ,, . .''#**1---. *C,@,@@.//+=C
r8   c                 0   t           j                            |           }t          d |D                       }|sdS g }|D ]&}|                    d |j        D                        't          d |D                       }t          ||z  dz  d          S )zd
        Determine the utilization rate of power in the rack and return it as a percentage.
        r   c              3   $   K   | ]}|j         V  d S ro   )available_power)r   pfs     r9   	<genexpr>z-Rack.get_power_utilization.<locals>.<genexpr>s  s%      #L#L2B$6#L#L#L#L#L#Lr8   r   c                 <    g | ]}t          |t                    |S r7   )
isinstancer   )r   peers     r9   r   z.Rack.get_power_utilization.<locals>.<listcomp>y  s7       D)9T9T  r8   c                 B    g | ]}|                                 d          S )	allocated)get_power_draw)r   	powerports     r9   r   z.Rack.get_power_utilization.<locals>.<listcomp>}  s6     
 
 
8AI$$&&{3
 
 
r8   r[   r   )r   r   r   sumextend
link_peersround)rq   
powerfeedsavailable_power_total
powerports	powerfeedallocated_draws         r9   get_power_utilizationzRack.get_power_utilizationn  s     &--4-88
 ##L#L#L#L#L L L$ 	1
# 	 	I  !*!5        
 
EO
 
 
   ^&;;cA1EEEr8   c                    t          d | j                            d                              d          D                       }|t          d t          j                            |                               d                              d          D                       z  }| j        r
|| j        z  }t          |d	z  d
          S )Nc              3   .   K   | ]}|j         j        V  d S ro   )r   _abs_weight)r   r   s     r9   r.  z$Rack.total_weight.<locals>.<genexpr>  s<       
 
 *
 
 
 
 
 
r8   T) device_type___abs_weight__isnullr   c              3   .   K   | ]}|j         j        V  d S ro   )module_typerB  )r   modules     r9   r.  z$Rack.total_weight.<locals>.<genexpr>  s<       
 
 *
 
 
 
 
 
r8   )device__rack) module_type___abs_weight__isnullrE  i     )	r6  r   r   r   r   r   r   rB  r9  )rq   total_weights     r9   rJ  zRack.total_weight  s     
 
,..PT.UUffgtuu
 
 
 
 
 	 
 
 .//T/BBWdW;;m,,	
 
 
 
 
 	
  	-D,,L\D(!,,,r8   )r   NNF)8r3   r4   r5   r;   r   r
   rI   r   r?   r`   r   r   r   rh   r   r   r   r   SET_NULLr   r   r   STATUS_ACTIVEr   r   serial	asset_tagRackAirflowChoicesr   r   vlan_groupsr   r   r:   rr   rx   r   r   r   r   r   r   DeviceFaceChoices
FACE_FRONTr   r  r  #RACK_ELEVATION_DEFAULT_LEGEND_WIDTH#RACK_ELEVATION_DEFAULT_MARGIN_WIDTHr  r!  r)  r?  r   rJ  r   r   s   @r9   r    r       sS        
O
 #&"%Q}%%	  K "!.  I 6QvYY  D !   E
 #&"Q}%%!122  K 6.  D
 !v /  H V.  F VQx[[!!/	  F 6.!%&&  D VQ''  F
 ! Q{^^!=>>  I fQy\\"	  G "/'"!	  KL) ) ) ) ) ) ) )   
4 4 4' ' ' ' 'R& & & & &O O O y y Xy9 9 9 #'->-ISWhl =/ =/ =/ =/~&/ &/ &/ &/P   #-<<!&& && && &&P/ / /  (F F F* - - _- - - - -r8   r    c                   ~    e Zd ZdZ ej        dej        d          Z e e	d           ej
                              Z ej        dej        dd	d	
          Z ej        ej        ej                  Z ej         e	d          d          ZdZdZ G d d          Zd Zd Z fdZed             Z xZS )r!   z3
    One or more reserved units within a Rack.
    	dcim.Rackr  rV   r   )r)   
base_fieldr   rackreservationsTr   )rW   rX   description   r\   )r   r   r   )rV  c                   B    e Zd ZddgZ ed          Z ed          ZdS )RackReservation.Metacreatedrw   zrack reservationzrack reservationsNr   r7   r8   r9   r:   r\    s;        t$q+,,a 344r8   r:   c                 6    d                     | j                  S )NzReservation for rack {})r   r   rp   s    r9   rr   zRackReservation.__str__  s    (//	:::r8   c                 0    t          d| j        g          S )Nzdcim:rackreservationrt   rv   rp   s    r9   rx   z RackReservation.get_absolute_url  s    -TWI>>>>r8   c           
          t                                                       t           d          r j        r	 fd j        D             }|rZt	          dt          d                               j        j        d	                    d |D                                 i          g  j        j
                             j                  D ]}|j        z  fd	 j        D             }|rSt	          dt          d
                              d	                    d |D                                 i          d S d S d S )Nr   c                 0    g | ]}|j         j        v|S r7   )r   r   )r   r   rq   s     r9   r   z)RackReservation.clean.<locals>.<listcomp>  s'    OOO1aty6N6NQ6N6N6Nr8   r   z/Invalid unit(s) for {height}U rack: {unit_list}z, c                 ,    g | ]}t          |          S r7   strr   s     r9   r   z)RackReservation.clean.<locals>.<listcomp>  s    ,K,K,KSVV,K,K,Kr8   )r   	unit_listr   c                     g | ]}|v |	S r7   r7   )r   r   r  s     r9   r   z)RackReservation.clean.<locals>.<listcomp>  s#     N N Nq!~:M:M:M:M:Mr8   z;The following units have already been reserved: {unit_list}c                 ,    g | ]}t          |          S r7   rc  r   s     r9   r   z)RackReservation.clean.<locals>.<listcomp>  s    ,O,O,OSVV,O,O,Or8   )re  )r   r   hasattrr   r   r?   r   r   rB   joinr  r   rw   )rq   invalid_unitsresvconflicting_unitsr  r   s   `   @r9   r   zRackReservation.clean  s   4   	TZ 	 POOO
OOOM %QPQQXX#y1"&)),K,K],K,K,K"L"L Y  '     N	.66$'6BB - -$*, N N N NDJ N N N  %Q\]]dd"&)),O,O=N,O,O,O"P"P e  '   %	 	 	 	" r8   c                 *    t          | j                  S ro   )r   r   rp   s    r9   re  zRackReservation.unit_list  s    tz***r8   )r3   r4   r5   r;   r
   r   CASCADEr   r   r?   r<   r   r   r   r   AUTH_USER_MODELr   rI   rY  r   r   r:   rr   rx   r   r   re  r   r   s   @r9   r!   r!     s         6.#  D
 JQwZZ36355  E V.'  F 6#.  D #&"Q}%%  K
 .L5 5 5 5 5 5 5 5
; ; ;? ? ?    6 + + X+ + + + +r8   r!   ):r   	functoolsr   django.confr   "django.contrib.contenttypes.fieldsr   django.contrib.postgres.fieldsr   django.core.exceptionsr   django.core.validatorsr   r	   	django.dbr
   django.db.modelsr   django.urlsr   django.utils.translationr   r?   dcim.choicesdcim.constantsdcim.svgr   netbox.choicesr   netbox.modelsr   r   netbox.models.featuresr   r   utilities.conversionr   utilities.datar   r   utilities.fieldsr   r   device_componentsr   r   r   r   mixinsr   powerr   __all__r%   r#   r"   r    r!   r7   r8   r9   <module>r     s    % % % % % %             > > > > > > 5 5 5 5 5 5 2 2 2 2 2 2 G G G G G G G G       " " " " " "       6 6 6 6 6 6         % % % % % % ' ' ' ' ' ' ; ; ; ; ; ; ; ; G G G G G G G G ) ) ) ) ) ) 2 2 2 2 2 2 2 2 = = = = = = = = ( ( ( ( ( ( # # # # # # # #            J J J J J{L J J JZ_y _y _y _y _yx _y _y _yL8 8 8 8 8" 8 8 8$d- d- d- d- d-=/ d- d- d-NJ+ J+ J+ J+ J+l J+ J+ J+ J+ J+r8   