
    1Gj                        d Z ddlZddlZddlZddlZddlZddlZddlZddl	Zddl
mZ d Zd ZdmdZ ee          j        Zej                            d ee                     ddlZddlZddlZedz  Z eed	          5 Ze                    d
            ej        e                                          Zddd           n# 1 swxY w Y   dZej         !                    ed ee                    Z"ej         #                    e"          Z$ e%ee$j&                   e$ej'        e<    e(dd           ddlm)Z* e*j+        Z,d Z-e-e*_+         e(dd           e-Z.d Z/e/e*_+         e(dd           e$j0        Z1dndZ2d Z3d Z4e2e$_0         e5e$d          re3e$_6         e(dd           n e(dd           e$j7        j8        Z9	 	 dodZ:e:e$j7        _8         e(dd           e$j7        j;        Z<	 	 	 	 dpd Z=e=e$j7        _;         e(d!d           e$j>        j?        Z@d" ZAd# ZBe$j>        jC        ZDd$ ZEe:ZF	 	 dqd%ZGeGe$j7        _8         e(d&d           eAe$j>        _?        eBe$j>        _B        eEe$j>        _E         e(d'd           e$jH        jI        ZJ	 drd)ZKeKe$jH        _I         e(d*d           d+ ZLeLe$j>        _M         e(d,d           dZN e5e$j>        d-          re$j>        jO        ZNeNrd. ZPePe$j>        _O         e(d/d           n e(d0d            e5e$j7        d1          rUe$j7        jQ        ZRd2 ZSeSe$j7        _Q         e5e$j7        d3          re$j7        jT        ZUd4 ZVeVe$j7        _T         e(d5d           n e(d6d            e(d7d           ddl
mZW ddlXZYe$jZ        Z[ eWej        \                    e[                    Z]d8 Z^ e^e]          Z_ e`e$d9d          Zaeard: Zbebe$_c         e(d;d           e_r e(d<e] d=d           e[Zd eW eYje                              d>z  d?z  Zfefg                                r]ddlhZi	  eijj         eef           ee]d?z                        e(d@d           na# ek$ rZl e(dAel d           Y dZl[lnFdZl[lww xY wn< eW eYje                              d>z  Z]	 e]m                    ddB           n=# ek$ r5  eW ejn                              dCz  Z]e]m                    ddB           Y nw xY w ee]dDz            ZdddlhZi	  eijj        e[ed            e(dEe[ d           n"# ek$ rZl e(dFel d           Y dZl[lndZl[lww xY wede$_Z         e(dGed d           dHD ]M\  ZoZp e5e$eo          r<e]epz  Zqeqm                    ddB            ere$eoeq            e(dIeo dJeq d           N e(dKd           ddlZsddlm)Zt e$j7        ju        ZvdL Zwewe$j7        _u         e(dMd            e(dNd            e5e$dO          r eWe$jx                  ne]d?z  Zyeyg                                r	 eyz                    dPQ          Z{ ej        e{          Z|g Z}g Z~ ee|                                          D ]$\  ZZe                    dRd          Zerej        g                    e          se                    dSd          ZerAej        g                    e          r' e(dTe dUd           e~                    e           n( e(dVe dWe d           e}                    e           e                    dXg           ZdY epg D             Z ee           eepg           k    r-eedX<    e(dZe dJ ee           d[ ee           d           &e}D ]Ze|e= e}se~rNey                     ej        e|d\d]^          dPQ            e(d_ ee}           d` ee~           d           n e(da ee|           dbd           n/# ek$ rZl e(dcel d           Y dZl[lndZl[lww xY w e(ddd            e(ded            e(dfd            e(dfd           edgk    re$H                                Ze$                    dhe$j        fe$j>                  Zee_        ee$_         e(did            e(dj ej         ej                               dke$j         d           	 e                                 dS # e$ r9  e(dld           e                                 e                                 Y dS w xY wdS )su  
Wrapper script for digital_human_server_v2.pyc
v11.4: Training auto-clone removed; voice library 100% clone with smart noise handling

CRITICAL CHANGES (v11.4):
1. REMOVED: Auto voice cloning during digital human training (Patch 11.1)
   - Training now only extracts audio + copies video (original pyc behavior)
   - Voice cloning is done exclusively through the voice library
2. Smart noise detection: analyze noise floor before deciding to denoise
   - Clean audio (< -55dB noise floor) → use raw original (preserves 100% timbre)
   - Noisy audio → single-pass light denoise (nr=6) + loudnorm only if needed
3. Clone quality tightened: temp=0.3, top_k=5, top_p=0.5 (tighter sampling)
   - Lower temperature = model stays closer to reference distribution
   - Smaller top_k/top_p = only high-confidence tokens used
4. Voice library upload: ref_text auto-transcription for accurate prompt_text

Previous fixes:
- v11.3: ref_text auto-transcription + two-pass denoising + clone quality mode
- v11.2: Fixed voice_id mismatch (vc_{timestamp} vs vc_{digital_id})
- v11.1: Original audio clone replaces TTS output in training
- v11.0: highpass(80Hz) + afftdn + loudnorm audio cleaning
- v10.2: Direct GPT-SoVITS API call (UTF-8 safe, bypasses GBK bug)
    N)Pathc                      t          |           S )z3Legacy wrapper - delegates to clean_audio_for_clone)clean_audio_for_clone)
audio_paths    dh_v2_startup.pydenoise_audior   '   s     ,,,    c           	         | rt           j                            |           sdS t           j                            t           j                            t           j                            t           j                            t                                        ddd          }t           j                            |          sd}	 |d| dddg}t          j        |d	d	d
          }d}|j	        
                    d          D ]}d|v r|                                
                    d          d                                         
                    d          d                                         }|
                    d          \  }}}	t          |          dz  t          |          dz  z   t          |	          z   } n|d| dddddg}
t          j        |
d	d	d
          }d\  }}|j	        
                    d          D ]}d|v rZt          |
                    d          d                                         
                                d                   }n#  Y nxY wd|v rZt          |
                    d          d                                         
                                d                   }#  Y xY w|d| dddddg}t          j        |d	d	d          }d}d}|j	        
                    d          D ]}d|v sd|v r|dz  }|dk    rd}n|dk     rd }nd!}||||fS # t          $ r}t          d"| d	#           Y d$}~dS d$}~ww xY w)%z
    Analyze audio for noise floor and volume level.
    Returns: (noise_floor_db, mean_volume_db, peak_volume_db, duration_s)
    noise_floor is estimated from the quietest segments (bottom 5% RMS)
    )NNNNffmpegbin
ffmpeg.exe-i-fnull-T
   capture_outputtexttimeoutr   
	Duration:   ,:  <   -afvolumedetect)imean_volume
max_volumezsilencedetect=n=-50dB:d=0.1   isilence_startsilence_endr    z&[AudioAnalyze v11.4] Analysis failed: flushN)ospathexistsjoindirnameabspath__file__
subprocessrunstderrsplitstripfloat	Exceptionprint)r   _ffmpeg_exe_dur_cmd_dur_r_dur_line_parts_h_m_s_vol_cmd_vol_r_mean_peak
_noise_cmd_noise_r_noise_floor_silence_count_es                      r   _analyze_audio_noiserL   +   s     &RW^^J77 &%%',,rwrwrwx?X?X/Y/YZZ'> >K7>>+&& .&z4EDRTUUU]((.. 	 	Ee##,,[99!<BBDDJJ3OOPQRXXZZ#\\#..
BRyy4'%))b.8599D	 $  z5.$PVX[\DRTUUUu]((.. 	 	E%%"5;;s#3#3A#6#<#<#>#>#D#D#F#Fq#IJJUUu$$"5;;s#3#3A#6#<#<#>#>#D#D#F#Fq#IJJUU %
 "4:D&#O
>*TVXYYY_**400 	$ 	$E%''=E+A+A!# ALLS[[LLLUE4// & & &;r;;4HHHH%%%%%%&sL   EL+ AIL+ I	L+ &AJ98L+ 9J=;A/L+ +
M5MM c                 P	   | rt           j                            |           s| S t           j                            t           j                            t           j                            t           j                            t                                        ddd          }t           j                            |          sd}dt           j                            |           v s!dt           j                            |           v r| S t           j                            |           }t           j                            t           j                            |                     d         }t           j                            || d          }|rd| d	nd
}t          |           \  }}}	}
|t          d| dd           | S |dk     r||dk     r	 |dd| dddddd|g}t          j        |ddd          }|j        dk    r]t           j                            |          r>t           j                            |          dk    rt          d| d|ddd           |S n# t          $ r Y nw xY wt          d| d | d!d           | S |d"k     rd#}d$}nd%}d&}||dk     r
|d'z  }|d(z  }	 |dd| d|dddd|g}t          j        |ddd)          }|j        dk    sBt           j                            |          r#t           j                            |          dk     rt          d| d*d           | S t          j        |d|dd+d,d-d.gddd/          }d0}|j                            d1          D ]`}d2|v rZt%          |                    d3          d4                                                                         d                   }Y#  Y ]xY wa|d5k     rt          d| d6|dd7d           | S t           j                            |           }t           j                            |          }t          d| d8| d9t           j                            |            d:| d;| d<| d=|dd>d           |S # t          $ r$}t          d| d?| d@d           | cY d}~S d}~ww xY w)Au  
    v11.4: Smart audio cleaning for 100% voice cloning.
    
    Strategy:
      1. Analyze noise floor first
      2. Clean audio (noise_floor < -55dB) → skip processing (preserve timbre)
      3. Moderate noise → light highpass(80) + afftdn(nr=6) only
      4. Heavy noise → highpass(80) + afftdn(nr=10)
      5. Volume normalization ONLY if mean < -25dB (preserve dynamics)
    
    Returns: path to (possibly) cleaned audio, or original if clean enough
    r   r   r   _cleaned	_denoisedr   z_cleaned.wavz []rM   Nz[AudioClean v11.4]z& Analysis failed, using original audioTr)   r&   i-yr   r   z)loudnorm=I=-18:TP=-1.5:LRA=11:linear=true-ar16000z-ac1r   r   i  z! Clean audio, volume boost only (z.1fzdB -> -18dB)z Audio is clean (noise=z'dB), using raw original for 100% timbrer'   z#highpass=f=80,afftdn=nr=6:nt=w:bn=1lightz0highpass=f=80,afftdn=nr=10:nt=w:bn=1:rf=-25:tn=1moderatez*,loudnorm=I=-18:TP=-1.5:LRA=11:linear=truez+normZ   z" Processing failed, using originalr   r   r   r   r   r    r   r!   r   r   r(   z Output too quiet (zdB), using original z
 denoise: z (z->z bytes, noise=z	dB, mean=zdB)z Error: z, using original)r+   r,   r-   r.   r/   r0   r1   basenamesplitextrL   r9   r2   r3   
returncodegetsizer8   r4   r5   r7   r6   )r   labelr:   _dir_base_out_labelrI   	_mean_vol	_peak_volr=   _cmd_result_af_desc
_vol_check	_out_meanr>   
_orig_size	_new_sizerK   s                        r   r   r   i   s     RW^^J77 ',,rwrwrwx?X?X/Y/YZZ'> >K7>>+&&  RW%%j1111[BGDTDTU_D`D`5`5`7??:&&DGRW--j99::1=E7<<44455D#+]%]]]]F 0DJ/O/O,L)YQ6QQQY]^^^^ c  Y__	#T4JwsD: %.dWYZZZ%**rw~~d/C/C*X\H]H]`dHdHdsvssXassss{  A  A  A  AK   w6ww,www  @D  	E  	E  	E  	E c3 A S;;T4sE7E3>.drRRR"""'..*>*>""'//RVBWBWZ^B^B^QvQQQY]^^^^  ^$e^T63OdB
 
 

 	&,,T22 	 	E%%!&u{{3'7'7':'@'@'B'B'H'H'J'J1'M!N!NYY & s??dvdd)ddddlpqqqqW__Z00
GOOD))	 c6 c cE c cRW=M=Mj=Y=Y c cc c )c c9Ec cPYbc c cjn	p 	p 	p 	p   G6GG2GGGtTTTTsY   BI 
I,+I,+BQ7 4AQ7 6AO	Q7 	O&Q7 2BQ7 7
R%R R% R%zdigital_human_server_v2.pycrb   digital_human_server_v2)loaderoriginza[Patch v11.4] Smart noise detection + 100% clone quality (voice library only, training unchanged)Tr)   c            	         	 t          | i |S # t          $ r ddl}ddl}| r| d         n|                    dd          }t          |d          r|j        }nt          |d          r|j        }ddl}|j	        
                    t          |                    }|j                            |j        |j        pd|                    dd	          
          }d}i }	t          | d         d          r(| d         j        }t#          | d         j                  }	n0t          | d         d          r| d                                         }d}
t          | d         d          r| d         j        r| d         j        }
|                    ||j        |j        r
d|j        z   ndz   |
|	           |                                }|                                } G d d          } |||          cY S w xY w)z:Wrap urlopen to handle non-UTF-8 responses from GPT-SoVITSr   NurlrM   full_urlselectorP   r      r   GETmethod
get_methoddata?)bodyheadersc                   &    e Zd Zd Zd Zd Zd ZdS )#_safe_urlopen.<locals>.SafeResponsec                 R    |j         | _         |j        | _        || _        || _        d S N)statusreasonr   _data)selfrr|   s      r   __init__z,_safe_urlopen.<locals>.SafeResponse.__init__  s&    hh !


r	   c                     | j         S r   )r   r   s    r   readz(_safe_urlopen.<locals>.SafeResponse.read  s
    z!r	   c                     | S r    r   s    r   	__enter__z-_safe_urlopen.<locals>.SafeResponse.__enter__  s    r	   c                     d S r   r   )r   argss     r   __exit__z,_safe_urlopen.<locals>.SafeResponse.__exit__  s    r	   N)__name__
__module____qualname__r   r   r   r   r   r	   r   SafeResponser     sP        " " "
" " "      r	   r   )_original_urlopenUnicodeDecodeErrorhttp.clientiogethasattrrt   ru   urllib.parseparseurlparsestrclientHTTPConnectionhostnameportrz   dictr   r{   r|   requestr,   querygetresponser   )r   kwargshttpr   rs   urllibparsedconnrz   r   r~   resp	resp_datar   s                 r   _safe_urlopenr      s5   /- $1&111 -- -- -- 				8d1gg6::eR#8#83
## 	,CCS*%% 	,C&&s3xx00{))&/6;;L"V\V`V`ajlnVoVo)pp47H%% 	*!W^F47?++GGT!Wl++ 	*!W''))F47F## 	 Q 	 7<DVV[&,,VC&,,>,>TVW^blsttt!!IIKK		 	 	 	 	 	 	 	 |D),,,,,[--s    G!G21G2z2[Patch v8.3] urlopen(): UTF-8 safe wrapper appliedc                  N   d}| rU| d         }t          |d          r|j        }nKt          |d          r|                                }n&t          |          }n|                    dd          }dt          |          v rdt          |          v sdt          |          v rxt          d	| d
           | rbt          | d         d          rL| d         j        r?	 t          | d         j                  dd         }t          d| d
           n#  Y nxY wt          | i |S )z%Log GPT-SoVITS requests for debuggingrM   r   rt   get_full_urlrs   9880ttscontrolz'[Patch v9.1 DEBUG] GPT-SoVITS request: Tr)   r|   N  z$[Patch v9.1 DEBUG] GPT-SoVITS body: )r   rt   r   r   r   r9   r|   _safe_urlopen_v2)r   r   rs   reqdata_strs        r   _debug_urlopenr   ,  sR    C 	$1g3
## 	,CCS.)) 	""$$CCc((CCjj##SuC00IS4I4I===TJJJJ 	GDGV,, 	a 	tAw|,,TcT2GXGGtTTTTTT,V,,,s   6D DzC[Patch v9.1] urlopen(): debug logging added for GPT-SoVITS requestsc                 |   ddl }t          j                            |           }t          j                            |dt          j                            |           z   dz             }t          j                            |dt          j                            |           z   dz             }	 t          |dd          5 }t          j        ||d	d
           ddd           n# 1 swxY w Y   t          j        	                    |           r'	 t          j
        | |           n# t          $ r Y nw xY wt          j
        ||            dS # t          $ rg}	t          d|	 d           t          | dd          5 }t          j        ||d	d
           ddd           n# 1 swxY w Y   Y d}	~	dS Y d}	~	dS d}	~	ww xY w)zAtomic write: write to .tmp then rename. Prevents data loss on crash.
    v0.6.1: Accepts lock_name (from original _save_json signature) but ignores it;
    atomic file replacement provides equivalent thread safety.
    r   N.z.tmpz.bakwutf-8encodingF   ensure_asciiindentz-[Patch v0.6] _save_json atomic write failed: Tr)   )tempfiler+   r,   r/   r.   rZ   openjsondumpr-   replacer8   r9   )
filepathr|   	lock_namer   _tfr_   	_tmp_path	_bak_pathfes
             r   _safe_save_jsonr   M  sg   
 7??8$$DT3)9)9()C)C#Cf#LMMIT3)9)9()C)C#Cf#LMMI=)S7333 	=qIdAE!<<<<	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 7>>(## 	
8Y////   

9h''''' = = =AaAANNNN(C'222 	=aIdAE!<<<<	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	==s   +E
 =C"E
 "C&&E
 )C&*"E
 D# "E
 #
D0-E
 /D00E
 

F;&F6:FF6F#	#F6&F#	'F66F;c                 &    t          | |d          S )zv0.6.1: Patched replacement for _save_json_nolock (used by _save_task/_update_task).
    Uses atomic write instead of file locks.N)r   )r   )r   r|   r   s      r   _safe_save_json_nolockr   f  s     8TT::::r	   c                 H   t          t          dt          j                            t          j                            t          j                            t          j                            t                                        dd                    }t          ||            dS )z'Helper to save voices with atomic writeVOICES_FILEdigital_human_v2voices.jsonN)	getattrmoduler+   r,   r.   r/   r0   r1   r   )voicesvo_files     r   _safe_save_voicesr   k  sq    fmRW\\
(A(ABBCCM.+ .+ , ,G GV$$$$$r	   _save_json_nolockzM[Patch v0.6.1] _save_json() and _save_json_nolock(): atomic write with backupz3[Patch v0.6] _save_json(): atomic write with backupzhclonec           	      	   t          | |||||          \  }}||d<   g |d<   |                    dd          }	|	rt          j                            |	          nd}
|	rt          j                            |	          r	 ddl}t          j                            t          j                            t          j                            t          j                            t                                        ddd	          }|
                    |d
t          |	          dddgddd          }d|j        v }|rt          dd           |                    d          r|                    dd          nd}|rt          j                            t          j                            t          j                            |
                    d|          }t          j                            |d          }t          j                            |d          }t          j                            |          rt!          |d          }||k    r|n|}|	dz   }t          j        |	|           ddl}|                    ||	           t          d| d           t          j                            |          rt!          |d          }||k    r|n|}t          j                            |
d          }|                    ||           ||d<   |g|d<   t          j                            |          dz  |d <   t          d!d           n+# t(          $ r}t          d"| d           Y d}~nd}~ww xY wd#|                    d$d          v r||d$<   t          d%| d&d           |                    d'          d(k    rd)|d'<   t          d*d           	 |	r!t          j                            |	          r|	nd}|r~|                     t          |                    }|rI|                                r5|                                |d+<   t          d,|dd-          d.d           nt          d/d           n+# t(          $ r}t          d0| d           Y d}~nd}~ww xY wt.                                          }|||<   t3          |           t          d1| d2| d3d           ||fS )4aO  v11.4: Voice library 100% cloning with smart audio handling + ref_text auto-transcription
    
    CRITICAL: original_train_voice saves GPT-SoVITS synthetic output (32000 Hz)
    as reference.wav. This causes cascading quality degradation.
    v11.4 replaces it with the original audio (minimally processed) for true 100% cloning.
    typeaux_ref_audios	ref_audiorM   r   Nr   r   r   r   r   r   r   Tr   r   z32000 HzzX[Patch v11.4] Detected 32000Hz synthetic reference.wav, replacing with original audio...r)   vc_dh_dh_trainedzref_processed.wavztrain_ref_audio.wavvoice_lib_refz.synthetic_bakz&[Patch v11.4] Replaced reference.wav: voice_lib_fullzreference_full.wavref_audio_fulli }  full_durationz"[Patch v11.4] Saved full referencez9[Patch v11.4] Reference audio fix failed (non-critical): u   默认音色namez![Patch v11.4] Fixed voice name: ''modedefault_tts	zero_shotz:[Patch v11.4] Changed voice mode: default_tts -> zero_shotref_textz)[Patch v11.4] ref_text auto-transcribed: r   z...z9[Patch v11.4] ref_text transcription empty, using defaultz<[Patch v11.4] ref_text transcription failed (non-critical): z+[Patch v11.4] Voice library clone SUCCESS: z (mode=zero_shot, type=))original_train_voicer   r+   r,   r/   r-   r2   r.   r0   r1   r3   r   r4   r9   
startswithr   r   shutilcopy2r]   r8   _transcribe_audior6   r   _load_voicesr   )r   r   
voice_namelanguage
output_dirtask_id
voice_typevoice_id
voice_infor   	voice_dir_subprocess_sp_ffmpegrf   is_32kvoice_id_short	train_dirprocessed_ref	train_ref
_clean_ref_ref_source_bak_shtl_clean_train_train_sourcefull_ref_pathrK   _ref_wav_ref_text_actual_tx_errr   s                                  r   patched_train_voicer    ss    0j*h2<gG GHj $Jv#%J {B//I /8?	***RI )`RW^^I.. )`(	`////gll27??27??27??S[C\C\3]3]#^#^#+ULB BG$(('4YvWZ)[7;$PR ) T TG7>1F Uqy}~~~~FNFYFYZbFcFc!k!1!1(E!B!B!Bik! U "RW__RW__Y=W=W-X-X,5~!G !GI$&GLL<O$P$PM "Y8M N NIw~~m44 U%:=/%Z%Z
4>-4O4OjjUb  )+;;
9d333....K;;;T{TT\`aaaa 7>>)44 U+@L\+]+]L<HI<U<ULL[dM,.GLLDX,Y,YM!KK}EEE;HJ'78<I?J'78:<'//-:X:X\e:fJ7!"GtTTTT 	` 	` 	`RbRRZ^_________	` 3333'
6?*???tLLLL ~~f..(
6KSWXXXX
d )QbgnnY.G.GQ99T 	`#55c(mmDD `$4$:$:$<$< `)9)?)?)A)A
:&\BRSVTVSVBW\\\dhiiiiiRZ^____ d d dVWVV^bcccccccccd   ""F!F8f	
f
f
fYc
f
f
fnrssssZs2   ?KM 
M0M++M0B%Q; ;
R#RR#zO[Patch v11.4] train_voice(): smart audio cleaning + ref_text auto-transcription      ?
expressivec                 \   |s|r	 t                                           }|                                D ]\  }}|                    dd          }|rtt          j                            |          t          j                            |          k    r4|                    dg           }|r|}|s|                    dd          } nn# t          $ r
}Y d}~nd}~ww xY wg }|rWt          |t          t          f          r:t          j                            t          j                            t          j                            t          j                            t                                        ddd          }d	dl}|D ]}|rt!          |                                          r	 |d
t%          |          dddg}d	dl}|                    |dd          }d}|j                            d          D ]}d|v r|                                                    d          d                                                             d          d	                                         }|                    d          \  }}}t1          |          dz  t1          |          dz  z   t1          |          z   } n||dk    r|                    |           Vt          j                            |                                dt          j                            |                              dd                    } t	          j        t          j                            |           d           t          j                            |           s2|dd
t%          |          dddd d!d"| g}!|                    |!dd#$           t          j                            |           r|                    |            n|                    |           # t          $ r |                    |           Y w xY w|r|}|r|                                s|}|	d%k    rd&\  }"}#}$n |	d'k    rd(\  }"}#}$n|	d)k    rd*\  }"}#}$nd+\  }"}#}$|d%k    r|	d,vrt=          d-|	 d.d/           d&\  }"}#}$d	d0lm }%m!}& ||||t%          |          d1d2d3d4t%          |$          t%          |"          d5}'|d6k    o|dupd}(|(rW|rU|                                rA|                                |                                k    r|                                |'d7<   |rtE          |          D ]\  })}*|*|'d8|) d9<   | j#        d:z   }+t=          d;|+ d<|dd#          d/           d	dl$m%}, d=}-d}.tM          |-          D ]}/	 g }0|'                                D ]S\  }1}2 |&t%          |1          d>          }3 |&t%          |2          d>          }4|0                    |3 d?|4            Td@                    |0          }5|+ dA|5 }6|,'                    |6dBC          }7|,(                    |7dDE          5 }8|8j)        dFk    r|8*                                }9|rt	          j        t          j                            |          d           tW          |dG          5 }:|:,                    |9           ddd           n# 1 swxY w Y   |cddd           c S |cddd           c S |/|-dz
  k     r"t[          j.        d=           	 ddd           	 ddd           n# 1 swxY w Y   # t          $ rE}|}.t=          dI|/dz    dJ| d/           |/|-dz
  k     rt[          j.        d=           Y d}~ d}~ww xY w|.r|.dS )Ka$  
    v10.2: Bypass original_synthesize - direct GPT-SoVITS API call
    FIXES:
    - orig. pyc has GBK encoding bug that garbles Chinese text
    - orig. pyc uses ref_processed.wav (synthetic) instead of reference.wav
    - v10.2 calls GPT-SoVITS API directly with correct UTF-8 encoding
    r   rM   r   r   Nr   r   r   r   r   r   r   r   T)r   r   r   r   r   r   r   r   r   g      $@dh_v2_trimmed.wavz_trim9s.wavexist_okrR   z-tz9.5z-acodec	pcm_s16lerS   rT   rw   )r   r   r   )g333333?         ?precise)r  r   g333333?balanced)gffffff?r#   g?)r     r  )r   z&[Patch v11.4] Auto-switching quality: z -> clone (voice_type=clone)r)   )	urlencodequotewavfalsecut1rU   )r   	text_langref_audio_pathprompt_langspeed_factor
media_typestreaming_modetext_split_method
batch_sizetop_ptemperaturer   prompt_textzaux_ref_audio_paths[rQ   z/ttsz&[Patch v10.2] Direct GPT-SoVITS call: z text=   )safe=&r}   ry   )rz   i,  rx      wbzHTTP z'[Patch v10.2] GPT-SoVITS error attempt : )/r   r   itemsr   r+   r,   normpathr8   
isinstancelisttupler.   r/   r0   r1   r   r   r-   r   r2   r3   r4   r5   r6   r7   append
gettempdirrZ   r   makedirsr9   r   r  r   	enumeratebase_urlurllib.requestr   rangeRequesturlopenr   r   r   writetimesleep);r   r   r%  r   r   speedgpt_weightssovits_weightsoutput_pathqualityseedaux_ref_audio_pathsr   r   vidvinfo
stored_refauxr   _trimmed_auxr  	_tempfile_pathr;   _sprf   r=   r>   r?   r@   rA   rB   _trimmed_pathre   r-  top_kr,  r  r   params	_is_cloneiaprs   _ureqmax_retries
last_errorattemptquery_partskvencoded_keyencoded_valquery_stringrt   r   r   
audio_datar   s;                                                              r   patched_synthesizerg    s	     > 	((**F$llnn 	 	
U"YY{B77
 "'"2"2:">">"'BRBRSaBbBb"b"b))$4b99C 2.1+% ;%*YYvr%:%:
E 	 	 	DDDD	 L #/z*=e}MM #/',,rwrwrwx?X?X/Y/YZZ'> >$$$$( 	/ 	/E /e++-- // 's5zz4MH,,,,!gght$gOOGD!(!5!5d!;!; " "&%//%*[[]]%8%8%E%Ea%H%N%N%P%P%V%VWZ%[%[\]%^%d%d%f%fF)/c):):JBB#(99t#3eBii"n#DuRyy#PD!E	 0
 |tt||$++E222 $&GLL!,,..((//77NN%P %PM K > >NNNN7>>-88 G 'tSZZu );w WT2FFFw~~m44 3$++M::::$++E222  / / / ''...../ 	/".  8>>++  '$/!UEE	I		$0!UEE	J		$0!UEE$0!UE W
!:!:\w\\\dhiiii$/!UE .-------(E

!#U;'' F( },R:T3I3QTI 1X 1(.."2"2 1x~~7G7G4::<<7W7W ( 0 0} 5233 	5 	5EAr24F.!...// -&
 C	
I3
I
Id3B3i
I
IQUVVVV #"""""KJ%%    	 K C C1#eCFF444#eCFF444""k#A#AK#A#ABBBB88K00L....H---77CsC00 BD;#%%!%J" +BGOOK$@$@4PPPP!+t44 0GGJ///0 0 0 0 0 0 0 0 0 0 0 0 0 0 0*B B B B B B B B B B 'B B B B B B B B B B {Q..JqMMMB B B B B B B /B B B B B B B B B B B B B B B  	 	 	JLGAILLLLTXYYYYq((
1	  4s   B?C 
CC,D+PD2PP0/P0+B4]A%]	[&]	&[**]	-[*.]	2]]	]]	/]=]	]	]]	]
^% 9^ ^  ^%zC[Patch v10.2] synthesize(): direct GPT-SoVITS API call (UTF-8 safe)c                     | j         dk    r|                                 S | j         dk    r|                                 S | j                             d          rt	          |           S t          |           S )zHv8.0: Add /voice/reseed endpoint + intercept /voice/train for voice_typez"/api/digital-human/v2/voice/reseedz!/api/digital-human/v2/voice/trainz#/api/digital-human/v2/voice/preview)r,   _handle_voice_reseed_patched_handle_voice_trainr   patched_handle_voice_previeworiginal_do_POSTr   s    r   patched_do_POSTrm    s}     y888((*** y777//111 yABB 2+D111D!!!r	   c           	         	 t          | j                            dd                    }|dk    r| j                            |          nd}t          j        |          }|                    dd          }t                                          }||vr| 	                    dddi           d	S dd	l
}|                    dd
          }|||         d<   t                              t          j        |           t          d| d| d           | 	                    dd||d           d	S # t          $ r3}| 	                    dddt!          |           i           Y d	}~d	S d	}~ww xY w)z&Generate a new random seed for a voiceContent-Lengthr      {}r   rM     error   声音不存在NirL  z[Patch v8.0] Voice z reseeded: Tr)   r3  )successrL  r   r   u   重新随机种子失败: )intr   r   rfiler   r   loadsr   r   _json_responserandomrandint
_save_jsonr   r9   r8   r   )	r   content_lengthr~   r|   r   r   ry  new_seedr   s	            r   ri  ri    s   ST\--.>BBCC2@12D2Dtz~...%z$88J++$$&&6!!g/@%ABBBF>>!Z00#+x &,f555CHCCCC4PPPPCT8QY!Z!Z[[[[[ S S SC'+PA+P+P!QRRRRRRRRRSs   B)D* -A;D* *
E'4(E""E'c                    t          | j                            dd                    }|dk    r| j                            |          nd}d}	 t          j        |          }|                    dd          }t          d| d           n# t
          j        t          f$ r Y nw xY wd	}t          | d
          r"t          | j        d          r| j        j        }n!t          t          d          rt          j        }|rt          |d          r||j        _        dd	l}| j        }|                    |          | _        	 t'          |           }|| _        |r,t          |d          rt          |j        d          r|j        `n:# || _        |r,t          |d          rt          |j        d          r|j        `w xY w|S )z?v8.0: Extract voice_type from form data and pass to train_voicero  r   rp  r   r   z%[Patch v8.0] Voice train: voice_type=Tr)   Nserverengine_global_engine
gpt_sovits_pending_voice_type)ru  r   r   rv  r   r   rw  r9   JSONDecodeError
ValueErrorr   r  r  r   r  r  r  r   BytesIOoriginal_handle_voice_train)	r   r|  r~   r   r|   r  r   original_rfileresults	            r   rj  rj    s    ))*:A>>??N.<q.@.@4:??>***eD Jz$XXlG44
BjBB$OOOOO *-    		 FtX '74;#A#A '#	)	*	* '& ;'&,// ;0:- III ZND!!DJ:,T22 $
 	:gfl33 	:v(*?@@ :%9	 $
 	:gfl33 	:v(*?@@ :%99999Ms   >B B&%B&F 7F>c           	          |rKt           j                            |          r,t          |d          }||k    rt	          d| d           |}|t          | dd          }t          | ||||||          S )zMv11.4: Voice library upload with smart audio cleaning + voice_type extractionvoice_lib_clonez5[Patch v11.4] Using cleaned audio for voice library: Tr)   Nr  r   )r+   r,   r-   r   r9   r   _original_train_voice_for_type)r   r   r   r   r   r   r   rP   s           r   patched_train_voice_with_typer    s      #bgnnZ00 #)*6GHH	
""U)UU]abbbb"JT#8'BB
)$
J+5w
L L Lr	   zM[Patch v11.4] train_voice_with_type(): smart cleaning + voice_type extractionz6[Patch v8.0] do_POST(): reseed + voice_type extractionrK  c                     |
dvrd}
t          d| d| d|
 d           |
| _        |                    dd	           t          | |||||||||	f
i |S )
a  
    v8.3: Enhanced generate with 100% voice cloning.
    - lip_sync_mode is stored in self._lip_sync_mode (NOT passed to original)
      because original _do_generate doesn't accept it as a parameter
    - The patched synthesize will auto-load aux_ref_audios from voices.json
    )rK  syncrK  z [Patch v8.3] _do_generate: task=z, voice=z, lip_sync=Tr)   lip_sync_modeN)r9   _lip_sync_modepoporiginal_do_generate)r   r   
digital_idr   r   bg_modebg_colorbg_image_pathrG  output_sizer  r   s               r   patched_do_generater    s     ///!	
bW
b
bh
b
bS`
b
bjnoooo (D
JJ%%%gz4=%    r	   zK[Patch v8.3] _do_generate(): lip_sync_mode routed via engine._lip_sync_modec                 P   t          dd           ddl}ddl}	 t          | j                            dd                    }|dk    r| j                            |          nd}t          |t                    rO	 |
                    d          }n8# t          $ r+ |
                    dd	
          }t          dd           Y nw xY wt          j        |          }|                    dd          }|                    dd          }|s|                     dddi           dS t                                          }||vr|                     dddi           dS ||         }	d}
t#          | d          r!t#          | j        d          r| j        j        }
|
t)          t          dd          }
|
t#          |
d          s|                     dddi           dS |
j        }t#          |d          r.|                                s|                     dddi           dS |	                    dd          }|	                    dd          }|	                    dd           }|	                    d!          }|	                    d"g           }|r|                                s|}t          d#d           d$}|	                    d%          pd}|	                    d&          pd}t          d'| d(| d)| d*t1          |           d           ddl}t4          j                            |                                d+          }t5          j        |d,           t4          j                            |d-| d.t          t?          j                               d/          }|                     ||r!t4          j        !                    |          r|nd||d0|||||||	                    d1d$          2          }|r|n|}|rvt4          j        !                    |          rVtE          |d3          5 }|                                }ddd           n# 1 swxY w Y   t1          |          dk    r|#                    |          
                    d4          }t4          j        $                    |          d5         %                                &                    d6d          }d7d8d9d:                    |d7          }t          d;t1          |           d<| d           |                     d=d|||t1          |          d>           dS t          d?d           |                     d@ddAi           dS t          dBd           |                     d@ddCi           dS # tN          j(        j)        tT          j+        tX          f$ rj}t          dD| d           |-                                 	 |                     dEddFt]          |           i           n#  Y n	xY wY d}~dS Y d}~dS d}~wt^          $ rj}t          dG| d           |-                                 	 |                     d@ddHt]          |           i           n#  Y n	xY wY d}~dS Y d}~dS d}~ww xY w)IzIv8.0: Return audio as base64 inline + use full ref audio for 100% cloningz.[VP_ENTER] patched_handle_voice_preview calledTr)   r   Nro  rp  r   r   )errorszM[Patch v8.5] VoicePreview: body had non-UTF-8 bytes, decoded with replacementr   rM   r   uH   大家好，我是您的专属数字人主播，欢迎来到直播间！  rr  u   缺少 voice_idrq  rs  r  r  r  r       GPT-SoVITS 引擎未就绪check_availableu,   GPT-SoVITS 服务不可用，请稍后重试r   r   r   r   rL  r   zO[Patch v8.1] VoicePreview: ref_text was empty, using synthesis text as fallbackr   rH  rI  z![Patch v8.0] VoicePreview: voice=z, seed=z
, quality=z, text_len=voice_previewsr  preview__r  r  r   r   r%  r   r   rG  rH  rI  rJ  rK  rL  rM  r   rm   asciir   r   	audio/wavz
audio/mpegz	audio/ogg)r!  mp3oggz%[Patch v8.0] VoicePreview: SUCCESS - z bytes, format=r3  rt  r   audio_base64
audio_mime
audio_sizez.[Patch v8.0] VoicePreview: audio file is emptyr   u0   语音合成失败：生成的音频文件为空z3[Patch v8.0] VoicePreview: no output file generatedu*   语音合成失败：未生成音频文件z*[Patch v8.0] VoicePreview: network error: i  u+   GPT-SoVITS 连接超时，请稍后重试: z"[Patch v8.0] VoicePreview: error: u   试听失败: )0r9   base64	tracebackru  r   r   rv  r   r8  bytesdecoder   r   rw  rx  r   r   r   r  r  r   r  r  r6   lenr   r+   r,   r.   r<  r=  rE  
synthesizer-   r   	b64encoder[   lowerr   r   rr  URLErrorsocketr   ConnectionError	print_excr   r8   )r   b64r  r|  r~   r|   r   r   r   r   r  gsr   r   r   rL  r   rK  rH  rI  r   preview_dirrJ  result_path
final_pathr   audio_bytes	audio_b64extmimer   s                                  r   rk  rk  5  s   	
:$GGGGFT\--.>BBCC2@12D2Dtz~...%dE"" 	tt{{7++% t t t{{79{==fnrsssssst z$88J++xx jkk 	g/@%ABBBF$$&&6!!g/@%ABBBFH%
 4"" 	(wt{H'E'E 	(['F>V%5t<<F>!>!>>g/K%LMMMF 2()) 	"2D2D2F2F 	g/]%^___F NN;33	>>*b11>>*d33~~f%%#(8"==  	rx~~// 	rHdlpqqqq  !nn]33;t#(899ATr(rr4rrSZrrgjkogpgprrz~ 	gll8#6#6#8#8:JKK
K$////gll;0\80\0\c$)++FVFV0\0\0\]] mm(1YbgnnY6O6OY99UY#)# .!~~fg66 $ 
 
  %0@[[[
 	^"'..44 	^j$'' '1ffhh' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ;!##MM+66==gFF	g&&z2215;;==EEc2NN*<TTXXY\^ijjdc+>N>Ndd_bddlpqqqq##C# ($-"&"%k"2"2* *      GtTTTT##C'3e)fgggggHPTUUUUg/[%\]]]]]L!6>?C   >1>>dKKKK	g/e]`ab]c]c/e/e%fgggg	D hgggggDDDDD   6166dCCCC	g/HA/H/H%IJJJJ	D KJJJJJDDDDDs   AV# ;B V# 2CV# CAV# %5V# A=V# AV#  HV# 2QV# QV# QC0V# )V# 8)V# #&Z%	(X.2(XX.XX..Z%;(Z $(ZZ ZZ  Z%zB[Patch v8.0] _handle_voice_preview(): base64 inline + 100% cloning_handle_voice_synthesizec                 v   	 t          | j                            dd                    }|dk    r| j                            |          nd}t          j        |          }|                    dd          }|                    dd          }|r|s|                     ddd	i           d
S t          	                                }||vr|                     dddi           d
S ||         }d
}t          | d          r!t          | j        d          r| j        j        }|t          t          dd
          }|t          |d          s|                     dddi           d
S |j        }	|                    dd          }
|                    dg           }|                    dd          }|r|                                s|}dd
l}t"          j                            |                                d          }t#          j        |d           t"          j                            |d| dt          t-          j                               d          }|	                    ||
r!t"          j                            |
          r|
nd
|                    dd          |                    dd          d|                    d          pd
|                    d           pd
|d!|                    d"          ||                    d#d!          $          }|r|n|}|rt"          j                            |          rdd
l}t5          |d%          5 }|                                }d
d
d
           n# 1 swxY w Y   |                    |                              d&          }|                     d'd||d(t;          |          d)           d
S |                     d*dd+i           d
S # t<          $ rK}dd
l}|                                  |                     d*dd,tC          |           i           Y d
}~d
S d
}~ww xY w)-z1v8.0: Enhanced voice synthesize with 100% cloningro  r   rp  r   rM   r   r  rr  u   缺少 voice_id 或 textNrq  rs  r  r  r  r  r  r  r   r   r   voice_synthsTr  synth_r  r  r   r   r  rH  rI  r   rL  r   r  rm   r  r3  r  r  r   u   语音合成失败u   语音合成失败: )"ru  r   r   rv  r   r   rw  rx  r   r   r   r  r  r   r  r6   r   r+   r,   r.   r<  r=  rE  r  r-   r  r   r  r  r  r8   r  r  r   )r   r|  r~   r|   r   r   r   r   r  r  r   r   r   r   	synth_dirrJ  r  r  r  r   r  r  r   r  s                           r   patched_handle_voice_synthesizer    s   S	Q !1!12BA!F!FGGN6Dq6H6H4:??>222eD:d##Dxx
B//H88FB''D 4 ##C'3M)NOOO((**Fv%%##C'3D)EFFF)JFtX&& ,74;+I+I ,+~ )94@@~WV\%B%B~##C'3O)PQQQ"B
 #{B77I'^^,<bAAN!~~j"55H  8>>#3#3  OOOX%8%8%:%:NKKIK	D1111',,y2\82\2\c$)++FVFV2\2\2\]]K--,5]"'..:S:S]yyY]#
B77#
D99&NN=99AT)~~.>??G4'^^F++$2%>>&':: (  K )4DJ JbgnnZ88 J$$$$*d++ +q"#&&((K+ + + + + + + + + + + + + + +MM+66==gFF	##C# ($-"-"%k"2"2* *      ##C'3G)HIIIII 	Q 	Q 	Q!!!g/Nc!ff/N/N%OPPPPPPPPP	QsX   B&O# *5O# !A=O#  G*O# 
M+O# +M//O# 2M/3AO# 	O# #
P8-A P33P8z=[Patch v8.0] _handle_voice_synthesize(): 100% cloning enabledz:[Patch v8.0] _handle_voice_synthesize: not found, skippingr   c                     	 t          | |          }|S # t          $ r}t          d| d           Y d}~dS d}~wt          $ r}t          d| d           Y d}~dS d}~ww xY w)z=v8.1: Safe transcription wrapper that catches encoding errorszF[Patch v8.1] _transcribe_audio: UTF-8 decode error (returning empty): Tr)   NrM   z9[Patch v8.1] _transcribe_audio: error (returning empty): )_original_transcribe_audior   r9   r8   )r   r   r  r   s       r   patched_transcribe_audior  1  s    	/jAAFM! 	 	 	^[\^^fjkkkk22222 	 	 	QaQQY]^^^^22222	s    
A$8A$AA$_try_duix_asrc                 r    	 t          | |          S # t          $ r}t          d| d            d }~ww xY w)Nz)[Patch v8.1] _try_duix_asr: UTF-8 error: Tr)   )_original_try_duix_asrr   r9   )r   r   r   s      r   patched_try_duix_asrr  B  sU    -dJ???%   E!EETRRRRs    
616zH[Patch v8.1] _transcribe_audio(): safe wrapper with UTF-8 error handlingz2[Patch v8.1] _transcribe_audio not found, skippingz.[Patch v8.4] All patches applied successfully!c                     	 t          |           dz  }|                    dd           |                                 dS # t          $ r Y dS w xY w)Nz.write_testtestr   r   TF)_Path
write_textunlinkr8   )r,   	test_files     r   _test_write_permissionr  [  si    $KK-/	Vg666t   uus   =A 
AAr   c            	          t                      } t          dt          |            dt          |                                            d           | S )Nz)[Patch v9.1 DEBUG] _load_voices returned z	 voices: Tr)   )_original_load_voicesr9   r  r9  keys)r   s    r   _debug_load_voicesr  k  sS    &((e#f++eePTU[U`U`UbUbPcPceemqrrrrr	   z0[Patch v9.1] _load_voices(): debug logging addedz*[Patch v8.5] Original directory writable: z, keeping native paths
dh_v2_datar   z1[Patch v8.5] Restored voices.json from temp cachez*[Patch v8.5] voices.json restore skipped: )parentsr  z.dh_v2_dataz
tasks.jsonz([Patch v8.5] Refreshed tasks.json from: z[Patch v8.5] Copy failed: z[Patch v8.5] TASKS_FILE: ))
UPLOAD_DIRuploads)TEMP_DIRtemp)
OUTPUT_DIRoutputs)
VOICES_DIRr   z[Patch v8.5] r5  z0[Patch v8.5] Sandbox-safe path redirects appliedc                 \   ddl m} 	  || j                  }|j        pd}|j        pd}t          j        t
          j        t
          j                  }|	                    d           |
                    ||f          }|                                 |dk    rdS dS # t          $ r Y dS w xY w)zBv9.0: Fast TCP socket check (2s), avoids /docs timeout on CPU moder   )r   z	127.0.0.1i&  r   TF)r   r   r?  r   r   _socketr  AF_INETSOCK_STREAM
settimeout
connect_excloser8   )r   r   r   hostr   sockr  s          r   patched_check_availabler    s    %%%%%%$-((-+{"d~gow/BCC$..

Q;;4u   uus   BB 
B+*B+z@[Patch v9.0] check_available(): TCP socket check + HTTP fallbackz1[Patch v10] Running voice file integrity check...r   r   r   r   r   z[Patch v10] Repairable: z( - ref_audio missing but full_ref existsz[Patch v10] Removing: z - ref_audio file missing: r   c                 P    g | ]#}t           j                            |          !|$S r   )r+   r,   r-   ).0as     r   
<listcomp>r    s+    GGGRW^^A5F5FG!GGGr	   z'[Patch v10] Cleaned aux_ref_audios for z -> Fr   r   z)[Patch v10] Voices.json cleaned: removed=z, repairable=z[Patch v10] All z voices pass integrity checkz$[Patch v10] Integrity check failed: z*[Patch v10] No voices.json found, skippingzW[Patch v11.4] Digital human training: no auto voice cloning (use voice library instead)z[Patch v8.5] Starting server...__main__z0.0.0.0u=   [服务] 正方元智能广告工作台 - 数字人 v2 (v8.4)u   [服务] 地址: http://r   u   [服务] 正在关闭...)rM   r   )r   NNr   )NrM   r   r  NNNr  NNN)r   NNN)rK  )__doc__sysr+   rE  r  r   r2   r@  r   urllib.errorpathlibr   r   rL   r   r1   parent
PORTAL_DIRr,   insertr   importlib.util	importlibmarshaltypesPYC_PATHr   r   r   rw  codemodule_nameutilspec_from_loaderspecmodule_from_specr   exec__dict__modulesr9   r   _urllib_requestrC  r   r   r   r   r{  _original_save_jsonr   r   r   r   r   GPTSoVITSEnginetrain_voicer   r  r  original_synthesizerg  DigitalHumanV2Handlerdo_POSTrl  rm  ri  _handle_voice_trainr  rj  r  r  DigitalHumanEngineV2_do_generater  r  rk  _handle_voice_preview original_handle_voice_synthesizer  r  r   r  r  r  r  r  r  r   r   
TASKS_FILE_original_tasks_filer/   
_tasks_dirr  _original_dir_writabler   r  r  r   _new_tasks_filer<  _temp_voices_jsonr-   r   _shutilr   r8   rK   mkdirgetcwd_attr_subdir_newsetattrr  _urllibr  _original_check_availabler  r   _voices_file	read_text_voices_raw_voices_data_removed	_repairedr9  r6  _vid_vinfor   _ref	_full_refr;  _aux
_valid_auxr  r  dumpsr   r  ThreadingHTTPServerPORTr  r  gethostbynamegethostnameserve_foreverKeyboardInterruptshutdownr   r	   r   <module>r5     sp   . 


 				                     - - -<& <& <&|f f f fR T(^^"
 33z?? # # #       55	T(D #QFF2JJJ7=""D# # # # # # # # # # # # # # #
 (~&&{4H&VV		(	(	.	. T6?   !K  iqu v v v v
 ) ( ( ( ( (#+ 1- 1- 1-f (  :$ G G G G
 ! - - -2 )  KSW X X X X
 ' = = = =2; ; ;
% % % $ 
76&'' M5F	E
Yaefffff	E
?tLLLL -9 ?CCJ]  ]  ]  ] ~ &9  " W_c d d d d
 ,7 NRDHEI=Ae e e eN %7  ! KSW X X X X
 /7 " " " S S S4 %:N / / /d "5 IMMQL L L L& &C  " U]a b b b b'6  $4H  1;V  8 >d K K K K
 2?  (1   2 ,?  ( S[_ ` ` ` `
L L L\ 6R  2 JRV W W W W
 $(  
76')CDD ]'-'C'\$# [TUQ UQ UQn =\F 9	E
IQUVVVVV	E
FdSSSS
 76!#677 L!'!7!I
 
 
 0HF, wv%77 D!'!7!E	 	 	 0D,	E
T\`aaaaa	E
>dKKKK 6d C C C C " ! ! ! ! !    ( U27??#78899
   0/
;; 
  ==  J   -F	E
<DIIII .J	E
Yz
Y
Y
Yaeffff*Oncn..//,>N!! Q    	QGM##/00##j=6P2Q2QRRREFdSSSSS 	Q 	Q 	QECrCC4PPPPPPPPP	QQ ~s~''((<7J65555 6 6 6U929;;''-7
555556 c*|344O=*O<<<O9MOOW[\\\\\ = = =/2//t<<<<<<<<<= (F	E
7o
7
7tDDDD 
? 
?w 765!! 	?'DJJtdJ333GFE4(((E1%11411>>>>	E
<DIIII                "2B   $ *A  & HPT U U U U 9 F F F F,3GFM,J,JjuuV'(((PZ]jPj !DG",,g,>>!tz+..	 D!3!3!5!566 	v 	vLD&::k2..D *BGNN400 *"JJ'7<<	 *	!:!: *EcTccckopppp$$T****EZ4ZZTXZZbfggggOOD)))::.33DGGdjbGGGJs:##djb//11+5'(hhhD		hhWZWZ[eWfWfhhptuuuu 	# 	#DT"" 	by 	b##JDJ|%XY$Z$Z$Zel#mmmEjcc(mmjjZ]Z]^gZhZhjjrvwwwwwETSS%6%6TTT\`aaaa G G G9R99FFFFFFFFFG 
E
6dCCCC _gk l l l l 't 4 4 4 4 't 4 4 4 4
 z((**F''FK(@&B^__FFM"F	E
JRVWWWW	E
_%9V%9:L&:L:N:N%O%O
_
_RXR]
_
_gkllll   (5555 s   8CCC3R R%
R  R%S 7TT.!U U/U**U/G!`> >aaad5 5:e32e3