FormDVDCopy FormDVDCopy 0 0 708 661 MOLPHIN MMC - DVD Copy DVD_Copy DVD Copy GroupBox26 0 0 380 60 10 1 Step 1 - read DVD DVDAMount 300 35 80 20 8 0 /media/dvd mountpoint to DVD Drive (mount before copy) Label17_2 220 35 80 17 8 0 (auto) mount: AlignVCenter|AlignRight required if you want to know the DVD size Label17 230 15 70 17 8 0 DVD device: AlignVCenter|AlignRight required for DVD reading DVDDrive 300 15 80 20 8 0 /dev/dvd FormatDVD false 140 25 71 25 0 For&mat image0 @OutputStep.setText(... formatting DVD - please wait ...) @DVDOutput.setText(Format output: @exec(dvd+rw-format @DVDDrive.text -blank 2>&1) ) @OutputStep.setText(DVD formatted.) @DVDSize.setText(0 GB) wiil format DVD ScanDVD 10 25 120 25 0 Re/Read D&VD image1 read contents of DVD Label105 200 60 70 30 10 DVD Size: AlignVCenter|AlignRight DVDSize 270 65 110 21 10 1 LineEditPanel 0 GB AlignVCenter|AlignRight GroupBox5 0 400 380 120 10 1 Step 4 - Action CopyProgressBar 10 85 240 27 Label143 254 70 120 17 0 curr. size of copy: ExecButton14 260 20 110 25 0 STOP Cop&y image2 @OutputStep.setText(... stopping copy process ...) @exec( mypids=$(ps ax | egrep 'mencoder dvd://|cp|mplayer dvd://.*-dumpstream' | grep -v grep | sed 's/^\ //g' | cut -d ' ' -f 1) for p in $mypids ; do if [ ! -z "$(ps $p | grep @OutputFileName.text)" ] ; then kill $p fi done sleep 2 ) @OutputStep.setText(Copy stopped.) stop copy process CurCopySize 270 90 100 21 0 1 LineEditPanel AlignVCenter|AlignRight DVDTitleCopy 10 50 240 25 0 C&opy Title image3 @if(@String.length(@OutputDirectory.text) < 1 || @String.length(@OutputFileName.text) < 1) @exec(kdialog --msgbox "Please fill in 'Save to directory:' and 'DVD/Title Name:' ." --title "INFO") @endif @if(@String.length(@DVDTitle.text) < 1) @exec(kdialog --msgbox "No DVD read so far." --title "INFO") @endif @if(@String.contains(@OutputDirectory.text, " ") || @String.contains(@OutputFileName.text, " ")) @exec(kdialog --msgbox "BLANKs in output directory and DVD name are not allowed." --title "INFO") @endif @if(@String.length(@OutputDirectory.text) > 1 && @String.length(@OutputFileName.text) > 1 && @String.length(@DVDTitle.text) > 0 && !@String.contains(@OutputDirectory.text, " ") && !@String.contains(@OutputFileName.text, " ")) @OutputStep.setText(... checking directory ...) @exec( rm -f /tmp/dvd_copy_momc.sh rm -f /tmp/dvd_theanswer_momc.txt dcop @dcopid KommanderIf setText OutputStep "... analysing size - please wait ..." titlenum=@DVDTitle.text titlesize=0 if [ -x @DVDAMount.text/video_ts ] ; then tl=@DVDAMount.text"/video_ts/vts_${titlenum}_*.vob" else tl=@DVDAMount.text"/VIDEO_TS/VTS_${titlenum}_*.VOB" fi for f in $(du -s ${tl} | cut -f 1) ; do titlesize=$[titlesize + $f] done if [ "$titlesize" -gt "$(df -k @OutputDirectory.text | grep '/dev/' | sed 's/\ \ */\ /g' | cut -d ' ' -f 4)" ] ; then dcop @dcopid KommanderIf setText OutputStep "Copy of title @DVDTitle.text aborted." kdialog --msgbox "Required disk space for title @DVDTitle.text :\n\n $[titlesize / 1024] MB.\n\nCurrent disk space is too low." --title "INFO" exit else if [ "$titlesize" == "0" ] ; then kdialog --msgbox "For copy status your DVD needs to be mounted!\n\nNo calculation of percentage can be done.\n\nCopy will be done anyway.\n\n" --title "INFO" fi rm -f /tmp/dvd_copy_momc.sh rm -f /tmp/dvd_theanswer_momc.txt tmpON="@OutputFileName.text" if [ -z "$(echo $tmpON | egrep '.vob$|.mpg$')" ] ; then tmpON="${tmpON}.vob" dcop @dcopid KommanderIf setText OutputFileName "${tmpON}" fi if [ -e @OutputDirectory.text/@OutputFileName.text ] ; then (kdialog --yesno "File(s) already exist(s):\n\n @OutputDirectory.text/@OutputFileName.text?" --title "OVERWRITE EXISTING FILE?") && echo "yes" > /tmp/dvd_theanswer_momc.txt if [ "$(cat /tmp/dvd_theanswer_momc.txt)" != "yes" ] ; then kdialog --msgbox "Copy stopped." --title "Stopped" exit fi fi if [ ! -x @OutputDirectory.text ] ; then mkdir -p @OutputDirectory.text fi dcop @dcopid KommanderIf setText OutputStep "... copying title @DVDTitle.text - please wait ..." if [ -x @OutputDirectory.text ] ; then echo '#!/bin/bash dcop @dcopid KommanderIf setText CopyProgressBar "0" dcop @dcopid KommanderIf setText CurCopySize 0KB dcop @dcopid KommanderIf setEnabled Copy1to1 false titlesize='$titlesize' if [ "$(whereis mencoder | cut -d ':' -f 2)" != "" ] ; then mencoder dvd://@DVDTitle.text -oac copy -ovc copy -of mpeg -dvdangle @DVDAngle.text -o @OutputDirectory.text/'$tmpON' > @global(MyTmpFile) 2>&1 & mypid=$! else mplayer dvd://@DVDTitle.text -dumpstream -dumpfile -dvdangle @DVDAngle.text @OutputDirectory.text/'$tmpON' > @global(MyTmpFile) 2>&1 & mypid=$! fi #dcop @dcopid KommanderIf setText CopyPID $mypid dcop @dcopid KommanderIf setText OutputStep "... copying title @DVDTitle.text - (backgrounded) ..." oldSize="0" sleep 4 while [ ! -z "$(ps -f ${mypid} | egrep [0-9])" ] ; do oldSize=$(ls -s @OutputDirectory.text/'$tmpON' | cut -d " " -f 1) if [ "$titlesize" != "0" ] ; then dcop @dcopid KommanderIf setText CopyProgressBar "$[oldSize * 100 / titlesize]" fi dcop @dcopid KommanderIf setText CurCopySize $(ls -sh @OutputDirectory.text/'$tmpON' | cut -d " " -f 1)B sleep 4; done dcop @dcopid KommanderIf setText CurCopySize $(ls -sh @OutputDirectory.text/'$tmpON' | cut -d " " -f 1)B dcop @dcopid KommanderIf setText CopyProgressBar "100" dcop @dcopid KommanderIf setText OutputStep "Copy of title @DVDTitle.text done." dcop @dcopid KommanderIf setEnabled Copy1to1 true dcop @dcopid KommanderIf setText DVDOutput_mplayer @global(MyTmpFile) kdialog --msgbox "Copy process of title @DVDTitle.text finished." --title "Title @DVDTitle.text"' > /tmp/dvd_copy_momc.sh chmod u+x /tmp/dvd_copy_momc.sh fi fi ) /tmp/dvd_copy_momc.sh > /dev/null 2>&1 @endif copy just the selected title Copy1to1 10 20 240 25 0 &1:1 Copy image4 @if(@String.length(@OutputDirectory.text) < 1 || @String.length(@OutputFileName.text) < 1) @exec(kdialog --msgbox "Please fill in 'Save to directory:' and 'DVD/Title Name:' ." --title "INFO") @endif @if(@String.length(@DVDTitle.text) < 1) @exec(kdialog --msgbox "Read a DVD first." --title "INFO") @endif @if(@String.length(@OutputDirectory.text) > 1 && @String.length(@OutputFileName.text) > 1 && @String.length(@DVDTitle.text) > 0) @exec( rm -f /tmp/dvd_copy_momc.sh rm -f /tmp/dvd_theanswer_momc.txt if [ -x @OutputDirectory.text/@OutputFileName.text ] || [ -f @OutputDirectory.text/@OutputFileName.text ] ; then kdialog --msgbox "A file or directory with that name already exists:\n\n @OutputDirectory.text/@OutputFileName.text \n\nChoose a different one.\n\n" --title "Stopped Copy" exit fi dcop @dcopid KommanderIf setText OutputStep "... checking directory ..." dvdsize="$(du -s @DVDAMount.text | cut -f 1)" if [ "$dvdsize" -gt "$(df -k @OutputDirectory.text | grep '/dev/' | sed 's/\ \ */\ /g' | cut -d ' ' -f 4)" ] ; then kdialog --msgbox "Required disk space:\n\n $(du -sh @DVDAMount.text | cut -f 1)B. \n\n Disk space too low for copy on '@OutputDirectory.text'" --title "INFO" dcop @dcopid KommanderIf setText OutputStep "Copy aborted." else if [ "$dvdsize" == "0" ] ; then kdialog --msgbox "For copy status your DVD needs to be mounted!\n\nNo calculation of percentage can be done.\n\nCopy will be done anyway.\n\n" --title "INFO" fi dcop @dcopid KommanderIf setText OutputStep "... copying DVD 1:1 - please wait ..." if [ ! -x @OutputDirectory.text/@OutputFileName.text ] ; then mkdir @OutputDirectory.text/@OutputFileName.text fi if [ -x @OutputDirectory.text/@OutputFileName.text ] ; then echo '#!/bin/bash dcop @dcopid KommanderIf setText CopyProgressBar "0" dcop @dcopid KommanderIf setText CurCopySize 0KB dcop @dcopid KommanderIf setEnabled DVDTitleCopy false dvdsize='$dvdsize' cp -a @DVDAMount.text/* @OutputDirectory.text/@OutputFileName.text/ & mypid=$! dcop @dcopid KommanderIf setText OutputStep "... copying DVD 1:1 - (backgrounded) ..." oldSize="0" sleep 4 while [ "$(ps -f ${mypid} | egrep [0-9])" != "" ] ; do oldSize=$(du -s @OutputDirectory.text/@OutputFileName.text/ | cut -f 1) if [ "$dvdsize" != "0" ] ; then dcop @dcopid KommanderIf setText CopyProgressBar "$[oldSize * 100 / dvdsize]" fi dcop @dcopid KommanderIf setText CurCopySize $(du -sh @OutputDirectory.text/@OutputFileName.text/ | cut -f 1)B sleep 4; done dcop @dcopid KommanderIf setText CopyProgressBar "100" dcop @dcopid KommanderIf setText OutputStep "Copy of DVD done." dcop @dcopid KommanderIf setEnabled DVDTitleCopy true kdialog --msgbox "Copy process of DVD finished." --title "1:1 Copy"' > /tmp/dvd_copy_momc.sh chmod u+x /tmp/dvd_copy_momc.sh fi fi ) /tmp/dvd_copy_momc.sh > /dev/null 2>&1 @endif makes a 1:1 copy to your harddrive FreeHDSpace 290 370 90 21 10 1 LineEditPanel 0 GB AlignVCenter|AlignRight free directory space on HD Label146_2 170 370 110 20 10 Free HD Space: AlignVCenter|AlignRight GroupBox26_2_2 0 250 380 120 10 1 Step 3 - set output OutputDirectory 20 40 350 23 0 @widgetText() Directory directory to save DVD OutputFileName 20 85 290 24 0 file name for the title copy OR directory name for 1:1 copy Label26 10 20 140 20 0 1 Save to directory: Label66_3 10 65 130 20 0 1 DVD/Title Name: calcDiskspace 340 10 32 32 @FreeHDSpace.setText(@exec(df -h @OutputDirectory.text | grep '/dev/' | sed 's/\ \ */\ /g' | cut -d ' ' -f 4)B) Label34 0 210 40 20 10 Hints: AlignVCenter|AlignRight Hints 40 210 340 37 184 255 191 GroupBox29 390 30 300 545 PrevPic_2 10 140 128 110 253 253 253 AlignCenter PrevPic_5 160 5 128 110 253 253 253 AlignCenter PrevPic_6 160 140 128 110 253 253 253 AlignCenter PrevPic_3 10 275 128 110 253 253 253 AlignCenter PrevPic_7 160 275 128 110 253 253 253 AlignCenter PrevPic_4 10 410 128 110 253 253 253 AlignCenter PrevPic_1_Label 10 115 90 21 10 LineEditPanel PrevPic_1 10 5 128 110 253 253 253 AlignCenter PrevPic_2_Label 10 250 90 21 10 LineEditPanel PrevPic_3_Label 10 385 90 21 10 LineEditPanel PrevPic_4_Label 10 520 90 21 10 LineEditPanel PrevPic_5_Label 160 115 90 21 10 LineEditPanel PrevPic_6_Label 160 250 90 21 10 LineEditPanel PrevPic_7_Label 160 385 90 21 10 LineEditPanel PrevPic_8 160 410 128 110 253 253 253 AlignCenter PrevPic_8_Label 160 520 90 21 10 LineEditPanel PrevPic_5_Info false 250 115 20 20 image5 @PrevPic_5.setText(@global(PicPath)/prev_@String.remove(@PrevPic_5_Label.text, "Title ")_info_momc.png) PrevPic_1_Info false 100 115 20 20 image5 @PrevPic_1.setText(@global(PicPath)/prev_@String.remove(@PrevPic_1_Label.text, "Title ")_info_momc.png) PrevPic_2_Info false 100 250 20 20 image5 @PrevPic_2.setText(@global(PicPath)/prev_@String.remove(@PrevPic_2_Label.text, "Title ")_info_momc.png) PrevPic_6_Info false 250 250 20 20 image5 @PrevPic_6.setText(@global(PicPath)/prev_@String.remove(@PrevPic_6_Label.text, "Title ")_info_momc.png) PrevPic_3_Info false 100 385 20 20 image5 @PrevPic_3.setText(@global(PicPath)/prev_@String.remove(@PrevPic_3_Label.text, "Title ")_info_momc.png) PrevPic_7_Info false 250 385 20 20 image5 @PrevPic_7.setText(@global(PicPath)/prev_@String.remove(@PrevPic_7_Label.text, "Title ")_info_momc.png) PrevPic_8_Info false 250 520 20 20 image5 @PrevPic_8.setText(@global(PicPath)/prev_@String.remove(@PrevPic_8_Label.text, "Title ")_info_momc.png) PrevPic_4_Info false 100 520 20 20 image5 @PrevPic_4.setText(@global(PicPath)/prev_@String.remove(@PrevPic_4_Label.text, "Title ")_info_momc.png) PrevPic_1_Play false 120 115 20 20 image6 rm -f /tmp/dvd_momc_mplayer_output.txt 2>/dev/null mplayer dvd://@String.remove(@PrevPic_1_Label.text, "Title ") -dvdangle @String.replace(@DVDAngle.text, 0, "") -vo sdl > /tmp/dvd_momc_mplayer_output.txt 2>&1 @DVDOutput_mplayer.setText(@exec( cat /tmp/dvd_momc_mplayer_output.txt | head -n $(cat -n /tmp/dvd_momc_mplayer_output.txt | head -n 150 | egrep 'VO:' | cut -f 1 | tr -d ' ') )) PrevPic_2_Play false 120 250 20 20 image6 rm -f /tmp/dvd_momc_mplayer_output.txt 2>/dev/null mplayer dvd://@String.remove(@PrevPic_2_Label.text, "Title ") -dvdangle @String.replace(@DVDAngle.text, 0, "") -vo sdl > /tmp/dvd_momc_mplayer_output.txt 2>&1 @DVDOutput_mplayer.setText(@exec( cat /tmp/dvd_momc_mplayer_output.txt | head -n $(cat -n /tmp/dvd_momc_mplayer_output.txt | head -n 150 | egrep 'VO:' | cut -f 1 | tr -d ' ') )) PrevPic_3_Play false 120 385 20 20 image6 rm -f /tmp/dvd_momc_mplayer_output.txt 2>/dev/null mplayer dvd://@String.remove(@PrevPic_3_Label.text, "Title ") -dvdangle @String.replace(@DVDAngle.text, 0, "") -vo sdl > /tmp/dvd_momc_mplayer_output.txt 2>&1 @DVDOutput_mplayer.setText(@exec( cat /tmp/dvd_momc_mplayer_output.txt | head -n $(cat -n /tmp/dvd_momc_mplayer_output.txt | head -n 150 | egrep 'VO:' | cut -f 1 | tr -d ' ') )) PrevPic_4_Play false 120 520 20 20 image6 rm -f /tmp/dvd_momc_mplayer_output.txt 2>/dev/null mplayer dvd://@String.remove(@PrevPic_4_Label.text, "Title ") -dvdangle @String.replace(@DVDAngle.text, 0, "") -vo sdl > /tmp/dvd_momc_mplayer_output.txt 2>&1 @DVDOutput_mplayer.setText(@exec( cat /tmp/dvd_momc_mplayer_output.txt | head -n $(cat -n /tmp/dvd_momc_mplayer_output.txt | head -n 150 | egrep 'VO:' | cut -f 1 | tr -d ' ') )) PrevPic_5_Play false 270 115 20 20 image6 rm -f /tmp/dvd_momc_mplayer_output.txt 2>/dev/null mplayer dvd://@String.remove(@PrevPic_5_Label.text, "Title ") -dvdangle @String.replace(@DVDAngle.text, 0, "") -vo sdl > /tmp/dvd_momc_mplayer_output.txt 2>&1 @DVDOutput_mplayer.setText(@exec( cat /tmp/dvd_momc_mplayer_output.txt | head -n $(cat -n /tmp/dvd_momc_mplayer_output.txt | head -n 150 | egrep 'VO:' | cut -f 1 | tr -d ' ') )) PrevPic_6_Play false 270 250 20 20 image6 rm -f /tmp/dvd_momc_mplayer_output.txt 2>/dev/null mplayer dvd://@String.remove(@PrevPic_6_Label.text, "Title ") -dvdangle @String.replace(@DVDAngle.text, 0, "") -vo sdl > /tmp/dvd_momc_mplayer_output.txt 2>&1 @DVDOutput_mplayer.setText(@exec( cat /tmp/dvd_momc_mplayer_output.txt | head -n $(cat -n /tmp/dvd_momc_mplayer_output.txt | head -n 150 | egrep 'VO:' | cut -f 1 | tr -d ' ') )) PrevPic_7_Play false 270 385 20 20 image6 rm -f /tmp/dvd_momc_mplayer_output.txt 2>/dev/null mplayer dvd://@String.remove(@PrevPic_7_Label.text, "Title ") -dvdangle @String.replace(@DVDAngle.text, 0, "") -vo sdl > /tmp/dvd_momc_mplayer_output.txt 2>&1 @DVDOutput_mplayer.setText(@exec( cat /tmp/dvd_momc_mplayer_output.txt | head -n $(cat -n /tmp/dvd_momc_mplayer_output.txt | head -n 150 | egrep 'VO:' | cut -f 1 | tr -d ' ') )) PrevPic_8_Play false 270 520 20 20 image6 rm -f /tmp/dvd_momc_mplayer_output.txt 2>/dev/null mplayer dvd://@String.remove(@PrevPic_8_Label.text, "Title ") -dvdangle @String.replace(@DVDAngle.text, 0, "") -vo sdl > /tmp/dvd_momc_mplayer_output.txt 2>&1 @DVDOutput_mplayer.setText(@exec( cat /tmp/dvd_momc_mplayer_output.txt | head -n $(cat -n /tmp/dvd_momc_mplayer_output.txt | head -n 150 | egrep 'VO:' | cut -f 1 | tr -d ' ') )) GroupBox23 390 0 300 25 DVDLibEnabled 5 5 195 16 10 enable &DVD Media Library true "no" "yes" DVDLibStore true 200 3 95 20 10 force &update @exec( myLibPath=@global(DVDLibraryPath); myLibBinder=@global(DVDLibraryBinder); myT=1; myTmax="$(cat @global(MyTmpFile) | grep 'Title:' | tail -n 1 | cut -d ',' -f 1 | cut -d ' ' -f 2)"; myTmax=$(echo -n $[myTmax + 0]); pngcomp=":z=4" cd /tmp while [ "$myT" -lt "$[myTmax + 1]" ] ; do dcop @dcopid KommanderIf setText OutputStep "... putting DVD to Media Library/title $myT..." if [ ! -f "prev_${myT}_momc.png" ] ; then mplayer dvd://$myT -frames 3 -ss 45s -sstep 45 -nosound -noframedrop -idx -vo png$pngcomp < /dev/null > /tmp/test.txt 2>&1; if [ ! -e /tmp/00000002.png ] ; then if [ ! -z "$(cat /tmp/test.txt | egrep 'PNG [U|u]nknown')" ] ; then pngcomp="" fi if [ ! -z "$(cat /tmp/test.txt | egrep 'libdvdread.*nvalid')" ] ; then exit fi mplayer dvd://$myT -frames 3 -ss 45s -sstep 45 -nosound -noframedrop -idx -vo png$pngcomp < /dev/null > /tmp/test.txt 2>&1; fi if [ ! -e /tmp/00000002.png ] ; then mplayer dvd://$myT -frames 3 -ss 2s -sstep 2 -nosound -noframedrop -idx -vo png$pngcomp < /dev/null > /tmp/test.txt 2>&1; fi if [ ! -e /tmp/00000002.png ] ; then mplayer dvd://$myT -frames 3 -nosound -noframedrop -idx -vo png$pngcomp < /dev/null > /tmp/test.txt 2>&1; fi convert -resize x110 00000002.png -sharpen 2 prev_${myT}_momc.png convert prev_${myT}_momc.png -draw "roundRectangle 2,78 65,92 3,3" -fill black -draw "roundRectangle 12,92 51,106 3,3" prev_${myT}_boxes_momc.png if [ ${#myT} -lt 2 ] ; then fmyT="0"$myT else fmyT=$myT fi ms="$(cat @global(MyTmpFile) | grep -A1 'Title: '${fmyT} | tail -n 1 | sed 's/.*\([1|\ ][6|4|3][/|:|_][9|3|2]\).*\([1-9|\ ][0-9][0-9][0-9]\).*\([0-9|\ ][0-9][0-9][0-9]\).*/\2x\3,\1/g')" ma="${ms#*,}" ms="${ms%,*}" #!!!!!!!!! wrong sizes reported by dvd_read !!!!!!!!!!!!!!!!!!!!! ms="$(file 00000002.png | cut -d ',' -f 2 | sed 's/\ //g')" convert prev_${myT}_boxes_momc.png -pointsize 14 -fill white -channel RGBA -draw "text 7,89 '$ms'" -draw "text 15,105 '($ma)'" prev_${myT}_info_momc.png & fi rm -f 00000*.png myT=$[myT + 1] done if [ ! -z $myLibBinder ] ; then echo "1" >> /tmp/debug.txt if [ ! -x ${myLibPath}${myLibBinder} ] ; then echo "2" >> /tmp/debug.txt mkdir -p ${myLibPath}${myLibBinder} fi if [ -x ${myLibPath}${myLibBinder} ] ; then cp prev_*_momc.png prev_*_info_momc.png mmc_dvdinfo.txt ${myLibPath}${myLibBinder}/ cp @global(MyTmpFile) ${myLibPath}${myLibBinder}/dvd.info echo "3" >> /tmp/debug.txt fi dcop @dcopid KommanderIf setText OutputStep "Media Library updated." cd - ) GroupBox26_2 0 90 380 120 10 1 Step 2 - select content DVDTitle_Chapter 310 45 59 21 0 LineEditPanel AlignVCenter|AlignRight current title no. of chapters Label82 240 45 70 20 0 Chapters: AlignVCenter|AlignRight Label66_2 20 45 40 19 0 1 Title: AlignVCenter|AlignRight Label30 148 45 42 17 0 1 Angle: AlignVCenter|AlignRight Label146 250 70 60 20 0 Aspect: AlignVCenter|AlignRight Label31 10 70 50 17 0 1 Audio: AlignVCenter|AlignRight Label66_2_2 10 95 51 19 0 1 Length: DVDTitle_Length 60 95 80 21 0 LineEditPanel AlignVCenter|AlignLeft current title length Label66 10 20 50 19 0 1 Name: AlignVCenter|AlignRight DVDSetTitleInfo 240 10 32 32 @if(@String.length(@File.read(@global(MyTmpFile))) > 0) @DVDTitle_Length.setText(@exec("cat @global(MyTmpFile) | egrep 'Title: @DVDTitle.text,.*Len|len.*Cha|cha' | sed 's/.*[L|l]ength:\(.*\)[C|c]hap.*/\1/g;s/\([0-9][0-9]:[0-9][0-9]:[0-9][0-9]\)/\1/g'")) @DVDTitle_Chapter.setText(@exec("cat @global(MyTmpFile) | egrep 'Title: @DVDTitle.text,.*Len|len.*Cha|cha' | sed 's/.*[C|c]hapters:\(.*\)[C|c]ell.*/\1/g;s/.*\([0-9][0-9]\).*/\1/'")) @DVDTitle_Chapter.insertItem("", 0) @DVDAngle.setText(@exec("cat @global(MyTmpFile) | egrep -A2 'Title: @DVDTitle.text,' | tail -n 1 | sed 's/.*[A|a]ngles: \(.*\).*/\1/g'")) @DVDAudioID.setText(@exec("cat @global(MyTmpFile) | egrep 'Title: @DVDTitle.text,' | sed 's/.*[A|a]udio streams: \(.*\), [S|s]ubpict.*/\1/g'")) @DVDTitle_Aspect.setText(@exec("cat @global(MyTmpFile) | egrep -A1 'Title: @DVDTitle.text,' | tail -n 1 | sed 's/.*ratio: \(.*\), [W|w]idth:.*/\1/g'")) @endif @if(@DVDTitle.currentItem < 8 && @global(prevBp) != 7) @OutputStep.setText(... grepping previews for 1 to 8 ...) @setGlobal(prevBp, 7) @setGlobal(cutT, 1) @ResetUI @SetPrevPic @OutputStep.setText(Previews done.) @endif @if((@DVDTitle.currentItem > @global(prevBp) || @DVDTitle.currentItem < @global(prevBp)) && @DVDTitle.currentItem > 7 && @DVDTitle.currentItem < 16 && @global(prevBp) != 15) @OutputStep.setText(... grepping previews for 9 to 16 ...) @setGlobal(prevBp, 15) @setGlobal(cutT, 9) @ResetUI @SetPrevPic @OutputStep.setText(Previews done.) @endif @if((@DVDTitle.currentItem > @global(prevBp) || @DVDTitle.currentItem < @global(prevBp)) && @DVDTitle.currentItem > 15 && @DVDTitle.currentItem < 24 && @global(prevBp) != 23) @OutputStep.setText(... grepping previews for 17 to 24 ...) @setGlobal(prevBp, 23) @setGlobal(cutT, 17) @ResetUI @SetPrevPic @OutputStep.setText(Previews done.) @endif @if((@DVDTitle.currentItem > @global(prevBp) || @DVDTitle.currentItem < @global(prevBp)) && @DVDTitle.currentItem > 23 && @DVDTitle.currentItem < 32 && @global(prevBp) != 31) @OutputStep.setText(... grepping previews for 25 to 32 ...) @setGlobal(prevBp, 31) @setGlobal(cutT, 25) @ResetUI @SetPrevPic @OutputStep.setText(Previews done.) @endif @if(@String.length(@DVDAngle.text) < 1)@DVDAngle.setText(1)@endif @DVDTitleCopy.setText(Copy Title @DVDTitle.item(@DVDTitle.currentItem)/angle @DVDAngle.item(@DVDAngle.currentItem)) DVDLabel 60 20 210 21 3 184 0 253 253 253 1 LineEditPanel title of DVD DVDAngle 190 45 50 20 0 Angle is used to play different scenes within one title stream without switching from file/chapter to file/chapter or putting the movie on disc as often as you have languages just because of small video sequences they differ in. Assume the following: You create a movie for two languages. No problem here with sound tracks and the movie itself. But, if your movie contains e.g. sliding text (not subtitles) you also want this text to be displayed for the two languages, each. For not having an interuption during playing the movie you create for each language the sliding text one behind each other inside the movie. While playing the movie you see both texts after each other, but this you can avoid while defining an angle 1 for language 1 telling a player to jump over the sliding text of language 2. The same you do for language 2 telling it jumping through language 1s text, defined by angle 2. While playing that movie based on the angle nobody sees that in reality the movie contains more information than displayed on the screen. (think about *Wars text intro :-}) DVDAudioID false 60 70 80 20 not implemented yet, sorry I know it would be a nice feature to have but it is a bit more complex than it looks like DVDTitle_Aspect 310 70 59 21 0 LineEditPanel AlignVCenter|AlignRight current titles aspect Label55 195 95 115 17 0 Longest Track: AlignVCenter|AlignRight DVDLongestTitle 310 95 59 21 0 LineEditPanel AlignVCenter|AlignRight current titles aspect btnPlay 290 15 80 25 0 &Play image7 @OutputStep.setText(... playing title @DVDTitle.text ...) @exec(rm -f /tmp/dvd_momc_mplayer_output.txt 2>/dev/null; mplayer dvd://@String.replace(@DVDTitle.text, 0, "") -vo sdl -dvdangle @String.replace(@DVDAngle.text, 0, "") > /tmp/dvd_momc_mplayer_output.txt 2>&1) @DVDOutput_mplayer.setText(@exec( cat /tmp/dvd_momc_mplayer_output.txt | head -n $(cat -n /tmp/dvd_momc_mplayer_output.txt | head -n 150 | egrep 'VO:' | cut -f 1 | tr -d ' ') )) @OutputStep.setText(Play done.) just play movie DVDTitle 60 45 80 20 0 title to play and copy I saw selfmade DVDs from DVD-Recorders containing multiple titles, but only one movie in the first one. So, be warned that it might confuse you what the content of your DVD is about. CleanTmp 170 60 32 32 @exec( # rm preview pics rm -f /tmp/00000*.png # rm my preview pics rm -f /tmp/prev_*_momc.png # rm my dvd info files rm -f /tmp/dvd_*_momc.info ) ResetUI 130 60 32 32 @PrevPic_1.clear @PrevPic_1_Label.setText("") @PrevPic_2.clear @PrevPic_2_Label.setText("") @PrevPic_3.clear @PrevPic_3_Label.setText("") @PrevPic_4.clear @PrevPic_4_Label.setText("") @PrevPic_5.clear @PrevPic_5_Label.setText("") @PrevPic_6.clear @PrevPic_6_Label.setText("") @PrevPic_7.clear @PrevPic_7_Label.setText("") @PrevPic_8.clear @PrevPic_8_Label.setText("") @PrevPic_1_Play.setEnabled(false) @PrevPic_2_Play.setEnabled(false) @PrevPic_3_Play.setEnabled(false) @PrevPic_4_Play.setEnabled(false) @PrevPic_5_Play.setEnabled(false) @PrevPic_6_Play.setEnabled(false) @PrevPic_7_Play.setEnabled(false) @PrevPic_8_Play.setEnabled(false) @PrevPic_1_Info.setEnabled(false) @PrevPic_2_Info.setEnabled(false) @PrevPic_3_Info.setEnabled(false) @PrevPic_4_Info.setEnabled(false) @PrevPic_5_Info.setEnabled(false) @PrevPic_6_Info.setEnabled(false) @PrevPic_7_Info.setEnabled(false) @PrevPic_8_Info.setEnabled(false) OutputStep 0 555 380 19 235 235 0 10 1 LineEditPanel Version 2006-03-31_0.7.2 AlignVCenter|AlignLeft Init 10 60 32 32 @setGlobal(MissingPrograms,@exec( function checkForProgs() { reqPROGS="mplayer lsdvd dvd+rw-format dvd+rw-mediainfo file mencoder convert" for p in $reqPROGS ; do retu="$(whereis ${p})" if [ "$(echo ${retu} | cut -d ':' -f 2)" == "" ] ; then echo " - $p" fi done } checkForProgs )) @if(@String.length(@global(MissingPrograms)) > 1) kdialog --msgbox "These programs were not found:\n\n\n@global(MissingPrograms)\n\n\n lsdvd (essential): read dvd data\n mplayer (optional): plays a title\n dvd+rw-format (opt.): to blank dvd\n dvd+rw-mediainfo (opt.): used by Library Management\n mencoder (opt.,but makes sense): for copying titles\n file (opt.): for reading right sizes for Info\n convert (imagemagick): for preview pictures\n\n\n" --title "Missing program(s)" ) @endif @if(@String.contains(@global(MissingPrograms), lsdvd)) @ScanDVD.setEnabled(false) @endif @if(@String.contains(@global(MissingPrograms), mplayer)) @btnPlay.setEnabled(false) @endif @if(@String.contains(@global(MissingPrograms), mencoder) && @String.contains(@global(MissingPrograms), mplayer)) @DVDTitleCopy.setEnabled(false) @endif @setGlobal(prevBp, 7) @setGlobal(cutT, 1) @OutputDirectory.setText(@exec(dirname ~/.)) @setGlobal(DVDLibraryPath, @exec(dirname ~/.)/@GlobalPath.text/@LibraryPath.text) @exec( if [ ! -e @global(DVDLibraryPath) ] ; then mkdir -p @global(DVDLibraryPath) fi ) @setGlobal(DVDLibraryPath, @global(DVDLibraryPath)/) SetPrevPic 90 60 32 32 @exec( myT=@global(cutT); myTbp=@global(prevBp); myLibDVDEnabled=@DVDLibEnabled; myLibPath=@global(DVDLibraryPath); myLibBinder=@global(DVDLibraryBinder); myTmax="$(cat @global(MyTmpFile) | grep 'Title:' | tail -n 1 | cut -d ',' -f 1 | cut -d ' ' -f 2)"; myT=$(echo -n $[myT + 0]); myTmax=$(echo -n $[myTmax + 0]); pngcomp=":z=4" pc=1 cd /tmp if [ "$myLibDVDEnabled" == "yes" ] ; then [ ! -x ${myLibPath}${myLibBinder} ] && mkdir -p ${myLibPath}${myLibBinder} if [ -x ${myLibPath}${myLibBinder} ] ; then dcop @dcopid KommanderIf setText OutputStep "... storing to/reading from DVD Media Library ..." cd ${myLibPath}${myLibBinder} fi fi while [ "$myT" -lt "$[myTbp + 2]" ] && [ "$myT" -lt "$[myTmax + 1]" ] ; do if [ ! -f "prev_${myT}_momc.png" ] ; then mplayer dvd://$myT -frames 3 -ss 45s -sstep 45 -nosound -noframedrop -idx -vo png$pngcomp < /dev/null > test.txt 2>&1; if [ ! -e 00000002.png ] ; then if [ ! -z "$(cat test.txt | egrep 'PNG [U|u]nknown')" ] ; then dcop @dcopid KommanderIf setText Hints "Your version of mplayer does not support PNG compression. This requires a bit more space in tmp. Will try to capture previews without compression." pngcomp="" fi if [ ! -z "$(cat test.txt | egrep 'libdvdread.*nvalid')" ] ; then kdialog --msgbox "Your libdvdread is too old!\nThis DVD cannot be read properly. Try to upgrade to a newer version.\n\nAlso, playing a title directly will not work and title copy also.\n\nError message:\n\n$(cat test.txt | grep -A3 'libdvdread')" --title "Previews are skipped!" dcop @dcopid KommanderIf setEnabled DVDTitleCopy false exit fi mplayer dvd://$myT -frames 3 -ss 45s -sstep 45 -nosound -noframedrop -idx -vo png$pngcomp < /dev/null > test.txt 2>&1; fi if [ ! -e 00000002.png ] ; then mplayer dvd://$myT -frames 3 -ss 2s -sstep 2 -nosound -noframedrop -idx -vo png$pngcomp < /dev/null > test.txt 2>&1; fi if [ ! -e 00000002.png ] ; then mplayer dvd://$myT -frames 3 -nosound -noframedrop -idx -vo png$pngcomp < /dev/null > test.txt 2>&1; fi convert -resize x110 00000002.png -sharpen 2 prev_${myT}_momc.png convert prev_${myT}_momc.png -draw "roundRectangle 2,78 65,92 3,3" -fill black -draw "roundRectangle 12,92 51,106 3,3" prev_${myT}_boxes_momc.png if [ ${#myT} -lt 2 ] ; then fmyT="0"$myT else fmyT=$myT fi ms="$(cat @global(MyTmpFile) | grep -A1 'Title: '${fmyT} | tail -n 1 | sed 's/.*\([1|\ ][6|4|3][/|:|_][9|3|2]\).*\([1-9|\ ][0-9][0-9][0-9]\).*\([0-9|\ ][0-9][0-9][0-9]\).*/\2x\3,\1/g')" ma="${ms#*,}" ms="${ms%,*}" #!!!!!!!!! wrong sizes reported by dvd_read !!!!!!!!!!!!!!!!!!!!! ms="$(file 00000002.png | cut -d ',' -f 2 | sed 's/\ //g')" convert prev_${myT}_boxes_momc.png -pointsize 14 -fill white -channel RGBA -draw "text 7,89 '$ms'" -draw "text 15,105 '($ma)'" prev_${myT}_info_momc.png & fi rm -f 00000*.png dcop @dcopid KommanderIf setText PrevPic_${pc}_Label "Title $myT" dcop @dcopid KommanderIf setEnabled PrevPic_${pc}_Play true dcop @dcopid KommanderIf setEnabled PrevPic_${pc}_Info true dcop @dcopid KommanderIf setText PrevPic_${pc} $(pwd)/prev_${myT}_momc.png myT=$[myT + 1] pc=$[pc + 1] done cd - ) ReadDVD 50 60 32 32 @ResetUI @CleanTmp @DVDSize.setText(0 GB) @DVDTitleCopy.setEnabled(true) @OutputStep.setText(... reading DVD drive ...) @setGlobal(MyTmpFile, /tmp/dvd_@exec("date '+%Y-%m-%d_%s'")_momc.info) @exec( MyFile=@global(MyTmpFile); [ -f ${MyFile} ] && rm -f ${MyFile} lsdvd -x @DVDDrive.text 2>&1 >> $MyFile; if [ ! -z "$(cat ${MyFile} | grep 'not open')" ] ; then echo "" > $MyFile; fi ) @DVDOutput.setText(@File.read(@global(MyTmpFile))) @if(@String.length(@File.read(@global(MyTmpFile))) < 1) kdialog --msgbox "Insert a DVD movie disk to DVD drive." --title "No disk found:" @OutputStep.setText(... no disk found.) @FormatDVD.setEnabled(false) @endif @if(@String.length(@File.read(@global(MyTmpFile))) > 0) @exec(rm -f /tmp/mmc_dvdinfo.txt; dvd+rw-mediainfo @DVDDrive.text > /tmp/mmc_dvdinfo.txt 2>/dev/null) @setGlobal(DVDLibraryBinder, @exec(md5sum /tmp/mmc_dvdinfo.txt 2>/dev/null | cut -d ' ' -f 1)) @OutputStep.setText(... reading DVD ...) @DVDLabel.setText(@exec("head -n 1 @global(MyTmpFile) | egrep 'Title:' | cut -d ':' -f 2 | sed 's/^\ //;s/\ $//'")) @DVDTitle.setText(@exec("cat @global(MyTmpFile) | egrep 'Title: [0-9][0-9],.*Len|len.*Cha|cha' | sed 's/[T|t]itle:\(.*\)[L|l]en.*/\1/;s/.*\([0-9][0-9]\).*/\1/'")) @DVDTitle_Length.setText(@exec("cat @global(MyTmpFile) | egrep 'Title: @DVDTitle.text,.*Len|len.*Cha|cha' | sed 's/.*[L|l]ength:\(.*\)[C|c]hap.*/\1/g;s/\([0-9][0-9]:[0-9][0-9]:[0-9][0-9]\)/\1/g'")) @DVDTitle_Chapter.setText(@exec("cat @global(MyTmpFile) | egrep 'Title: @DVDTitle.text,.*Len|len.*Cha|cha' | sed 's/.*[C|c]hapters:\(.*\)[C|c]ell.*/\1/g;s/.*\([0-9][0-9]\).*/\1/'")) @DVDTitle_Chapter.insertItem("", 0) @DVDTitle_Aspect.setText(@exec("cat @global(MyTmpFile) | egrep -A1 'Title: @DVDTitle.text,' | tail -n 1 | sed 's/.*ratio: \(.*\), [W|w]idth:.*/\1/g'")) @DVDSize.setText(@exec("du -sh @DVDAMount.text | cut -f 1")B) @DVDLongestTitle.setText(@exec(cat @global(MyTmpFile) | egrep '[L|l]ongest.*[T|t]rack' | tr -d '0 .:-_[a-z][A-Z]')) @OutputStep.setText(... grepping preview pictures ...) @SetPrevPic @endif @if(@String.length(@DVDSize.text) < 2)@DVDSize.setText(-not mounted-)@endif @OutputStep.setText(... analysing if DVD+/-RW in drive ...) @exec(cat /tmp/mmc_dvdinfo.txt | sed 's/.*\(DVD.RW\).*/\1/g' | egrep 'DVD.RW' > /tmp/mmc_fdvdinfo.txt) @if(@String.length(@exec(cat /tmp/mmc_fdvdinfo.txt)) > 0) @FormatDVD.setEnabled(true) @endif @if(@String.length(@exec(cat /tmp/mmc_fdvdinfo.txt)) < 1) @FormatDVD.setEnabled(false) @endif @OutputStep.setText(DVD read.) @setGlobal(PicPath,/tmp/) @if(@String.length(@global(DVDLibraryBinder)) > 1 && @exec(du -sk @global(DVDLibraryPath)@global(DVDLibraryBinder) 2>/dev/null | cut -f 1) > 25 && @DVDLibEnabled == "yes") @setGlobal(PicPath,@global(DVDLibraryPath)@global(DVDLibraryBinder)/) @exec([ ! -f @global(DVDLibraryPath)@global(DVDLibraryBinder)/dvd.info ] && cp @global(MyTmpFile) @global(DVDLibraryPath)@global(DVDLibraryBinder)/dvd.info) @endif Logs Logs TabWidget1 0 10 690 530 tab lsd&vd Label53 8 9 270 19 lsdvd debug output: DVDOutput 0 40 690 450 tab &mplayer Label53_2 10 10 270 19 mplayer debug output: DVDOutput_mplayer 0 40 690 450 Configuration Config&uration Label138 50 20 130 19 1 GLOBAL PATH: AlignVCenter|AlignRight Label138_2 20 50 160 20 1 LIBRARY PATH: AlignVCenter|AlignRight GlobalPath 190 20 480 19 .momc LibraryPath 250 50 420 19 dvdlibrary the DVD info is stored here 789c5596c9721c370c86ef7a0a957073a5e0eee9bd5239689765edb264d9a91cd0dda4f67db4a6f2ee21ff9f2327031ffc09200962637ffe347fb2b73dffe9f3dce3d4a6e7c3fc70660ff39fc6a7ebebb73ffffae3efb985bc9ec7bfc9fc64e1b7b985fde9fc30bf737be322a804900cbfc8f6f4c13958c1659693e50c5c45c1fad3c40dd92ec116a487dec06314e8d7c8613b9ca71b6097b99ce7c19fbc8c82f3be82fb28e073f01005ebabc893320ad62f81bb0f5e4ddc4d606fcbe0210ad66f815d14e8572217599117f047afc165d14d0af011b88e02f6e0360afcfb01eea2400f7f8a3e7739e39d472eb3d297b47f01477779de3ab8287d41fb1e8c1fece16fd94781fe38724c470dbd3e82bbb29d7870061ecaa662fc4ec06314e891cfba6bcb06f63605bbdaa7fdf72337aeacd2f9cf601f05fa21729b45c1fa45f0a4ca4bea1db88e02fd05d8ba81f6d2817beb0cf1d083c85d1913061ec17514700d6e3bebe9df15d8a260bfedc89607c17a83deca20c89f219ed1bc67fc07f2980dc897bd82cd8691fe91fb701cf743be6cb4b147bdcb4de43e0b16d8cf9ec9e12f88afbc81f37e3236604d5c0ddcef1d3c699a96f9b920f79301f63a0117a1dc195fee57597000fa57721f4208fe02c60ffc13ecfa62647fde26f69ef11ac9c330305fe78947b2a09f7b3fe41ef19107b2cb7bd4a7a09f86bcf52dfbe385ec729e27382f345be6c8f06728a2c01ef91aea266b99ef02dcccf4b293b819d91f88f7d0b9cc184ff4d310d2e5e90ffa7718ac6bb87e931c2c189f2672c8f6c4f37e9837631936a03fa8c7b1aa9b9af5704d0ec2fdb2193baedf20fb102230ea6dacad1939ef4672388ff747bec7662cd3f9a7899b541fdfc9bef2a877394eec69af989f63d7fb86f582f93af6ad633f5be220ccd794ecccd1fe1e3c0c45cdfadc9db1e73c7e23c71da07f24cfceb73bf018ea8feb31df46d78e1defb74e0ee68c17ea310cbfc6f17e4764ef537db4e0e2c31ef17665eb3bde778f1cfa89f9477c5c15f2c5f357c9ae65fd08deaf705a95eacd25ee1ce731fad3b5e17cce3ff45bd0b68ef3e73d71b2b72171cffa32c4c3595fd57cff16c951a0bf49dcb3bf8ce7f76d91fcdf244701e3bd70c1c1b4df2139fee03fea358633cdabb519737e28e2e7b33841a1efc9a1bdf95e637ef8d04d23ebd3937deee9cfb7c405e3aff789eb547fc87778acfa96fd93f8a31ed1dfa15a130bf7abfd2c7fc88fef9cb13ef4811c058cf7dd5b14c40bf32774934ff58479e087d0507c7ff6c86122723e96601705eb793f1f5e30dee784dce4ec17bb4f5cb77c2f77127735e3bd9fb8aff95ed15fdf86cf27e8cbc47dc5fb2d93bb346fec946c6dcdf8ee92fba6e17d0e12f735df978a1c260eeb7f911c3a86efff4ae22ec57f4a0e19a17f67892bce2b394cec1ae6bf4eec1beef734e314bfcb19337ffbd35fa2a2a6bd0e3aaa53af12fff67f1b3dd5333dd70bbd4c7215ad7ed9841daef5466ff54eeff5e1c36a5099d9048b479dea933eeb8bbeea9bbe279b45b50f9b255dd6155dd5355dd70dfda29bfa35596dd126ecb2ad3bbaab7bba1ffe2f7aa087fa2dd91c259b63fdae27fa437f6a162c729d68114e2961c3da14adb5d156bbb08588492f838ce2c4eba59cca19e2792e17722957722d37722b77722f0ff22853790a36cfbc97bcc8abbcc9bb2cca922ccb8aacca9aaccb867c914df9caf8c8966ccb4e58b32b7bb22f077228dfe4488ee5bb9ccc62283fe467b0c824978914524a25b534d286cf1d9de5c2c2b78a6e86af8f217c93b8d044a77666e7766197cc00ef25277665d77663b77667f7f6608f36b5a759166731942d7bb6177bb5377bb7455b62c6ff6b13adc289cbb662abb61623fddf7a59f8e7f7b97f010c08f25e 789ca599478f24397386effb2b06cbdb42e057953e21e8d0def7b477820e1141667bef5bd07f5754bc5125697a0f1a69720a83072423c9f0ccf9c75f3f4e76b67efcf58f3f9e5fe8e5527ec8053dfdf82bbddede7efeebbffdcbbffff16759fcd0bf555dff28fefca73ffedc7df9213fb6efeff204e2974218d91fe34f70d1778df19973eefb09871be371315069bc3ae3cae69f1a1765c964fce15c91bd3c5c1b9765956ae39519b736ff045c5539191f3bb7c3d8e65f39f7c360e3efc655d993ed2f1e81ab6ec0fb2e9dc9e71f1ad7badec6e39b71530ab1cd5f36eeaaecf35f8dfb6a4ca6af70614cf5c8c75f8cb9aa19fa3b30161d87fc67e35c119b7ec292f150d7befe69c2e35195d9f41dce8dc775ebe3fbc645dd0ca6eff8685cd653fd3e18d775c362eb178ddb3af9fa7be3ae6606df19533d88e933ee4d19f2c330639b1f5ae354d5047fb8053795c07e0bc6b9a9fc7de61fe3a1e904f6dc9d70316aea01e7cfc6e3a6f1f9e60f45d12431fd47b36f51b52331fb8bc92b9a8ae16f3c366e2b717fbb04eb814dfffcd3b8ab12d9fe78ce3983f3a3f3e0e7d9013709fb63c8eba7f3a974f6f921819ba97f5c80db3e99bd69cb98a6f3e9055c8fc8f4911f9c0bea6cbdd9bb9036279b9fcd5e45aa1b827d719edc9683ed270ee0ae48b63e9b3d8ba126327d059970396addbf321b8f5b823e6306776d327fc966cfb2a8b3fbaf9daf2c3b4ae6efd9f45f56cd98117ff3c6b5ca87bc6d67c6fe06c86fcaa6b278ccd7e0a686ff47ecafe9866cf2b2d9bbec9a8e4d3f01fbd5edb97e03b82f33e289678c7820e3beafb3c9cf66bf921b61e4ab39702bbedf2d70a72e6af3cd7e656a471e3f9f601dc7fbb13ef75dc67cb35739b415e229e0fd43e7fe1f2c9f56235d6ffaa337e7a93dcc7ed5b86d3dfe368df540be1fd35f55b52c88c70f70e7f92e9b7daaa61d04f305dc1582f39abeaab613dfff8671df0d03f46bf9b2a2cee33b8e8c998a8cfc67fea0d15564e8231ae7bef4f9eb13ae477debf2ec7cb50600c6939da72efb32c17f7be3a6675fbfe69c06f3df60f9b5eefaa9bd3b63a1a9feadbed449030afe6ef9a8ce258f8d93c57333ea25e1fdc13965f3e7f002a6a97dd69c19e74d168fcdb896c6f4272370effe297b601a8107d37f5334458bf5561fd5ddb9377bc80a98c6f05779772edc5fa7e384f3c4793097a81762fa6f2aaae0cf129cddbf63ebecfec08571432dfc93779cdd5fc3b3b3d7bf6cf5b169ab726ce765bcbfa53e9b3df9ca99b2ed8f2ae34ef565f3c9e2bde9353d987d33ce439a2030ff154c19e3a1731ea0efb80ce6f1807add1833b93f66ab874d6a9ad6ec97608fd4d63deaaf8ff3d43fac9e3603b72eaf9e705bb0d797f0e8ecfe3958bcb475dd57d0bfd5cbb6e134c05fedbc6dc71e3fc9fa99b6efc6c8dfe101cceeafc9ea51cbdd349f2f80a584bc60f9b91565e467cbef9a7c0b5f6fe7693309f245b2fcd60e94c0b1048bc71f993f7523f2fa33d8fc6e5c8f0be4c731587489bdcff4db697c229f47f397ae92cedf6ff6eea8e3def63b583eebb8eb7bf8f709b8afd09f248bf74efa0af53799ff745919f162f3fb715ff6b0a7d5afbea88702f9be9bb1e9332d8075bdbd3f59beeab57c8c517fac5febdb668cf5d2827b2d68366ee7d166b5823ca9c07d82bc60f6d3c38ce18fc9ea51cf3da3de49e39c60df04799a0fc5f4992c1ff7d20ffe3eab0f7d6a7ae85b709ed427b6f8ced6af6a32efb19f6cf269d4b52de4df8069847a28e67f34a6c2ebf71998bd7fcd162fa4f9c5cfbf03a612eb33b86e72817c5a83d53f91cf4d1f34f16ff883f91369b9863f268b57ea8818f30bf06cdcfc8d7a2ebc9e9a7f11a9ffa2befd74f67c94ac5ea8b0b118cbb273010e87602932783465ec2f5bbe27692b9c47ccdf287195e03fe69f94751cfdfd099807b7afe5031ac8fb5bb9077389f3c9ba7385f3c8b57383fe2dd5ce6d32fd0e967f79d4771dfceb10ac0fde37e7dca27f48d594b13e95ce1d381c81a5447dcdd62fb0f6677ede089ece4fc7ce8cfb5236fd73d19685f95b5a04ab7ed1bf9a3ef5b484f9c9fa8dc969bdbf81bc4a1adcafd8f239abbfe0fe95cc5edc6803857a763a63d45bab4f7ada16fd3d6f3a277fff97f390502f2ec0527a3f6ff59835bf0ae2ef63c6a85707604dbfd087d97bb27bf45b0c79bd8cd15f50e7ecfd0f9d3bf7388f58bc32c918f2e9d2592f7c262fcfd8fc83ccff59f337fa63da77ae309e2c9e7537adefe7c339e1fdbc07d6f7a11e5e39b7b89f10f493a4f6f7ad390bfa79867eb3be0fe7db74ae91bfe9da39e3fc0c7f1bf4fcb8efec3bb7d0373d4f19fd11cd3977184f475346bf44f0f72179fdcc660f1969bb8a7c5c83bba1c2fe6fc0698cf58271ad3faeaf0fe70efa117626e48374e8cce89768cf59e03f611f9c3ae41bb1faaba765bfef597d55eb09f2433a704ee8b7e8d479803f30b8925e60dfde3979fc6f8193c747b6f890ba1be1fc340f56fd23feb03fbd7d66dc170767bf9f843d67ef2708fb6b743fc8ffe61faaad16f12a97cebdeb0febdb54a03f0bbbce5effc33a3857c8d76cf574625d9c77b07c223d150df6bb02e601f930ddcd18f1f90a9ec64fba7466f727c8efd318fba5db19a37fd975aed12f861d70f6ef25d9f2b350e7f53ddd837baa113fb00709211e68159c46d0172d3a17b82fb3c5bfee2ec39f08e7e354fafe779c5bbfdffc04e769ff65f1a8de53b8fc25e7cae3919d6bdfcfe794e1af09acde037fa065e7dafd17fe93b2df3f32e22177ed18f943c0a9413ca79fce84fa9060dfa1e302f5be04f703eed7740656fdc39ee7ceade7df63e70ee301fe3d648f6fb6f5aadd11f25dda76968c78b3fca4d20bc8e3e8dcbbbc4d709ef69366af545051237e7ae7a686bfb4e0e4f9889373eff9f6d099fcfb84e5a354760c7d25ac2fa9aa6d9cdfc1d3fdd091b31634dbdf0638fbfd87ac5f50eb8afb2bde5feb83f1ec9ce12f44e099fdccbf53437565f69225b0e60bf3077e76f6fba788737636fbeae93bd7e79bb3df3719e7d56cecf22c1e539fc79ecfcc1f543b04e67b702efcbe68f79da4fe8df18cf30a8f3cbe5ec0b9f4f91bce7edf64f38fa47f906f04fa51ff457e13d83327bfdf710dceb5df3fc9b9f1ef25566ff47295502f7811ace3884fdb8f9e7684fb266f38b7ce6bce1d385b7f93c7da90e27d37603d0fe637ce2df20f1f3877ceebce3d38437ec1750d7b96607d307f9831c6cf660c7fbd732e5d1fabcebdcfdf742667f31f9d5d22bef8c199e06fd9fc27573caee09fd89fde7ebd3f3c064ff5c753f6ef19d9ec971b9d8f7ee004ac0d83ed572cdfa97692d7378b9fdcf503f20bb7e09c7d7fe6df7a9a01fd3a5bbe9b9c06f7137e040fa301fd4374f6fb79367b67a6ba403cefcf18fdc705782a3f63bde838fce5093c952fb04752f9a8f7e45ce1be23fb33c6792d9e731e0affbeb2eaece37ced5c83a9766efcbed4cf18f5cff2f764b79047bb33463c1e81f57dc672ee5c3a9b3f4e4e83efcd72e15c8193d5b3619c461dfce91cac0fe2f1d9b9c6f7d664fb1bf4b68afa9edf668c7a3606eb037f59766efc7ba3f9e7504ad9c05f4af0e0df9b693463f8df82b3bf9f2c5e27bbf7f12767974f963f26b3f17e7a9a31e26bc5d9bf2766eb6787268ff1bd9f1ec1fa60fea17387f791c5fb6435c6e97ec688b739e7dec72dde26abe12fd9f2eba0fd09be2fe58d19c31fcfa64ce83777c1faa0deca8ce16ff3ceecf2a12fca0dbe0fe5bd19db7e12ec6917565bbfe52cce965f26d29c8b19a35f337f9bccf6fbb3f5b743d208437e5b9f31bed7cd3bfbff77c93678f2188f670c7d587e1eb2cec77d04e79d383cfae19d19a37e5abf34d89f09efbefcff9e898c1822458e1253cc7188e7f1225ec6ab781d6fe26dbc8bf7f1213ec6a7f81c5fe26b7c8beff1237ec6af5f64ccc5f9b81017e3525c8e2b7135aec5f5b81137e356dc8e3fe34edc8d7b713f1ec4c378148fe3493c8d67f1ebbfa4988c511cc72296b18a756c621bbbd8871842a0c041420a390ce13c5c84cb7065cf75b8f95546b80d77e13e3c84c7f0149ec34b780d6fe13d7c84cff015e6c27c58088b61292cbb84abb01256bfc9580beb61236c86adb01d7e869db01bf6c27e380887e1281c8793701acec2288c4311ca50853a34a1fd26a30b3d450a44c4f6c8a4a550373ca70bbaa42bbaa61bbaa53bbaa7077aa4277aa6975f65d0abca08f446ef2ee3833ee98be6689e166891966899566895d6689d3654c2066dd2d63719db2a8354c24f5dbf43bbb447fb74a02b0fe9487f8bfa1cd389fe4ee98c46f69dacfc26a3a2da77c0d4504b1df51c394c908ef45fbdbedbbfda1669e09cf3055ffe2a83aff87a7a16bee15bbea365bee7077ee4277ee6177ee53795f0aa32dff9833ff98be7bec998ff6f321654130774c88bbcc4cbbca22b5f785557afe9b3ce1bbcc95bbccd3fbfc9d851197612dee53dde574d1ef181eee1908f54c6814a3be6137f4ef98c473cfe26a35019a6532eb952198baacf13aeb9d13d90ca6af579b467893bee257e9721617a162ef536c6b4c251ad702c7af5e147c9fa1be45c2ef497e552aee45abef9badcaa0cf331b9937b79508fd0d3c8a3eae164f2769570c1cbf2a4bf6779915779fb1b19ef5319c4f2219fe6532b74a852d6e58b9f74074f3227f3fa5b90455992e5bf91b122ab53bbc89aacd3929e654977b2219baa892779e615d9926d95f2537664f76f65ecc9befbe98e1cc8a17caa8c133af91f32e6e5488ee5444ee5ec6f658c54c6c4b63b3296424aa9a416d1d481b33caa2ed5ce7a8e46efff9ddea1e37719497bfdc959124b91841e268dba26eb73b5ca816a75496f7a17e9325da5eb74936ed35dba4f0fdf643cba8ca7f4acd17d4f4fe925bda6b7f49e3ed267fa4a73693e2da4c5b49496d34a5a4d6b693d6dfc2263336da5edf433eda4ddb497f6d3413a4c47e9389da4d374a6f7c7c98db1d47b56ad771fbbede498b52f9c4ab1da629fb1b4d11cf279bec897f92a5fe79b7c9beff27d7ec88f72337df2537ece2ff935bfe5f7fc913dbb5b4efefadf3ff92bcfe5f9bca05216f3525e9e48f96d192b7935afe5f5bc9137f356dece1ac1bf5be74cce4ede55297b2a653f1fe4c3dfaf952ae3281fe7937c9acf548affffe4efc9f0bd4c6e2fa7931b1eee6cbf2bc3f6d24e6e58431c02faaedf9781bd4cfa9c69eff17f91012978fefc8f7ffee33f014ac092e0 789c85d7496fe4cc0d06e0fbfc0a63ea3608ead3be20c8c11eafedb53d5eda0e722029c9fbde5e83fcf7d07cd9ca31d333403f53a5aa128b45a9fffab5343bd85dfaf5d78f9739cdaf64492ee979e957f77a77f7f9cf7ffde3df3f7e66d992fecd936629fbf9b71f3fa7f32559da7bb8efbf11ef1521b13fe6604e4793b918cddfae72ed5099efdc69d29837cdc5a25d66ee3c216b4fcce5a2bf1cba0b6f7ff8765da559529b37ccb5b6b7d6ffd4dca47522e63733a79474e60bb3a8ad9d8bd1d6cefbe62e65f7e7688b075fba05a674f460de71777078730f696aebbd81b324cdadffdcdca75d6af12371f770381b6dd787897b31deb579c8b2b4305f8d2ecd9d3b4fb11f367e93687c10cf4b786cbf701729e23b8cc6fedd9ad3b4f1f86eb909f1883d9c95e82f07dfe6a24c724bae68f1e2b26833acaf34d76591d97a82ed3f37659561bf2c5fb8cdbb0cf79bc16599231eefeed67d31dae6a337779fe37e6cbf994aca2dfe3177736ef74f7bee018e583f55498e784ddd698e7c833963c42f0cb0ce67eda1700f39f66707d6f12c7ed4b93377ee2e72b6fedb66d1fe168fb8eb2e72cbafb8ef2e73c4ffd05dc184f575da1feb09ee12e3d3d5689b3fd4eeda7d6eeeabbac0feedb99bc2e2c7d76ef276f41ff2d2f76bdd5dc3f4092fd6c7cbeec6d7ffe7db92544361f9439539adc4e79bbafbc2e2cdf7709d14b6bfbce64ee178e6a6127e34679a4f160f5a86753eecff35ace3d9fc5cb9b3c2faf397bb28b0de6377e946ff5cd76bd70782753d963fd4b8f302f1ff721705f6f76834f6efde5d16d88fa7d1a84f07eeaa403e9cb8ebd2ea076fba09edf26a2eca1ae721e4f022de81e1c5fd70391af54cdc3e5fe8dc3e9f5cba1b5fcfa9bb2d2d3f82d507d1e38dfd0ce85f6a7c6cbe10dd99c7e7d0ede353ed6e301eadbadb12f936196df747776ef2f9d7dd5ca2fe06775f5a3de217b849707db0f3257a1c10eff0e86e713d3fb87dbcf0ec168c175edc5d89e7dd977b315f188df5ae8d46fdfc740f7098c3ba3e9c677bfe49ad46fd3c7167a5c54f26eebc44fe6c8e467ddd7517ee1d7755225fac9e49a3fb857ccadd798178afb95b9c8fb00dd795dfdfaabb83e5035eac978eddbe3e267759221f4eddb5af677be10af930713715eacbb3bbad6cbfd9ea95b455857c23e45fabf984fd99baa9b4fa1c0edc827833c66b753d88cfbbbb86e36c34ce2bb9a9c27ce76eae100fdc3f69fdb4f9e4c4ddc201f1a0717ff6dc5ca1bed9f34d58eb2df2e9d8cd5effdc4d85f8f0e0d60a6debb1e7abc8a23ec991bbc3fed1b67bf07a85fc15ad8766f9331ae793dd291c3edc83ef1ff2e33b21705e9fdc1e8fb805b7698df38678767afeedfe09f5a1d3eb51ef4fddfa84b4f693d1d84f8cd78ff5ead55d793d443de9353f6c3ec1f9e9dba4b6f5c9be5b2b92f5b7f73519349ed89fc6ad47d0e65f777730e3fc0c6d5ed9fcfceed60a62b67ad425cd80f668f1e8d2bac3fdc51ad67cc6fb46eb2698196eb3cae22b570bd7b8bf5d37d7b8dece5f973529f229ecb97b5fdf09acf78bf372e4ae6ae4eb96bbad916f321af9f3e426983337d7769ee36f73aef508cfc795d198ff0dd6f1b01f6b6ec1f5d2bbfb06cf97f968bc6fd8f3bb2b9adccfff3bacf140bea4eeaec6797a760f182f5a3dee4a7de1c4fe5cb97dbf6303b705d64785bb467c43e5e61aeffffb0b637d9cb8a5463dee604a1bbc7f5a7dd7e469b0ff948dc6fbca87bbf57cdb1d6de735be8ec67ecf47237e8f3025585f44bcebf1faf7d138efaf6ecf3741fed4ed50a3be6d8d463d7e81a96cf0fb006ef43c22df0e61dd2f9c27e477abf1c77e9dc194231ec26edd01eb3f73573e3ef68ff4bcdafe30f283b41df9b3eeee5bb4dbf9ee84b4c2d87cf6bcee748006ef4f737787765976f72dea15f2b7d7eb51cf6fdd9dfbc83db478be21bf7bce5ad4637b9fe9064e60b1f1fa44db717f4feebc453ed9fb569fa951ffecfabee48ef0fbc2d6dfd76abc0f60bc5a98713f76ff7d233921fe96cf7d2bfa03d6c6b3f5e9ed148cdf4ba9bb65d4ff03f720d88f007785203fadfef72cfa83c9dcba6bb7d5cb5e1f20305bfef5ba018cfab0ed1e18f9790d7709a31eacb873c179fb701782f595ee4a909f8847afd7e37963e76748bb12fd25bafb0ef5dbcecf9075ad203e2beea1c37e583c87bc236f3f82fbbcc3fc763f43d1971ddea7ee47a3ffea68bc3fdb79d28761dda13e9cbadb1ef5c1de0f86aa6f7afcdebf1e8dfdb1e7891ebeb6c7fbe51f37bbad7e0c8d1af5faccddf7c8371a8dfa61e761681766710f3de2753f1af9d8c243e2fd27a3d1dff67ba021edf1fbd5de3706d6ebadde31d62b43d6231eadbb1e703eadbe0edd500ea80fb7ee0a0ef6bc1c7afd1fe4cbad5b3fd6beb0feb1f9edfd564103ce5f371ae765d9cd03f673e69601f5efc2edf3851bb7cf2777eec1e7ff1a6df34fe731449aceffdf27520c8bfefa8fa3c42ef6718817f6b9b4cf957eaee34dbc8d77dffdacfeddebb787f8189fe2737c89f3f81adfe27bfc889ff12b2ec795f83baec6b5b81e37a6731f7f537b6fc549dc8e3b7137eec5fd7810a7f130fe8947f1389ec4d3388b67f13c26de5f74ec494c6316f358c43256b18e4d6c430c2150e020a18bb3d0c75befdfe94ab663168670112ec355b80e37e136dc85fbf0101ec353780e2f611e5ec39bf7ef75dd3b310fefe1237c86afb01c56c2efb0aadfbef49ab5b01e36c266d80a13ef3fe85deeead8db61477bec86bdb01f0ec2341c863feaa3701c4ec269988533ef7f11dfc3794842aaad59c843114afd56853a34a10d5f1429101193fcaf3f69bda7812ee892aee89a6eb4d72dddd13d3de8b7477aa2677aa1453c2fe895dee85d5b3ee893be689956f4fb6f5aa5355aa70ddaa42d9ad036ed78ff4bdaa53ddad73e0734a5431d5fd74d47619d8ee9844e694667744e09a563ff8c722ab44fa90fe19a1ad25573e4c0c4ccc21df73cf0055f2efaf3155ff30ddfd205dff13d3ff0a3f67fe2677ee1b97e7be5377ee70ffef4fe577199bf789975d5fc9b57798dd7f5db066ff2164ff4db36eff02eeff1fed87f850f78ca87fc1def5d3ee2633ee1539ef199f63ee78453d6e71517deff5a73f0844bfd495273a33d5a8912348ab3f0a58f6116914e7a7dbe5c78ff1bcdd853cdaa67b9942bb9168dbedcca9ddccb833cca933ccb8bcce55516f9731bd7e43d74e1453ee453bef8449665457ecb2aefc89a8efd22ebb2219bb2e5fd133d0d679ab17399c83691ecc82e4d644ff6f52e335dc95c7b1fc8540ec7f3b511cf43af19bb1566c4f287b6e5488ee5446392ebba5f75eca99c8ee7ebfbfcdec5dbf01626e18c84e6b443295ff227ef732117f2265b32b3f3fb9fbffff82f5f6a9671 789c8d95d76e2c370c86effd140bf3ce087846d2cc4842900bf7debb835c4853dcfbba0679f76849cec65e7bcf8969c0fb59ff6aa89fa4e6c754ef686bbd37f563e2b11ffae755af3a0b0fbda9fae9fafaedcfbffef87b6252eb5efa55daf5f4e46f1393dbfd5ed5dbb8bd6906007502c8d28fa545f4c2ca1a5a5f6256ce55c42fc25eb8120e8ef75b64b6b62d89678483f0b370253c27dcb62df102b3cb84a785b5f093702eccf9aa2cb705f11af330df7966a744ff2a6c98d111ebacb49c0fb3c99c75b46e99b5f6ecc73bf3f0fb9a38cf820db4fe1f47e22de6e40fe7f3c6ec0ac987f72f867a235c5bd2a3222eb3d692bf9831ebe03de9ef999d95fd8e89ad5296794f38f2f3f180d8a9dc295adf172e1d9d0f59ef8df2fcfd55661bb95ec8fa90eacf7e6f0b07c7fe1d095772de5b66eb9b9a7885b9f30ffac25efcdc248eaa717cbe75e24ab58efc4561e3033fff82d945f9fe0671adb5e3e72d0b1be173661b391fe4fe6eb5f519adcf0a3b4ffe20f7639b0a48f541ea6fa574e57362ea07a54db288f895397791fd6d995d23e7bd2336c95fee2fea07959bc273fd1f995d2dfa86b834c173fd1f86cce795f5b2ae291f20ff944df3c2f54062679ac0f37d2fdc06ae37e7e37217b85ec0ec655e90fa51f95c8bdf1bcc9ddff0202cf38b540f15f23c70bf1c12c7dc06aa2792ffaa4acfe37a9e31172a723e342faace23e78339b3efe68deaa9da228b542fac8515fb8d745fe8acc8793fa0ef6b95f2e1fa55cc858d741e24bfb54ef6b35f9139f9cff56436451539ff23665f4a3e97c47951473e4f202e4a15b9bfc84f5d9626b25fbbcca9dfd99f5362eb5cc3fedf307b9967a4f94add28f3013bc4bef303ae859de84be2e0b5e4ff225cb43c4f57c475b71fae0877f3c3eb6dda8ffb91ea97aec352e6f79279a8a7f936cab50d33ddf7467be9773c211ef8c5f9d0bc1b1bbafb9dee23e37c10a6fbcef8d4b05c1ff2cbc4f43c9e17bacf4d93f6e7f3d079f3f4fea8b95f5ae6a0247f7a7e6ed279f9f96bc22def0767cca17b9fd0fd9abab57bdf9c0a4bbda11870916e47992faa77d1c46e5e68dd16b112a6fbd8c5aaeb17aa5fc8ea4e4ff76b4ced234cefc358d5dd3cd17d54f946de1748efcfaa69ba7ad3fbb0ae9bce6fea9f266bc55fa4fe488bd24fdb7d0e040c18b1c2bafbcfd7f8a40fd8608ba77886e778f13ff4977885d77883b77887f7f8f04bfd23f6f129c533bee02bbee1fb2ff4d33883b31473388f0bb8884b3fd52fe30aae0e630dd77103377fa2dfc26ddcf910bbb887fb7830567f884778fc294e3043857a8cde608ec5489468d1a1ff4e0f0800e14b44a8a0fe56df400ba7126729bacfe7dfebf10d2ee052e24afe5ec30ddc8ed9ff0eeee161188fd087a714cff03266ff45788537897798a69819a8c7ec3f0b73304fb1903e0d6211963eaa47f4cbb0f2295661edb37a44bf0e1b1f6213b646d523fa6dd819c62eec7d558fe8f7e140e2108ebe538fe88fe104b2140af4f7ea11bd811c0a28c18e538fe81df881729c96f4fffc3ef12f1315fbfb 789c85d4594fdb401007f0f77c0a8b7d43d5e0337654f581fb3ec20d551fbcf69a335c0967d5efde99ff2c46a642f51fa1fc3693f1c4bb30331d1cef6c06d333bdf1a49c5c5441755e3e04d3f5e368f4faf3d78fdfbda9a808f8274f8278ea5b6f6a3809aa60ebf6c609a8669810175cc14d548628a6521c5512d8899350025b711a4ac4c6c0b10446bf2c91c004a7127c3e810b091cc156021fc28d048ec5fd5002efc1b1040ee15402afc1b8e0033897c04bf040024fd4655666f0296c25f0135c4be013d849e07b711e4ae0633896c0777022818fe04c02dfc2b8e07d7820c1f36b602bc1fbeb7025c1fbd89fbc96e0fd6571114ae0673891c0d8af22755584e76fb09fd80e9d07f72b72093c80ad042e6027c1e7cfc4652ec1fb63d8f285e76f70de6c2c8171be6c25417d2ec6d7d1cff7c575248133d84ae0548cc7affbbb2b6e5297d57a9e56e1cce5be7ee85dd47abf45b8cfd6e7f5e85d3a7d5e0b70eeacd3fbdf78574ef773c7bb767adee6e1c239a7cf6fd45ae7db86074de874beb9d67afeaebd2357c25b70d9c44ee79df54e9cce7be59d3a3d7f9bb0e53f179dffcdbbdfe8fc97ad75fe0db86a8a46e77f6dadf35f780f1a9d7fa5b5eecf0b5c73479dffdcbb6a74fe07d8c90a8cf3d1e0d27f46c309192a39f65364ada27a3869eb1c35bc7e46e77441977445d734a21b5eb9e5ca9a6aadfbb297a5bb8f3a7ef575affb7fea1e684c139f313dfa5e4f9dba675e7da1577aa3599aa3795aa0455e915e4b9dba655e5de9f45be515e9b5d6a95be7d50ddaa42ddaa61dbee7907679457aed75eaf679e6cfdff700bd0e3b75473cf331cf73c2f73ae53e5213a257d4a9d39a6ebf18bd924e9df4b19452467dcaf9554103fecdbd0c75eae45e96322317ef82b17852dccb549d3a99c752df185a3335d739c34f1ebd9c54b57532b3a5dc94a63667fc4abe977defd5d6d5d8f38f9350b6f1557aaedef555e4dcf973f59f2aaefbf3bdf717c301c7d2 789c559659535d390ec7dff329a8e82d35a53ebb7daaab1f8090859d4008616a1ee4e500093b17084ccd776fdfbf746f677292825f24dbb256fff16ee5647f67e5dd1f6f1e6632bb882bf15cee57dea5c7abab977fffe7afffbe795b0f2bf3bfa35b69defeebcddb83d94a5cd9bdb9ce73a0cb02d474fd142af01578e8b34ce06be3857c5d7968420bee8c538860a7ec9aa0fbaf81ddd0860e7c603c04376739572efaba7e15ec873ef4e05763a7faf462ec83071f194f21817f82c7729edab76f3c0601ef816508765e6b1c8d778d93d9ffd538dbfecd9221e7111c864a547fc7389a7dc7caae0aeacf7ac1b1c6fdcf8c6b65fa058ec55ebdff3765d798dc2f19c1a40fe0344818c11f8da3ddf71338177bf57e9f8d17feda542ef6a9fd95711bd57f27c69d9d773ae7b65ac44b26e33e6a7ce18fb65e3283fb7e1cd5fe0de54144e3ff041e9cc4019cc16ec9bade17567de46b3bba18d5bfb7e050f6833ec33f6d2cf7c7f942e0b4d097649c22fc258fe05c58e571ce5d55ce43be0beaa1ab7da5fa04fdae73c1fc710f1e16faf4601c6cfd0cec7c17d5ff7760ef46f3f70f63d3a79971d2fd05f9dc8dbed278cab5b1edc7c8af2eba2e409f11af2eb956d43f87cabe367fdc180f11e78bda9bbd57a6f773eeab729efaffdeb88bc84779351e2d1eab4b467e33f2b7af5d258837df1ad7a2e76f2a97fd341fbe180f76bfe72507f036b819bcd7fd71ffbe2dfba97f4f8c83f607463fe93bd7a89c5f96acf1c2fdfbc14de60fd443ef7c4aeaef2db0f79dd693ac196795b38047e745f3818cb3f64746fef6c18d26efc1c98fd6ef50cf7df641eb43509ffd3456ea3f1ae63c54beb5fdb697acfb5d18478d07c39f43e38268bf08ca0b3925e364f1da551eeb08ff12f27d68177246ff1e3a2f56bf62bc90abbef84efb9da03f0e61f409faace725ef83f637f4e7211739fa89ec1b87a4f58679e0aa51743d6d1927d3df33ce49f3e3d8784a5a4fdf95a54a9aafb0dfd5a561e07e1c8c45eb430e9517e709f2cf35c51eb55ff7438301a3fe5d375a7f945363ebc782783937f6da2f05f1717eb4fa61cc1717c66cf5867c7471ec34df79304e11fd981be385feba721948da6fc5d8a93f18f9ebf218cddede78d2f5acf64e8bfdb8325ec86b65b1fc63cc735faa3769fee13ebef847ef17d08f7d3b7aeb6f9877be1f17fd0af55ebc9f13f60fb0d7fb2257ffc03e1f2426bd2fe2edd398745e4aa55ce47a7fc4c34f52ebfc0ca8b7b1922e6a3e74caa1ca1acfdab83686ff8bb7bbacf9d12c59df13983fa30b83d98379367ab1fec387caa1b2fc785eb2d603f2732cd9a5f94cd9d8e2c5a8b73114b9ea1f19b7aacf7a9f28363ff8557929877f8b7716eb516f630e9dd50fe6ad3432e9fc0ac87729d34099d16f24845ee72963fe8436f659fb19f2ab48fbacfd1aef87f27ce993e603fa5f7071307df4fbe0a3337df4af124e6f72d47728d965fec67c8b551cac3eb17fec527960421ff517637259edbd342e050fc6fc4b5d4a59fdf9649c8db17f1a7235e9f99857c9e72a6bfe609e25c99dc931efcae3ae99347ff15e48d3fc831cf3bdac76aa4f93b19f10ff80fe97bbdc648dd799b1337b6e8cbdda2f988785ec3e82f75a963c4dea8f0de5a952a6b325ab3f607fce53a34ce74bc63c60bc17a67aea9409f3621ae6050e39faeb342f78edf7cf4bd67e128cc518f931d7b6f5b0b748c3a4f180bd13feccf960a61f130b078ee54b9c795afcff4287cff89c2ff807ffb4ef92aff8fa771dbee15bbee3fb227be0193f969f4f859ef9d76f3a2ffccaabbcc6ebfc9e37f8037f2cbfaff127fecc9baac35bbccd3bbc5bbe3ddee703fec2877c04fecac7fc0d3a27fc9d4fb9e29a1b6eb9e3befceb7860c79e47629deb24142852a24c139dd1395dd00ffa49977445d774039d5bbaa37b7aa0193dd2136fd033fda2177aa5555aa3757a0f9d0dfa401fe9137da64dda2a3adbb443bbb447fb45f380be40e7908ee82b1dd3373aa1efd8e7942aaaa9a1963ad2393e90235f1a0b0b89f08694929392d632c9999ccb85d69afc944bb9926bb991dba27327f7f2203379942779965fea437991575995355997f7b2211fe4a37c92cfb2295bb2fd4fbc644776654ff6e540bec8a11cc95739966f72f27b4c8bd6773995322b4aff69a5935e0671ff1f776895b752e050dc194a230a71991bfffbf3cddfa68f6847 789c5d96594f5d3b1285dff32b50fc16b5eaeed183aefa2104081920104820b4faa16cef0d84190e995afddfafcf5ae6a4fbea44913e5c7695570dde7fbc583bdedb597bf1c7b387852eced35a3ad3fbb517f9f1eaeae7bffefdcfff3c7bdedab5f2af6bbab5eef93f9e3ddf5faca5b5dd9beb6909ba59c0344dd737cd92a3561ec966068f412b9f807d9b7aec37a7e0a0beaeff0427b564e997dc466b5b8bf577e0dc3b8f6074004feddc0de0915cec1dec77c0b34e6d8ff58f4bee1ae75b45bc88afeb87dc317ec4d3d93e7623ec0fc963d305704f7681f6e61bd9abf588771dec8a7d84bd21fba1cb383f83c33075882f4ee4b1efb0bf48bfe41cb4fabf054fdad4fb41df6e1e6a3ce6fb92fb66159f803bdb04eaf5033ce8d4e1be7a0c0e6e1c119f58b0bab167bc88af8fc1f7f06fde83736c7bf8372d784e4d4f3daf973c74e33ccee0ab27d684f317e0d13b87f3cd1ed8b990b1aebfc0defa887c9a061c7418c042fb38a691fc08ceae0fb4ff525927ea19c173d981fbebc18ab12eb764d78fd4776bc963eb06aeeb0d394eac4fc5fd47e7bac47cf7643f64def71539a6818c7a1bbd6d3ce331648d23f4923b721c6a7c091c52a908aca39fc6ac5ae379099e6c9108fecfc9b1de47f72aa791f5c7f867cd35bfe827db9604233e83786de7d3c4fe817eb60f7e447dea5bf0e0fbcc7a5a9043647d9b001efd34317f6fc8ea2ccf43ff585bd65bf887bed6b9d6317ff4ef62b0385f509f3684c6323efad7d0cfd4fbb8b24ed467a772b69c1f5fc9295bce0bd4a78d5afb31425f9bec6ca9c721d99512c4fe8e1c1ac7fabeaedc557d8ec8b17788379e81b3f5d53fd7b33613f413de3fc7c4757d4d4ed132ff9817767263607f5d549e78bef94cd676623d35e438317efd444ed6b21ed00f760e65e4e1fc0372ea797f7d20e7d6b2de517faeb1c1213f06f771fdf28775c4e786e027c6077f6ed4b1e603f9765607e6c3ec571e2b639e39e763c6f97a490e73ad970d720e551ff4ab2bfd41fd05ef83d3d065f6f72159957ac85c3939d623e65529a7cc7885fe637435bf98f72ea9327ea99cb2a33dead92df3c77edc26970786f5e0c1937afa37079563e5edcaa99e8f7a7273d6badf2dd9379aabbdad3ccdec8f0fe4120fe7735dcf5dbd1fdeb7f2583ded1f9fb8ee47bff82e84cc7970428eb3a79edc3f26ef698f7af04510877c18d4a72fd397e799adca4ffd877cf9b0e2cd15f33ce4cfa79438ef14f3c6679db9ae2d397b4fbd51dfa1d134b1de17e4a7f305f328b43a4fd4e3821c6df5a7e43479ce8391bc74007bcc83d0455ffd9f570e33fb19f51eca0357ef7bb762f627ded3300417a8cf0379657fb362d6e7ed8ab1dfdc57d6babe0bb6a17408cecfe4dcf1fd52f44f7053e7995fbc8721845e391f797fcd4a7b41be428c0dcf9797e45c1e109c87efa3908b5ef47749cee54507ef569e387f04f331ccd906ce17d4a33631d5f71b7a695bfc8323be2fb49b06da1becd721b555df1f95fb99f1404f1dcbf3c8f9d291270d9c17a81fb569acfae98ad93f66c59c47f4efca40e7f9a8a7321dca0713e2c57cd298ba1a0fbec78a7c4511ac431f9d6397d91fa897384c56596fd02796072572de6c90cbf9e45f9535b2be5ce5f28509c63c897eca91f584f7ab8ca766a6ffa3ca1d59315f62190791f160dec7187da6bef89e8a2996898475bf62ea83fbc51c27aeebbc62ae239f718e73bd2fe679ea539ff95ea15ed338cdfcbe11f82b8fd79c783fbc2fc9a586df3b62c8d398385f517f29a4d2f2b0c7fc2dc5d366f6a7ab3c567ffbe4b29ffd8ffa4c3185ba7e4d9edb44bdf0fd55c64b4f3d04fd5cd4ecb95f307f733b3533ea737fc19f1851899224cb24f3d35ff717bf6de454cee45cbeca855cca955ccb8ddcfebf8ddcc9bd3cc8421ee59b7c971ff2537ec94b59ff6d23af644336654b5ecbb6bc91b7f24edecb8eecca07d9a38deccb47399043f9249fe5a8fc8ee58b9c4823ad74d2579b4146b1e2c44b30628c51134d32d94c6636a7e60c3a9d9bafe6c25c9a2b736d6ecc6df9dd997bf36016e6d17c33df61f3c3fc34bfcc4bb36e5e990db369b6f0ff6bb36dde98b7e61d6cde9b1db35b6c3e983db36f3e9a0373683e99cfe6c81c9b2fe604368d694d577cad9bde0c662c3f6b9cf1650c899ada275153e9aa49673dd5333dd7af7aa1977aa5d77aa3b77a477df45e1f74a18ffa4dbfeb0ffda9bff4a5aeeb2bddd0cd270d754b5febb6bed1b7fa4edfeb8eeeea07ddd37dfda807bf73a187fa493feb911eeb173dd1465bedb4d7e16f39ddd351ad3af51aa2c4d25731fe3defcbdfb27fe254bae2349efd4f6dfcf7cf677f01d5c87665 789c6d98d78e25c70d86eff729065b7782513a9dbb61f86272ce790c5f90aceec9398fe07737873f4f6b2ddbc70be9132bb018feaadedf7f9b39d9d99cf9edf71fcf2ff472293372414f33bfa5d7dbdbcf7ffeeb1f7ffcf899e733faffa26e67f29f7ffbf173f7654666b6eeeffa6fe0258590a5bae3daf8d1b8af5bae8cef8c87ba819daa6fceb3bae4c278dd38af73ce6cfc89715133db66746f5c564c627ce72c946cfc2ab8c9b933fb837155f5c4c66bc67535d060bc04ae0b2e8d4f9d1b6e8d5b67f79fb07e5367f08f569c73f7af1c19e759762e9c8b916d3fbe75ae3c1ee076f42f07ab1dfb67ce353736ffc6b901d399738bf3f3b93333e23531eed46ee7e3eb9131feca99988c2f9d992d7e7cec2c588f679d07367ff9c998c6f9cfcee2f31747c6fc8b9191bf35e7e4bc3032eaebc8b9779e1f19fb1f829b894cecbcd88fa7f1e117e7e9faafce83afb73e32d67b033713e7b929637d7e77cec0d28f8cfacd9c73b00cce0538a0fea54a847a38008ff373e75cacbef8c3384dd7e30de7027649c67d530aeab9331e347fc86f744e9e8fe0dc7b3e04dc647ede7de752ac7e797364f84bdf5c4c345e882783355e8867e15cb93f56af45a6f586f9e66f91abff88e796732d56efc1faa928ea12fdc07b605dcffc910fe716e3d9eabb289b0afd26e2dcb81deb553adefa4d6e9c3be74fe3ba19e06fa88d75b90ef1de068fe3ad7f8ab69d80c9eab5e8547f2cbec2ce2ca83fcb7741cad0179c579a02fd22b7ce09e3c5fab7484d83f370ed9cc4f2192cff455f37a81f0960b5dbfa4223430f2d7fc5507704fd6a9c05f383e5abfccea7c54bdec11a0f9b2fd66f65d6b4d02b31fd2d733d3feaab19d9ce4356cf65a1e7853e5abccab2a95d8fb69d5bd40fed3877a83fda9db2f717b86ab4e5cdbee74ce807da77f6fde40ddc16827cd8fd51d6232f38d762fe08fc699a84fdc5f4b06c9b0af787c03fcd37fc0fa62765d74c509fd1f25baafe7556ff023bb5a5eff7e05cf97eaf23dbf9a3e94bc93a1f9c3b4b67eb8777e79e701f3c831bd74f32fd2d551f60974570db607db1fbb8ec95cdbf68f5576aff63fd88780e7a1eac7f0856ff916f1b5f4dda4e30defca972dd0ffdb6046ec9eda67755510f7e9e1edc4cc0d23a5764f59e6e9d197a1db69d7be89754e0b645fcc8e25b7de713f97f752ebddede9ca77a71e8dc396f3aa7043d86bf4d53ba1e3f805bcf6f689d4bbf5fde9d6bd7b70f67d71b3976f6f5e5c87970b67ea93abda0512fd6df15b58c7847d3c78a9b1afd9a6ec07a7e3b5f347da8a469087ce74c64fd17b69c1361fd65703749e88f7264c4c3de5b55ea3270b0faab063d8f8d4fa62ff5a44df02f995ed6599b43cfa5007719ea8bec3c75d192bfa7ac9feab2eda14f6cfda8cfabc1fb09f6b69df6ff8673823e46cb57dda9ddd64f1fcefe3e912fe7c119f3bbae4de65fb47aaaa9cda01fe9c139a17ed23558c7dbf9d3e5c8d047bb4fb51b33e8335d3a97d0bb74e1dc20bf899d39d979d3d5c856cf1176ed4f7f4f3e3a33f437f4ce3dea9522b8cbfdfe08ce85eb3b8d0cfdf5f5a7feb1bd0febbe157f8faf80bbcae379eedca23e9238bbff11f91d5a2d51b327704709fe5aff3593b646fdc54b67c2fb38f5e0aef3f5c979403c92f55f93e97a76de68f96db47e50bfc1fab92995a19f07e0ae80fe8575e71a7a1bacbf9abacb513f2173eedc0eff9ab6877f8cfd9bae773d363d6a5ab5e3fe5f0677ec7af3e9dc23dffc05a689ebabc5afe9ba0cf18e6fce53bd3871eea16711f1a0b6c779d33b9826097a60f5d5b09e076cf5d4483b201e7c0aee08f90c87ce3df43860bfd40df02f1c8c0cfb1158fd374e8fcefac4b4f5779d4bd777c453eb03f5252b60d20787cdb77a6d86ceefef30018feb5bffb7136d60f8b3e33c20fe617764d8f7c0d3f961df39733e9d72c27e67ce3958a6761564b39b3eab1ab83dbd3ab7bd71b4f74e9b77fe1e4b2fe0a93dbd39773dfa1de30bad67d89fc1a3ddbe6fda729a9fb402d6fce23e88ceae1f11f169f47cd017fbde52794c8867b27a6c3bfd40c27bcfeaa3d5ed7cfd05f068873ffaf5ecfa66ef8d565f7f88378933a3ded21398273df4cffab14de4fa48386f4fc9fbd9be8fb51a6bef9fdab9f3fbd5f4bbd37ce23e485f60cafc3d78e13ca0de92bd27ba4cfdc579ec3dd3e5ba1ff26df1eb0ab563fdb591a1f716afaea4caf57d6b64dc57d6ff5da5e7c7fc2fe7e47a36ebdc3bcf8f6cf10973ce83db574786ddf4413fa77dbd68f76dd750e3fd60f9d1eacf919f60fadb917e20207ebbcee4fece39fbf743825d2879ffd9fdd4693edcbeeddcc31ef7c15c22bed1de13dda0765b3fed380fd0a364fd469a0fcc0f563f9a2d9500dbcfde07a45f3bdeefa6bf54b3df47c1f4534f33b5dbfefabc29ddfee42cb007f387ba91af47463c2c9e7afcdacf67f544c2fe1e14f8abaf45afe70496a2c7fbc8fa5bbd2bb01ed97da4b3b9b7fc247b3f31eb0739fc4bcee4f56ffdc6a2e36dbd1047c67d65ef093d2ca3df633732e69b9eb2aabdfbd38e8c7a6d9c1398ac1e455f6b3df207cea4433dc93a58ed788f0c23e3bd7ce65cf4b8efec7cfa1c2c610fd64fba5a83f5c9ea4f3f26f442b3f956ff222947bf45d36fe9d58efb6ac399303e987e88dee6be7fe6ccd85f6c7e9a24f1f976df24cd86f3c1c8f8fb844f709f0f8897e9752a477b0f1eed76dfa52af56edf01f7c580fc987ea73a0dd82f99fffa39dd797d62ff56d9fc8d0be03e1bf0f713ad7335205f964f3d6dd6e37d6df5aca76d06e4c7ea5dbdf17c44eb1fddbd86bfc1f4ae9ff485db9f9c1bd8e9c899b05eb4f3e86efac96f6cf9ed2bb5a3be4c2ffbba4f3edede87bd5ed088475c769601f3579c93b3e957df8ef613e7e97a4b23c36efdd97f5f37c8df9af3d4beeedc3b2f8e8cbfdfc07efd500e88b7ddcf4331d403f4c6fa6968bf05c9d8deb3433765b27a50e201f9ee9c054ca6976a9df2acb3a6c0d6b3f87c1358ccff6f72fbfdc8b86fec7d36d8ffbe79f765fa8b2152e42831c53e0ef13c5ec4cb7815afff1cf1ebf878136fe35dbc8f0ff1313ec5e7f8125fe35b7c8f1ff1f3afe3e3579c8d73713e2ec4c5b81497f5cf4a5c8d6b713d6ec4cdb815b7e3ce7f8ddf8d7b713f1ec4c378148fe3493c8d67facf23fd1dc649cc621e8b3fc7c73256b18e4d6c6317623c0c2150e020faef9dfeda90421f86708ef1e1225c86ab701d6eec771beec2bd8e7f088fe169fcafcfe125bcfaf8b7f01e3ec267f80ab3612ecc8785b01896c2725809abfa9bb5df5a580f1b61d3c66f85edb01376f5b717f6c341380c47e1389c84d370a6ff9c842ce4a10865a802eed726b47a1d46d23b81f455432a4434d0395dd0255dd135ddd02dddd13d3dd0a3e5ff899ee9855ee98ddee9833ee98b6675ea1ccdd3022dd2122dd30aadd21aadd3868ddfa42ddaa61ddaa53ddaa7033aa4231d7f4c27744a677a2feacb910ad2f784ff7d943eddf5b68a1c98f493548594fbeff13cf0395ff0255ff135dff02ddff1bdd5eb033ff2133ff30bbff21bbff3077fdaf82f9ee5399ee7055eb4394bbc6ce3577895d7785d476ef0266ff136efd8f85dde53dae7033ee4233ee6133eb5f1673ce18c732eb8e48a6b6eb80da4b76394207a6d8a4abb4af120e77281f7905cc9b5dcc8addcc9bd3cc8a33c7dc7479ee5455ee54dde75ce877cca97cca27e644ee66541c72eca922ccb8aacea75bc26ebb2219bb2a5b3b6654776656f5a6fb22f07722847722c27722a6732b15f26b914524a25b5e8e7ccaff5acb7534c2151d26b347d0bffa07fced345ba4c57e93adda4dbbff657ba4bf7e9213da6a7f49c5eeccf6b7a537a4f1fe97ffacbe77ca5d93497e6d3425a4c4b6939ada4d5b496d6ff7fffda8c8db499b6d276dad1df6eda4bfbe9e057fbcf7ffffdc77f001fda96f9 DVDTitle widgetTextChanged(const QString&) DVDSetTitleInfo execute() ScanDVD clicked() ReadDVD execute() OutputDirectory widgetTextChanged(const QString&) calcDiskspace execute() FormDVDCopy selected(const QString&) Init execute()