From 4d64e4cd434426234a5c313c151cd79b6afc299e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juha=20Vehvil=C3=A4inen?= Date: Sat, 6 Jul 2002 17:50:18 +0000 Subject: *** empty log message *** svn path=/trunk/Framestein/; revision=27 --- CHANGELOG.txt | 130 ++ Filters/BossTota.8bf | Bin 0 -> 57344 bytes Filters/BubbSpac.8bf | Bin 0 -> 57344 bytes Filters/ChloeMag.8bf | Bin 0 -> 57344 bytes Filters/ColSteps.8bf | Bin 0 -> 57344 bytes Filters/README.txt | 9 + Framestein.exe | Bin 0 -> 874496 bytes HARMON.jpg | Bin 0 -> 31376 bytes Patches/00 example-basics.pd | 38 + Patches/01 example-video.pd | 30 + Patches/02 example-docking.pd | 88 + Patches/03 example-docking2.pd | 15 + Patches/04 example-draganddrop.pd | 25 + Patches/05 example-plugins.pd | 127 ++ Patches/06 example-photoshopfilters.pd | 105 + Patches/07 example-blending.pd | 57 + Patches/08 example-masking.pd | 66 + Patches/09 example-sonogram.pd | 74 + Patches/10 example-waveformdisplay.pd | 126 ++ Patches/11 example-browser.pd | 30 + Patches/12 example-network.pd | 62 + Patches/13 example-avioutput.pd | 61 + Patches/14 example-hist.pd | 46 + Patches/15 example-searchpath.pd | 28 + Patches/README.txt | 1 + Patches/arraysize.c | 44 + Patches/arraysize.dll | Bin 0 -> 36864 bytes Patches/arraysize.exp | Bin 0 -> 594 bytes Patches/arraysize.lib | Bin 0 -> 1986 bytes Patches/arraysize.obj | Bin 0 -> 1761 bytes Patches/bangx.pd | 10 + Patches/buildstr.c | 51 + Patches/buildstr.dll | Bin 0 -> 36864 bytes Patches/buildstr.exp | Bin 0 -> 586 bytes Patches/buildstr.lib | Bin 0 -> 1970 bytes Patches/buildstr.obj | Bin 0 -> 1830 bytes Patches/count.pd | 17 + Patches/displaydepth.h | 19 + Patches/dllcall.h | 46 + Patches/externals-documentation.pd | 342 +++ Patches/fps.pd | 25 + Patches/fs.avi.pd | 33 + Patches/fs.blend.pd | 37 + Patches/fs.browser.pd | 48 + Patches/fs.copy.pd | 51 + Patches/fs.draw.pd | 32 + Patches/fs.event.pd | 30 + Patches/fs.film.pd | 47 + Patches/fs.frame.pd | 137 ++ Patches/fs.framed.pd | 24 + Patches/fs.fx.pd | 21 + Patches/fs.hist.pd | 39 + Patches/fs.info.pd | 33 + Patches/fs.main.pd | 52 + Patches/fs.mask.pd | 39 + Patches/fs.rgb.pd | 31 + Patches/fs.sonogram.pd | 63 + Patches/fs.text.pd | 29 + Patches/fs.waveform.pd | 146 ++ Patches/fs.waveselection.pd | 47 + Patches/fs_sender.pd | 7 + Patches/init.pd | 9 + Patches/l2s.c | 89 + Patches/l2s.dll | Bin 0 -> 28672 bytes Patches/l2s.exp | Bin 0 -> 546 bytes Patches/l2s.lib | Bin 0 -> 1884 bytes Patches/l2s.obj | Bin 0 -> 2407 bytes Patches/makefile | 38 + Patches/noize.dll | Bin 0 -> 36864 bytes Patches/ooo.pd | 19 + Patches/play.pd | 8 + Patches/ramp.pd | 35 + Patches/randombox.pd | 19 + Patches/reset.pd | 8 + Patches/sameonce.pd | 15 + Patches/snapOut~.pd | 45 + Patches/vcolor~.c | 96 + Patches/vcolor~.dll | Bin 0 -> 49152 bytes Patches/vcolor~.exp | Bin 0 -> 599 bytes Patches/vcolor~.lib | Bin 0 -> 1976 bytes Patches/vcolor~.obj | Bin 0 -> 3898 bytes Patches/vcopy.pd | 16 + Patches/vdrawarray.c | 131 ++ Patches/vdrawarray.dll | Bin 0 -> 49152 bytes Patches/vdrawarray.exp | Bin 0 -> 602 bytes Patches/vdrawarray.lib | Bin 0 -> 2004 bytes Patches/vdrawarray.obj | Bin 0 -> 4031 bytes Patches/vframe.c | 262 +++ Patches/vframe.dll | Bin 0 -> 49152 bytes Patches/vframe.exp | Bin 0 -> 570 bytes Patches/vframe.h | 66 + Patches/vframe.lib | Bin 0 -> 1936 bytes Patches/vframe.obj | Bin 0 -> 7069 bytes Patches/vframeread~.c | 123 ++ Patches/vframeread~.dll | Bin 0 -> 49152 bytes Patches/vframeread~.exp | Bin 0 -> 631 bytes Patches/vframeread~.lib | Bin 0 -> 2044 bytes Patches/vframeread~.obj | Bin 0 -> 3703 bytes Patches/videoscrub.pd | 29 + Patches/vimport.pd | 11 + Patches/vplugin.pd | 9 + Patches/vref.pd | 10 + Patches/vrgb~.c | 117 ++ Patches/vrgb~.dll | Bin 0 -> 49152 bytes Patches/vrgb~.exp | Bin 0 -> 583 bytes Patches/vrgb~.lib | Bin 0 -> 1942 bytes Patches/vrgb~.obj | Bin 0 -> 3717 bytes Patches/vsig~.c | 123 ++ Patches/vsig~.dll | Bin 0 -> 49152 bytes Patches/vsig~.exp | Bin 0 -> 583 bytes Patches/vsig~.lib | Bin 0 -> 1942 bytes Patches/vsig~.obj | Bin 0 -> 3346 bytes Patches/vsnapshot~.c | 139 ++ Patches/vsnapshot~.dll | Bin 0 -> 49152 bytes Patches/vsnapshot~.exp | Bin 0 -> 623 bytes Patches/vsnapshot~.lib | Bin 0 -> 2028 bytes Patches/vsnapshot~.obj | Bin 0 -> 4210 bytes Patches/vsnap~.pd | 18 + PeRColate Framestein.pdf | Bin 0 -> 7998 bytes Plugins/2colors.cpp | 21 + Plugins/2colors.dll | Bin 0 -> 28672 bytes Plugins/2colors.exp | Bin 0 -> 627 bytes Plugins/2colors.lib | Bin 0 -> 2066 bytes Plugins/2colors.obj | Bin 0 -> 1133 bytes Plugins/README.txt | 12 + Plugins/bend.c | 86 + Plugins/bend.dll | Bin 0 -> 49152 bytes Plugins/bend.exp | Bin 0 -> 697 bytes Plugins/bend.lib | Bin 0 -> 2110 bytes Plugins/bend.obj | Bin 0 -> 1726 bytes Plugins/black.c | 13 + Plugins/black.dll | Bin 0 -> 28672 bytes Plugins/black.exp | Bin 0 -> 700 bytes Plugins/black.lib | Bin 0 -> 2120 bytes Plugins/black.obj | Bin 0 -> 560 bytes Plugins/colortv.c | 69 + Plugins/colortv.dll | Bin 0 -> 28672 bytes Plugins/colortv.exp | Bin 0 -> 708 bytes Plugins/colortv.lib | Bin 0 -> 2146 bytes Plugins/colortv.obj | Bin 0 -> 864 bytes Plugins/copy_vert.c | 30 + Plugins/copy_vert.dll | Bin 0 -> 28672 bytes Plugins/copy_vert.exp | Bin 0 -> 583 bytes Plugins/copy_vert.lib | Bin 0 -> 1970 bytes Plugins/copy_vert.obj | Bin 0 -> 816 bytes Plugins/fs2vf.c | 49 + Plugins/fs2vf.dll | Bin 0 -> 36864 bytes Plugins/fs2vf.exp | Bin 0 -> 575 bytes Plugins/fs2vf.lib | Bin 0 -> 1932 bytes Plugins/fs2vf.obj | Bin 0 -> 1894 bytes Plugins/gol.c | 89 + Plugins/gol.dll | Bin 0 -> 28672 bytes Plugins/gol.exp | Bin 0 -> 567 bytes Plugins/gol.lib | Bin 0 -> 1908 bytes Plugins/gol.obj | Bin 0 -> 1878 bytes Plugins/green.cpp | 14 + Plugins/green.dll | Bin 0 -> 28672 bytes Plugins/green.exp | Bin 0 -> 619 bytes Plugins/green.lib | Bin 0 -> 2042 bytes Plugins/green.obj | Bin 0 -> 849 bytes Plugins/hist.cpp | 54 + Plugins/hist.dll | Bin 0 -> 45056 bytes Plugins/hist.exp | Bin 0 -> 614 bytes Plugins/hist.lib | Bin 0 -> 2032 bytes Plugins/hist.obj | Bin 0 -> 1986 bytes Plugins/makefile | 82 + Plugins/makesliders.c | 40 + Plugins/makesliders.dll | Bin 0 -> 36864 bytes Plugins/makesliders.exp | Bin 0 -> 599 bytes Plugins/makesliders.lib | Bin 0 -> 2004 bytes Plugins/makesliders.obj | Bin 0 -> 940 bytes Plugins/ms.dll | Bin 0 -> 36864 bytes Plugins/noize.c | 21 + Plugins/noize.dll | Bin 0 -> 36864 bytes Plugins/noize.exp | Bin 0 -> 700 bytes Plugins/noize.lib | Bin 0 -> 2120 bytes Plugins/noize.obj | Bin 0 -> 865 bytes Plugins/pixels.h | 117 ++ Plugins/plot.cpp | 25 + Plugins/plot.dll | Bin 0 -> 28672 bytes Plugins/plot.exp | Bin 0 -> 614 bytes Plugins/plot.lib | Bin 0 -> 2032 bytes Plugins/plot.obj | Bin 0 -> 1011 bytes Plugins/plugin.h | 119 ++ Plugins/rgb.c | 62 + Plugins/rgb.dll | Bin 0 -> 36864 bytes Plugins/rgb.exp | Bin 0 -> 567 bytes Plugins/rgb.lib | Bin 0 -> 1908 bytes Plugins/rgb.obj | Bin 0 -> 1180 bytes Plugins/rgbcopy.cpp | 28 + Plugins/rgbcopy.dll | Bin 0 -> 28672 bytes Plugins/rgbcopy.exp | Bin 0 -> 621 bytes Plugins/rgbcopy.lib | Bin 0 -> 2062 bytes Plugins/rgbcopy.obj | Bin 0 -> 1884 bytes Plugins/setbits.c | 11 + Plugins/setbits.dll | Bin 0 -> 28672 bytes Plugins/setbits.exp | Bin 0 -> 583 bytes Plugins/setbits.lib | Bin 0 -> 1956 bytes Plugins/setbits.obj | Bin 0 -> 514 bytes Plugins/sharemem.h | 61 + Plugins/shuffle.c | 42 + Plugins/shuffle.dll | Bin 0 -> 28672 bytes Plugins/shuffle.exp | Bin 0 -> 583 bytes Plugins/shuffle.lib | Bin 0 -> 1956 bytes Plugins/shuffle.obj | Bin 0 -> 1020 bytes Plugins/sonogram.cpp | 82 + Plugins/sonogram.dll | Bin 0 -> 45056 bytes Plugins/sonogram.exp | Bin 0 -> 630 bytes Plugins/sonogram.lib | Bin 0 -> 2080 bytes Plugins/sonogram.obj | Bin 0 -> 2306 bytes Plugins/subtract.cpp | 38 + Plugins/subtract.dll | Bin 0 -> 28672 bytes Plugins/subtract.exp | Bin 0 -> 630 bytes Plugins/subtract.lib | Bin 0 -> 2080 bytes Plugins/subtract.obj | Bin 0 -> 1409 bytes Plugins/swap.cpp | 62 + Plugins/swap.dll | Bin 0 -> 36864 bytes Plugins/swap.exp | Bin 0 -> 608 bytes Plugins/swap.lib | Bin 0 -> 2026 bytes Plugins/swap.obj | Bin 0 -> 1893 bytes Plugins/tile.cpp | 59 + Plugins/tile.dll | Bin 0 -> 28672 bytes Plugins/tile.exp | Bin 0 -> 608 bytes Plugins/tile.lib | Bin 0 -> 2026 bytes Plugins/tile.obj | Bin 0 -> 1312 bytes Plugins/vf2fs.c | 49 + Plugins/vf2fs.dll | Bin 0 -> 36864 bytes Plugins/vf2fs.exp | Bin 0 -> 575 bytes Plugins/vf2fs.lib | Bin 0 -> 1932 bytes Plugins/vf2fs.obj | Bin 0 -> 1894 bytes Plugins/xbend.c | 99 + Plugins/xbend.dll | Bin 0 -> 36864 bytes Plugins/xbend.exp | Bin 0 -> 700 bytes Plugins/xbend.lib | Bin 0 -> 2120 bytes Plugins/xbend.obj | Bin 0 -> 1832 bytes Plugins/xshred.c | 20 + Plugins/xshred.dll | Bin 0 -> 28672 bytes Plugins/xshred.exp | Bin 0 -> 570 bytes Plugins/xshred.lib | Bin 0 -> 1936 bytes Plugins/xshred.obj | Bin 0 -> 640 bytes README.txt | 75 + Reija/01.jpg | Bin 0 -> 37151 bytes Reija/02.jpg | Bin 0 -> 24320 bytes Reija/03.jpg | Bin 0 -> 30982 bytes Reija/04.jpg | Bin 0 -> 31003 bytes Reija/05.jpg | Bin 0 -> 26077 bytes Reija/06.jpg | Bin 0 -> 37365 bytes Reija/07.jpg | Bin 0 -> 35830 bytes Reija/08.jpg | Bin 0 -> 36637 bytes Source/Filez.pas | 87 + Source/Framestein.cfg | 39 + Source/Framestein.dof | 91 + Source/Framestein.dpr | 46 + Source/Framestein.dsk | 222 ++ Source/Framestein.res | Bin 0 -> 4056 bytes Source/FsAviWriter.pas | 888 ++++++++ Source/GPL.txt | 340 +++ Source/README.txt | 36 + Source/Strz.pas | 182 ++ Source/configureunit.dfm | 157 ++ Source/configureunit.pas | 120 ++ Source/dc.inc | 42 + Source/effectsunit.pas | 109 + Source/fsDcAvi.pas | 1615 +++++++++++++++ Source/fsaviunit.dfm | 23 + Source/fsaviunit.pas | 103 + Source/fsbrowserunit.dfm | 35 + Source/fsbrowserunit.pas | 113 + Source/fscopyunit.dfm | 26 + Source/fscopyunit.pas | 349 ++++ Source/fsdrawunit.dfm | 17 + Source/fsdrawunit.pas | 101 + Source/fsformunit.pas | 18 + Source/fsframeunit.dfm | 146 ++ Source/fsframeunit.pas | 1098 ++++++++++ Source/fsinfounit.dfm | 16 + Source/fsinfounit.pas | 53 + Source/fsspeedbutton.pas | 48 + Source/fstextunit.dfm | 18 + Source/fstextunit.pas | 148 ++ Source/logunit.dfm | 100 + Source/logunit.pas | 60 + Source/mainunit.dfm | 3547 ++++++++++++++++++++++++++++++++ Source/mainunit.pas | 903 ++++++++ Source/pluginunit.pas | 227 ++ Source/pshostunit.pas | 145 ++ extract.wav | Bin 0 -> 229580 bytes head.avi | Bin 0 -> 82944 bytes ijl15.dll | Bin 0 -> 372736 bytes 289 files changed, 16850 insertions(+) create mode 100644 CHANGELOG.txt create mode 100644 Filters/BossTota.8bf create mode 100644 Filters/BubbSpac.8bf create mode 100644 Filters/ChloeMag.8bf create mode 100644 Filters/ColSteps.8bf create mode 100644 Filters/README.txt create mode 100755 Framestein.exe create mode 100644 HARMON.jpg create mode 100644 Patches/00 example-basics.pd create mode 100644 Patches/01 example-video.pd create mode 100644 Patches/02 example-docking.pd create mode 100644 Patches/03 example-docking2.pd create mode 100644 Patches/04 example-draganddrop.pd create mode 100644 Patches/05 example-plugins.pd create mode 100644 Patches/06 example-photoshopfilters.pd create mode 100644 Patches/07 example-blending.pd create mode 100644 Patches/08 example-masking.pd create mode 100644 Patches/09 example-sonogram.pd create mode 100644 Patches/10 example-waveformdisplay.pd create mode 100644 Patches/11 example-browser.pd create mode 100644 Patches/12 example-network.pd create mode 100644 Patches/13 example-avioutput.pd create mode 100644 Patches/14 example-hist.pd create mode 100644 Patches/15 example-searchpath.pd create mode 100644 Patches/README.txt create mode 100644 Patches/arraysize.c create mode 100644 Patches/arraysize.dll create mode 100644 Patches/arraysize.exp create mode 100644 Patches/arraysize.lib create mode 100644 Patches/arraysize.obj create mode 100644 Patches/bangx.pd create mode 100644 Patches/buildstr.c create mode 100644 Patches/buildstr.dll create mode 100644 Patches/buildstr.exp create mode 100644 Patches/buildstr.lib create mode 100644 Patches/buildstr.obj create mode 100644 Patches/count.pd create mode 100644 Patches/displaydepth.h create mode 100644 Patches/dllcall.h create mode 100644 Patches/externals-documentation.pd create mode 100644 Patches/fps.pd create mode 100644 Patches/fs.avi.pd create mode 100644 Patches/fs.blend.pd create mode 100644 Patches/fs.browser.pd create mode 100644 Patches/fs.copy.pd create mode 100644 Patches/fs.draw.pd create mode 100644 Patches/fs.event.pd create mode 100644 Patches/fs.film.pd create mode 100644 Patches/fs.frame.pd create mode 100644 Patches/fs.framed.pd create mode 100644 Patches/fs.fx.pd create mode 100644 Patches/fs.hist.pd create mode 100644 Patches/fs.info.pd create mode 100644 Patches/fs.main.pd create mode 100644 Patches/fs.mask.pd create mode 100644 Patches/fs.rgb.pd create mode 100644 Patches/fs.sonogram.pd create mode 100644 Patches/fs.text.pd create mode 100644 Patches/fs.waveform.pd create mode 100644 Patches/fs.waveselection.pd create mode 100644 Patches/fs_sender.pd create mode 100644 Patches/init.pd create mode 100644 Patches/l2s.c create mode 100644 Patches/l2s.dll create mode 100644 Patches/l2s.exp create mode 100644 Patches/l2s.lib create mode 100644 Patches/l2s.obj create mode 100644 Patches/makefile create mode 100644 Patches/noize.dll create mode 100644 Patches/ooo.pd create mode 100644 Patches/play.pd create mode 100644 Patches/ramp.pd create mode 100644 Patches/randombox.pd create mode 100644 Patches/reset.pd create mode 100644 Patches/sameonce.pd create mode 100644 Patches/snapOut~.pd create mode 100644 Patches/vcolor~.c create mode 100644 Patches/vcolor~.dll create mode 100644 Patches/vcolor~.exp create mode 100644 Patches/vcolor~.lib create mode 100644 Patches/vcolor~.obj create mode 100644 Patches/vcopy.pd create mode 100644 Patches/vdrawarray.c create mode 100644 Patches/vdrawarray.dll create mode 100644 Patches/vdrawarray.exp create mode 100644 Patches/vdrawarray.lib create mode 100644 Patches/vdrawarray.obj create mode 100644 Patches/vframe.c create mode 100644 Patches/vframe.dll create mode 100644 Patches/vframe.exp create mode 100644 Patches/vframe.h create mode 100644 Patches/vframe.lib create mode 100644 Patches/vframe.obj create mode 100644 Patches/vframeread~.c create mode 100644 Patches/vframeread~.dll create mode 100644 Patches/vframeread~.exp create mode 100644 Patches/vframeread~.lib create mode 100644 Patches/vframeread~.obj create mode 100644 Patches/videoscrub.pd create mode 100644 Patches/vimport.pd create mode 100644 Patches/vplugin.pd create mode 100644 Patches/vref.pd create mode 100644 Patches/vrgb~.c create mode 100644 Patches/vrgb~.dll create mode 100644 Patches/vrgb~.exp create mode 100644 Patches/vrgb~.lib create mode 100644 Patches/vrgb~.obj create mode 100644 Patches/vsig~.c create mode 100644 Patches/vsig~.dll create mode 100644 Patches/vsig~.exp create mode 100644 Patches/vsig~.lib create mode 100644 Patches/vsig~.obj create mode 100644 Patches/vsnapshot~.c create mode 100644 Patches/vsnapshot~.dll create mode 100644 Patches/vsnapshot~.exp create mode 100644 Patches/vsnapshot~.lib create mode 100644 Patches/vsnapshot~.obj create mode 100644 Patches/vsnap~.pd create mode 100644 PeRColate Framestein.pdf create mode 100644 Plugins/2colors.cpp create mode 100644 Plugins/2colors.dll create mode 100644 Plugins/2colors.exp create mode 100644 Plugins/2colors.lib create mode 100644 Plugins/2colors.obj create mode 100644 Plugins/README.txt create mode 100644 Plugins/bend.c create mode 100644 Plugins/bend.dll create mode 100644 Plugins/bend.exp create mode 100644 Plugins/bend.lib create mode 100644 Plugins/bend.obj create mode 100644 Plugins/black.c create mode 100644 Plugins/black.dll create mode 100644 Plugins/black.exp create mode 100644 Plugins/black.lib create mode 100644 Plugins/black.obj create mode 100644 Plugins/colortv.c create mode 100644 Plugins/colortv.dll create mode 100644 Plugins/colortv.exp create mode 100644 Plugins/colortv.lib create mode 100644 Plugins/colortv.obj create mode 100644 Plugins/copy_vert.c create mode 100644 Plugins/copy_vert.dll create mode 100644 Plugins/copy_vert.exp create mode 100644 Plugins/copy_vert.lib create mode 100644 Plugins/copy_vert.obj create mode 100644 Plugins/fs2vf.c create mode 100644 Plugins/fs2vf.dll create mode 100644 Plugins/fs2vf.exp create mode 100644 Plugins/fs2vf.lib create mode 100644 Plugins/fs2vf.obj create mode 100644 Plugins/gol.c create mode 100644 Plugins/gol.dll create mode 100644 Plugins/gol.exp create mode 100644 Plugins/gol.lib create mode 100644 Plugins/gol.obj create mode 100644 Plugins/green.cpp create mode 100644 Plugins/green.dll create mode 100644 Plugins/green.exp create mode 100644 Plugins/green.lib create mode 100644 Plugins/green.obj create mode 100644 Plugins/hist.cpp create mode 100644 Plugins/hist.dll create mode 100644 Plugins/hist.exp create mode 100644 Plugins/hist.lib create mode 100644 Plugins/hist.obj create mode 100644 Plugins/makefile create mode 100644 Plugins/makesliders.c create mode 100644 Plugins/makesliders.dll create mode 100644 Plugins/makesliders.exp create mode 100644 Plugins/makesliders.lib create mode 100644 Plugins/makesliders.obj create mode 100644 Plugins/ms.dll create mode 100644 Plugins/noize.c create mode 100644 Plugins/noize.dll create mode 100644 Plugins/noize.exp create mode 100644 Plugins/noize.lib create mode 100644 Plugins/noize.obj create mode 100644 Plugins/pixels.h create mode 100644 Plugins/plot.cpp create mode 100644 Plugins/plot.dll create mode 100644 Plugins/plot.exp create mode 100644 Plugins/plot.lib create mode 100644 Plugins/plot.obj create mode 100644 Plugins/plugin.h create mode 100644 Plugins/rgb.c create mode 100644 Plugins/rgb.dll create mode 100644 Plugins/rgb.exp create mode 100644 Plugins/rgb.lib create mode 100644 Plugins/rgb.obj create mode 100644 Plugins/rgbcopy.cpp create mode 100644 Plugins/rgbcopy.dll create mode 100644 Plugins/rgbcopy.exp create mode 100644 Plugins/rgbcopy.lib create mode 100644 Plugins/rgbcopy.obj create mode 100644 Plugins/setbits.c create mode 100644 Plugins/setbits.dll create mode 100644 Plugins/setbits.exp create mode 100644 Plugins/setbits.lib create mode 100644 Plugins/setbits.obj create mode 100644 Plugins/sharemem.h create mode 100644 Plugins/shuffle.c create mode 100644 Plugins/shuffle.dll create mode 100644 Plugins/shuffle.exp create mode 100644 Plugins/shuffle.lib create mode 100644 Plugins/shuffle.obj create mode 100644 Plugins/sonogram.cpp create mode 100644 Plugins/sonogram.dll create mode 100644 Plugins/sonogram.exp create mode 100644 Plugins/sonogram.lib create mode 100644 Plugins/sonogram.obj create mode 100644 Plugins/subtract.cpp create mode 100644 Plugins/subtract.dll create mode 100644 Plugins/subtract.exp create mode 100644 Plugins/subtract.lib create mode 100644 Plugins/subtract.obj create mode 100644 Plugins/swap.cpp create mode 100644 Plugins/swap.dll create mode 100644 Plugins/swap.exp create mode 100644 Plugins/swap.lib create mode 100644 Plugins/swap.obj create mode 100644 Plugins/tile.cpp create mode 100644 Plugins/tile.dll create mode 100644 Plugins/tile.exp create mode 100644 Plugins/tile.lib create mode 100644 Plugins/tile.obj create mode 100644 Plugins/vf2fs.c create mode 100644 Plugins/vf2fs.dll create mode 100644 Plugins/vf2fs.exp create mode 100644 Plugins/vf2fs.lib create mode 100644 Plugins/vf2fs.obj create mode 100644 Plugins/xbend.c create mode 100644 Plugins/xbend.dll create mode 100644 Plugins/xbend.exp create mode 100644 Plugins/xbend.lib create mode 100644 Plugins/xbend.obj create mode 100644 Plugins/xshred.c create mode 100644 Plugins/xshred.dll create mode 100644 Plugins/xshred.exp create mode 100644 Plugins/xshred.lib create mode 100644 Plugins/xshred.obj create mode 100644 README.txt create mode 100644 Reija/01.jpg create mode 100644 Reija/02.jpg create mode 100644 Reija/03.jpg create mode 100644 Reija/04.jpg create mode 100644 Reija/05.jpg create mode 100644 Reija/06.jpg create mode 100644 Reija/07.jpg create mode 100644 Reija/08.jpg create mode 100644 Source/Filez.pas create mode 100644 Source/Framestein.cfg create mode 100644 Source/Framestein.dof create mode 100644 Source/Framestein.dpr create mode 100644 Source/Framestein.dsk create mode 100644 Source/Framestein.res create mode 100644 Source/FsAviWriter.pas create mode 100644 Source/GPL.txt create mode 100644 Source/README.txt create mode 100644 Source/Strz.pas create mode 100644 Source/configureunit.dfm create mode 100644 Source/configureunit.pas create mode 100644 Source/dc.inc create mode 100644 Source/effectsunit.pas create mode 100644 Source/fsDcAvi.pas create mode 100644 Source/fsaviunit.dfm create mode 100644 Source/fsaviunit.pas create mode 100644 Source/fsbrowserunit.dfm create mode 100644 Source/fsbrowserunit.pas create mode 100644 Source/fscopyunit.dfm create mode 100644 Source/fscopyunit.pas create mode 100644 Source/fsdrawunit.dfm create mode 100644 Source/fsdrawunit.pas create mode 100644 Source/fsformunit.pas create mode 100644 Source/fsframeunit.dfm create mode 100644 Source/fsframeunit.pas create mode 100644 Source/fsinfounit.dfm create mode 100644 Source/fsinfounit.pas create mode 100644 Source/fsspeedbutton.pas create mode 100644 Source/fstextunit.dfm create mode 100644 Source/fstextunit.pas create mode 100644 Source/logunit.dfm create mode 100644 Source/logunit.pas create mode 100644 Source/mainunit.dfm create mode 100644 Source/mainunit.pas create mode 100644 Source/pluginunit.pas create mode 100644 Source/pshostunit.pas create mode 100644 extract.wav create mode 100644 head.avi create mode 100644 ijl15.dll diff --git a/CHANGELOG.txt b/CHANGELOG.txt new file mode 100644 index 0000000..426adc3 --- /dev/null +++ b/CHANGELOG.txt @@ -0,0 +1,130 @@ +0.30 +- vframe supports plugin parameters +- doubleclicking the framestein-logo equals "reset" +- fs.frame "stayontop" OFF by default +- got rid of the console, "Show debug" in menu instead (right-click the framestein-logo) +- l2s from zexy included in Patches-dir, zexy no longer needed +- disconnecting pd from fs will cause a reset + +0.29 +- example-basics.pd is really just the basics now +- fs.event.pd: get more events from fs.frame (mousedown, mouseup, dropped filename) +- fs.waveform.pd: array display with selection capabilities, see example-waveformdisplay.pd +- new external vdrawarray for the previous: draw array contents on vframe +- the really cool fs.mask.pd and example-masking.pd +- the really cool fs.blend.pd and example-blending.pd +- fs.frame button widget. try "button " + (no more widgets are planned) +- dragging fs.frame with down moves window, ignoring mousetrack_1 +- fs.sonogram made compatible with latest pd test-version +- cleaned up some examples.. + +0.28 +- finally, the ability to write AVIs! see example-avioutput.pd +- added searchpath, see example-searchpath.pd + + new in fs.frame: + +- "use " - like buffer, but no buffering (load on demand) +- new popupmenu commands: save image as, undock +- mousewheel functions as zoom (shift down to preserve aspect ratio) +- fix: borders/stayontop discarded the image +- dock string matching is now substring + +0.27 +- runs Adobe Photoshop Filter Plugins, see example-photoshopfilters.pd +- hide/show messed fs.frame positions +- vsnap~, wrapper for vsnapshot~ + +0.26 +- no more typing docked window positions! see example-docking2.pd +- easy loading of images from fs.frame popup-menu +- new fs.frame commands: minimize, maximize, bringtofront, hidecursor_1, bufferize (copy to image buffer) +- dock main window to pd on connect (out of the way) +- init.pd to load patches correctly + +0.25 +- vframeread~: read image with a control-signal +- vcolor~, merge r g and b channels (must be used with vrgb~) + +0.24 +- externals: vframe, vsig~, vsnapshot~, vrgb~, ... + in short, the ability to convert video to signal and back, + and run framestein plugins in pd. + see Patches\externals-documentation.pd + +0.23 +- fs.film +- fs.hist and example-hist.pd +- fs.sonogram and example-sonogram.pd +- mouserect_1 will report rectangle "drawn" in frame (mousetrack_1 must be on) + +0.22 +- add: drag and drop images/video to fs.frame +- add: videoscrub.pd + +0.21 +- add: dock frames to pd patches, see example-docking.pd +- add: fs.info, get information of images (width, height and framecount) +- add: fs.rgb, get rgb information of pixel at x, y +- add: fs.frame reports mouse x and y thru second outlet +- add: easy moving of frames (drag the window when mousetrack is off) +- improved fs.browser, see example-browser.pd + +0.20 +- add: send_auto to automate sending frames thru network. works like send but + keeps sending frames on each flip until you give it send_manual +- add: BETA of fs.browser, see example-browser.pd +- fix: execution order of events was reversed. what was i thinking? +- fix: most plugins now work on displays other than 16 bits +- more meaningless plugins: copy_vert + +0.19 +- major fix: bigger patches were not initialized correctly +- new plugins: rgbcopy +- fix: colors to fs.draw and fs.text are now given in r g b, + instead of impossible one number +- fix: more intelligent default positioning of fs.frames +- fix: banging fs.main's reset-inlet resets framestein before recreating fs.*-objects +- add: play.pd, really just |inlet|-|fps $1|-|next|-|outlet|, but i do that a lot + +0.18 +- add: sending frames thru network jpeg-compressed, see example-network.pd +- add: some plugins, notably xbend, bend, shuffle, tile +- add: pixels-class for easy iteration thru pixels in c++, see pixels.h and green.cpp +- fix: finally fixed the annoying "asynchronous socket error" when exiting pd before fs + +0.17 +- add: plugins, write effects with C without recompiling Framestein +- add: plugins colortv, noize and subtract + +0.16 +- add: effectsunit.pas shows how easy it is to add pixel level routines +- fix: alpha, sub and add modes of fs.copy had fixed values :( +- add: blend mode to fs.copy, same as alpha but i'm trying to make it faster +- add: some raster operations for fs.copy, see fs.copy.pd for info +- add: fs.draw for drawing boxes, lines and pixels +- add: some implementation on fs.text +- fix: access violation when closing a frame under copy operations +- loading video no longer sets display to 1:1 + +0.15 +- add: fs.frame accepts "SAVE <"BMP" or number for jpeg quality>" +- add: framestein-link.pd and framestein-demo.pd + +0.14 +- fix: occasional access violation with "SEEK" +- default copymodes are now "source_all" and "dest_all" +- add: "reset" inlet to fs.main + +0.13 +- add: "Reset" to main popup-menu (right-click the logo) +- "prev" for previous frame/buffered image +- "seek 0.5*" will seek to middle of video/buffered images +- updated documentation in fs.frame.pd + +0.12 +With source under GPL. + +0.1 +Initial version. diff --git a/Filters/BossTota.8bf b/Filters/BossTota.8bf new file mode 100644 index 0000000..9d1845a Binary files /dev/null and b/Filters/BossTota.8bf differ diff --git a/Filters/BubbSpac.8bf b/Filters/BubbSpac.8bf new file mode 100644 index 0000000..f2d39f8 Binary files /dev/null and b/Filters/BubbSpac.8bf differ diff --git a/Filters/ChloeMag.8bf b/Filters/ChloeMag.8bf new file mode 100644 index 0000000..4c4c056 Binary files /dev/null and b/Filters/ChloeMag.8bf differ diff --git a/Filters/ColSteps.8bf b/Filters/ColSteps.8bf new file mode 100644 index 0000000..3354df5 Binary files /dev/null and b/Filters/ColSteps.8bf differ diff --git a/Filters/README.txt b/Filters/README.txt new file mode 100644 index 0000000..104d1b0 --- /dev/null +++ b/Filters/README.txt @@ -0,0 +1,9 @@ +Framestein will look for filters in this directory in 8BF-format. + +The example filters are (C) Andrew Buckle and were downloaded from +http://showcase.netins.net/web/wolf359/plugins.htm. + +There are more than a thousand more available on that page. + +A good program to convert various formats to 8BF is Plugin Commander Light, +available from http://thepluginsite.com/products/picopro/index.htm. diff --git a/Framestein.exe b/Framestein.exe new file mode 100755 index 0000000..4879d1f Binary files /dev/null and b/Framestein.exe differ diff --git a/HARMON.jpg b/HARMON.jpg new file mode 100644 index 0000000..b84472c Binary files /dev/null and b/HARMON.jpg differ diff --git a/Patches/00 example-basics.pd b/Patches/00 example-basics.pd new file mode 100644 index 0000000..ca9ab3f --- /dev/null +++ b/Patches/00 example-basics.pd @@ -0,0 +1,38 @@ +#N canvas 228 3 648 661 12; +#X obj 5 31 fs.main; +#X msg 5 7 6001; +#X msg 56 7 reset; +#X text 32 103 fs.main connects pure data and Framestein. Only one +at a time!; +#X text 33 143 1st inlet: re-establish connection to given port number +; +#X text 33 159 2nd inlet: "reset" will re-create all fs.*-objects; +#X obj 36 206 fs.frame; +#X text 119 206 -- load images and video \, perform effects \, run +plugins \, photoshop-filters \, and more ...; +#X text 120 273 some commands are listed here; +#X obj 358 273 fs.fx; +#X text 120 304 1st outlet: fs.frame ID. Connect this to other fs.*-objects +\, like fs.copy \, fs.info \, fs.event etc.; +#X text 120 344 2nd outlet: reports mouse movement in the frame when +mousetrack_1 is set. See example-docking.pd!; +#X text 119 384 3rd outlet: report the window position when docked +\, see example-docking2.pd!; +#X obj 45 442 fs.copy; +#X text 121 442 -- connect two fs.frames to copy pixels by built-in +copy operations \, plugins or photoshop-filters.; +#X text 122 486 1st inlet: connect the first outlet of fs.frame here. +; +#X text 122 505 2nd inlet: name of the copy operation \, or other parameter. +See inside fs.copy for list of built-ins. See example-plugins.pd and +example-photoshopfilters.pd.; +#X text 123 557 1st outlet: connect to the fs.frame to copy to.; +#X text 31 70 The central objects to get started with:; +#X text 49 602 Have fun!; +#X text 119 253 1st inlet: for a list of commands \, look inside the +patch.; +#X obj 344 320 fs.info; +#X obj 416 320 fs.event; +#X connect 1 0 0 0; +#X connect 1 0 2 0; +#X connect 2 0 0 1; diff --git a/Patches/01 example-video.pd b/Patches/01 example-video.pd new file mode 100644 index 0000000..3624331 --- /dev/null +++ b/Patches/01 example-video.pd @@ -0,0 +1,30 @@ +#N canvas 243 28 638 555 12; +#X obj 7 34 fs.main; +#X msg 7 8 6001; +#X msg 46 8 reset; +#X obj 300 209 fs.framed video; +#X msg 424 209 82 + 128; +#X text 41 64 drag & drop your favorite .avi here; +#X obj 442 185 init; +#X obj 303 121 hsl 256 15 0 1 0 0 empty empty empty 20 8 0 8 -262144 +-1 -1 9200 1; +#X obj 300 272 fs.copy; +#X msg 300 146 seek \$1* \, bang; +#X obj 300 348 fs.framed video; +#X msg 424 348 82 + 330; +#X msg 392 271 source_random \, dest_random; +#X text 314 299 Look inside fs.copy for more commands.; +#X connect 1 0 0 0; +#X connect 1 0 2 0; +#X connect 2 0 0 1; +#X connect 3 0 8 0; +#X connect 3 2 4 0; +#X connect 4 0 3 0; +#X connect 6 0 4 0; +#X connect 6 0 11 0; +#X connect 7 0 9 0; +#X connect 8 0 10 0; +#X connect 9 0 3 0; +#X connect 10 2 11 0; +#X connect 11 0 10 0; +#X connect 12 0 8 1; diff --git a/Patches/02 example-docking.pd b/Patches/02 example-docking.pd new file mode 100644 index 0000000..bf29cc8 --- /dev/null +++ b/Patches/02 example-docking.pd @@ -0,0 +1,88 @@ +#N canvas 385 33 594 516 12; +#X obj 13 33 fs.main; +#X obj 250 231 fs.framed example-docking 27+117; +#X msg 13 6 6001; +#X msg 64 5 reset; +#X floatatom 211 414 4 0 0; +#X floatatom 251 414 4 0 0; +#X floatatom 292 414 4 0 0; +#X obj 211 382 unpack f f f; +#X obj 386 367 fs.info; +#X floatatom 386 402 4 0 0; +#X floatatom 428 402 4 0 0; +#X floatatom 471 402 4 0 0; +#X obj 385 292 unpack f f; +#X floatatom 385 320 4 0 0; +#X floatatom 460 319 4 0 0; +#X msg 233 192 bang; +#X text 87 442 scrub the pict with mouse to get r g b values; +#X text 386 266 mouse x and y; +#X msg 268 322 bang; +#X obj 211 350 fs.rgb; +#N canvas 0 0 296 396 beeper 0; +#X obj 90 56 inlet; +#X obj 91 92 unpack f f f; +#X obj 171 130 *; +#X obj 123 252 osc~; +#X obj 155 170 / 256; +#X obj 86 132 / 256; +#X obj 123 203 *; +#X obj 125 323 dac~; +#X obj 127 284 *~ 0.1; +#X obj 85 161 * 20000; +#X obj 196 243 / 256; +#X obj 200 332 * 0.1; +#X connect 0 0 1 0; +#X connect 1 0 5 0; +#X connect 1 0 10 0; +#X connect 1 1 2 0; +#X connect 1 2 2 1; +#X connect 2 0 4 0; +#X connect 3 0 8 0; +#X connect 4 0 6 0; +#X connect 5 0 9 0; +#X connect 6 0 3 0; +#X connect 8 0 7 0; +#X connect 8 0 7 1; +#X connect 9 0 6 1; +#X connect 10 0 11 0; +#X connect 11 0 8 1; +#X restore 124 398 pd beeper; +#X msg 43 362 \; pd dsp 1; +#X msg 43 402 \; pd dsp 0; +#X msg 284 193 mousetrack_1; +#X obj 297 256 videoscrub; +#X text 264 77 or drop a videofile to the frame ...; +#X obj 206 51 init; +#X floatatom 513 402 5 0 0; +#X msg 250 51 HARMON.JPG; +#X text 42 336 Play the harmon!; +#X connect 1 0 19 0; +#X connect 1 0 8 0; +#X connect 1 0 24 0; +#X connect 1 1 12 0; +#X connect 1 1 19 1; +#X connect 1 1 18 0; +#X connect 1 1 24 1; +#X connect 2 0 0 0; +#X connect 2 0 3 0; +#X connect 3 0 0 1; +#X connect 7 0 4 0; +#X connect 7 1 5 0; +#X connect 7 2 6 0; +#X connect 8 0 9 0; +#X connect 8 1 10 0; +#X connect 8 2 11 0; +#X connect 8 3 27 0; +#X connect 12 0 13 0; +#X connect 12 1 14 0; +#X connect 15 0 1 0; +#X connect 18 0 19 0; +#X connect 19 0 7 0; +#X connect 19 0 20 0; +#X connect 23 0 1 0; +#X connect 24 0 1 0; +#X connect 26 0 28 0; +#X connect 26 0 15 0; +#X connect 26 0 23 0; +#X connect 28 0 1 0; diff --git a/Patches/03 example-docking2.pd b/Patches/03 example-docking2.pd new file mode 100644 index 0000000..f5687e5 --- /dev/null +++ b/Patches/03 example-docking2.pd @@ -0,0 +1,15 @@ +#N canvas 345 114 641 488 12; +#X obj 11 40 fs.main; +#X msg 11 12 6001; +#X msg 62 12 reset; +#X obj 26 133 fs.framed example-docking2; +#X msg 229 161 365 + 203; +#X obj 240 133 init; +#X text 24 78 Used this way the frame position is saved with the patch +automatically. Try moving the frame around!; +#X connect 1 0 0 0; +#X connect 1 0 2 0; +#X connect 2 0 0 1; +#X connect 3 2 4 0; +#X connect 4 0 3 0; +#X connect 5 0 4 0; diff --git a/Patches/04 example-draganddrop.pd b/Patches/04 example-draganddrop.pd new file mode 100644 index 0000000..2c68f99 --- /dev/null +++ b/Patches/04 example-draganddrop.pd @@ -0,0 +1,25 @@ +#N canvas 323 36 587 428 12; +#X obj 15 37 fs.main; +#X msg 66 12 reset; +#X obj 38 185 fs.framed draganddrop; +#X msg 201 212 352 + 233; +#X obj 38 244 fs.event; +#X msg 50 288 set \$1; +#X obj 92 150 init; +#X obj 48 151 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X text 18 95 Using fs.frame to provide drag & drop:; +#X text 352 180 Drop a file here:; +#X msg 15 12 6001; +#X msg 67 329; +#X connect 1 0 0 1; +#X connect 2 0 4 0; +#X connect 2 2 3 0; +#X connect 3 0 2 0; +#X connect 4 0 5 0; +#X connect 5 0 11 0; +#X connect 6 0 3 0; +#X connect 6 0 2 0; +#X connect 7 0 2 0; +#X connect 10 0 0 0; +#X connect 10 0 1 0; diff --git a/Patches/05 example-plugins.pd b/Patches/05 example-plugins.pd new file mode 100644 index 0000000..f6187a2 --- /dev/null +++ b/Patches/05 example-plugins.pd @@ -0,0 +1,127 @@ +#N canvas 344 18 621 620 12; +#X obj 11 41 fs.main; +#X msg 11 11 6001; +#X msg 62 12 reset; +#X obj 70 216 fs.frame; +#X msg 103 177 noize; +#X text 106 154 send the name of the plugin to fs.frame to execute +; +#X obj 70 466 fs.frame; +#X obj 70 302 fs.copy; +#X msg 141 216 bang; +#X text 161 249 plugins can also be copy operations; +#X msg 153 177 colortv; +#X msg 158 278 colortv; +#X msg 220 177 subtract \$1 \$2 \$3; +#X obj 376 205 pack f f f; +#X floatatom 368 177 4 0 0; +#X floatatom 409 177 4 0 0; +#X floatatom 450 177 4 0 0; +#X msg 460 205 bang; +#X obj 255 355 pack f f; +#X msg 323 355 bang; +#X floatatom 255 331 4 0 0; +#X floatatom 295 331 4 0 0; +#X obj 466 408 int; +#X msg 320 379 \$1 180; +#N canvas 686 105 602 402 funny 0; +#X obj 47 97 random 352; +#X obj 135 97 random 352; +#X obj 73 145 pack f f; +#X obj 80 186 outlet; +#X obj 76 13 inlet; +#X obj 86 56 t b b; +#X connect 0 0 2 0; +#X connect 1 0 2 1; +#X connect 2 0 3 0; +#X connect 4 0 5 0; +#X connect 5 0 0 0; +#X connect 5 1 1 0; +#X restore 255 412 pd funny; +#X msg 324 412 bang; +#X msg 158 331 xbend \$1 \$2; +#N canvas 638 233 375 411 bend 0; +#X obj 18 328 outlet; +#X msg 43 281 bend \$1 \$2 \$3 \$4; +#X obj 55 242 pack f f f f; +#X msg 158 242 bang; +#X floatatom 35 159 4 0 0; +#X floatatom 77 159 4 0 0; +#X floatatom 124 159 4 0 0; +#X floatatom 168 159 4 0 0; +#X msg 200 262 158 161 154 214; +#X text 187 315 oh i'm sorry virve...; +#X msg 209 290 94 95 280 214; +#X msg 187 339 169 144 262 162; +#X text 132 365 but this thing is killing me; +#X text 67 13 bend works in both x and y; +#X connect 1 0 0 0; +#X connect 2 0 1 0; +#X connect 3 0 2 0; +#X connect 4 0 2 0; +#X connect 5 0 2 1; +#X connect 5 0 3 0; +#X connect 6 0 2 2; +#X connect 6 0 3 0; +#X connect 7 0 2 3; +#X connect 7 0 3 0; +#X connect 8 0 1 0; +#X connect 10 0 1 0; +#X connect 11 0 1 0; +#X restore 255 442 pd bend; +#X text 71 503 note: 16 bit display is way faster than 24 or 32 in +my machine \, so i recommend trying out which one performs best.; +#X text 69 555 there are more plugins.. see the Framestein/Plugins-dir. +; +#X msg 70 118 virvezoom.jpg; +#X obj 186 118 init; +#X obj 94 407 init; +#X text 367 412 click here; +#X text 320 442 look here; +#X msg 94 438 291 x 325 \, 0 + 370; +#X obj 466 433 sameonce; +#X obj 466 384 ramp; +#X msg 466 356 220 66 10; +#X msg 466 333 66 220 10; +#X text 467 309 and here ..; +#X text 340 330 try these ..; +#X text 147 42 PLUGINS -- effects and copy operations; +#X connect 1 0 0 0; +#X connect 1 0 2 0; +#X connect 2 0 0 1; +#X connect 3 0 7 0; +#X connect 4 0 3 0; +#X connect 7 0 6 0; +#X connect 8 0 3 0; +#X connect 10 0 3 0; +#X connect 11 0 7 1; +#X connect 11 0 8 0; +#X connect 12 0 3 0; +#X connect 13 0 12 0; +#X connect 14 0 13 0; +#X connect 15 0 13 1; +#X connect 15 0 17 0; +#X connect 16 0 13 2; +#X connect 16 0 17 0; +#X connect 17 0 13 0; +#X connect 18 0 26 0; +#X connect 19 0 18 0; +#X connect 20 0 18 0; +#X connect 21 0 18 1; +#X connect 21 0 19 0; +#X connect 22 0 36 0; +#X connect 23 0 18 0; +#X connect 24 0 26 0; +#X connect 25 0 24 0; +#X connect 26 0 7 1; +#X connect 26 0 8 0; +#X connect 27 0 7 1; +#X connect 27 0 8 0; +#X connect 30 0 3 0; +#X connect 31 0 30 0; +#X connect 32 0 35 0; +#X connect 35 0 6 0; +#X connect 36 0 18 0; +#X connect 37 0 22 0; +#X connect 38 0 37 0; +#X connect 39 0 37 0; diff --git a/Patches/06 example-photoshopfilters.pd b/Patches/06 example-photoshopfilters.pd new file mode 100644 index 0000000..2b7a359 --- /dev/null +++ b/Patches/06 example-photoshopfilters.pd @@ -0,0 +1,105 @@ +#N canvas 221 6 707 598 12; +#X obj 16 54 fs.main; +#X msg 16 27 6001; +#X msg 58 27 reset; +#X obj 460 157 init; +#X msg 434 122 28 + 128; +#X obj 262 398 fs.copy; +#X obj 262 477 fs.framed example-pho; +#X obj 262 122 fs.framed example-pho; +#X msg 434 477 28 + 308; +#X obj 461 447 init; +#X msg 333 252 bosstota; +#X msg 281 157 next \, bang; +#X msg 345 285 bubbspac; +#X msg 357 320 chloemag; +#X msg 370 351 colsteps; +#X text 493 241 without parameters; +#X text 496 266 a dialog will pop; +#N canvas 298 218 624 424 realtime 0; +#X obj 42 347 outlet; +#X floatatom 42 241 5 0 0; +#X floatatom 91 241 5 0 0; +#X floatatom 140 241 5 0 0; +#X floatatom 189 241 5 0 0; +#X floatatom 238 241 5 0 0; +#X floatatom 287 241 5 0 0; +#X floatatom 336 241 5 0 0; +#X floatatom 385 241 5 0 0; +#X obj 88 33 inlet; +#X obj 88 109 fps 0; +#X floatatom 88 79 5 0 0; +#X obj 181 175 random 255; +#X obj 189 199 random 255; +#X obj 267 175 random 255; +#X obj 275 199 random 255; +#X obj 353 175 random 255; +#X obj 361 199 random 255; +#X obj 94 175 random 255; +#X obj 102 199 random 255; +#X obj 42 282 pack f f f f f f f f; +#X msg 42 318 colsteps \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8; +#X connect 1 0 20 0; +#X connect 2 0 20 1; +#X connect 3 0 20 2; +#X connect 4 0 20 3; +#X connect 5 0 20 4; +#X connect 6 0 20 5; +#X connect 7 0 20 6; +#X connect 8 0 20 7; +#X connect 9 0 11 0; +#X connect 10 0 12 0; +#X connect 10 0 13 0; +#X connect 10 0 14 0; +#X connect 10 0 15 0; +#X connect 10 0 16 0; +#X connect 10 0 17 0; +#X connect 10 0 18 0; +#X connect 10 0 19 0; +#X connect 11 0 10 0; +#X connect 12 0 3 0; +#X connect 13 0 4 0; +#X connect 14 0 5 0; +#X connect 15 0 6 0; +#X connect 16 0 7 0; +#X connect 17 0 8 0; +#X connect 18 0 1 0; +#X connect 19 0 2 0; +#X connect 20 0 21 0; +#X connect 21 0 0 0; +#X restore 520 391 pd realtime; +#X text 472 336 this is the real-time way; +#X floatatom 520 365 5 0 0; +#X msg 572 365 2; +#X obj 520 421 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X text 266 535 the example-filters are (C) Andrew Buckle.; +#X text 266 555 see Filters/README.TXT for more info.; +#X msg 262 62 head.avi; +#X connect 1 0 0 0; +#X connect 1 0 2 0; +#X connect 2 0 0 1; +#X connect 3 0 24 0; +#X connect 3 0 4 0; +#X connect 4 0 7 0; +#X connect 5 0 6 0; +#X connect 6 2 8 0; +#X connect 7 0 5 0; +#X connect 7 2 4 0; +#X connect 8 0 6 0; +#X connect 9 0 8 0; +#X connect 10 0 5 1; +#X connect 10 0 11 0; +#X connect 11 0 7 0; +#X connect 12 0 5 1; +#X connect 12 0 11 0; +#X connect 13 0 5 1; +#X connect 13 0 11 0; +#X connect 14 0 5 1; +#X connect 14 0 11 0; +#X connect 17 0 5 1; +#X connect 17 0 21 0; +#X connect 19 0 17 0; +#X connect 20 0 19 0; +#X connect 21 0 11 0; +#X connect 24 0 7 0; diff --git a/Patches/07 example-blending.pd b/Patches/07 example-blending.pd new file mode 100644 index 0000000..d11e887 --- /dev/null +++ b/Patches/07 example-blending.pd @@ -0,0 +1,57 @@ +#N canvas 5 47 1010 514 10; +#X obj 12 52 fs.main; +#X msg 10 23 6001; +#X msg 56 23 reset; +#X msg 210 190 597 + 108; +#X msg 495 188 815 + 109; +#X msg 343 365 696 + 342; +#X floatatom 227 272 4 0 0; +#X obj 150 273 fs.blend; +#X obj 235 38 fps 0; +#X floatatom 193 38 4 0 0; +#X msg 286 96 next \, bang; +#X msg 207 94 next \, bang; +#X obj 220 167 init; +#X obj 503 163 init; +#X obj 353 335 init; +#X text 166 419 note: fs.blend initializes this frame to flip_manual. +; +#X text 174 441 in manual mode \, you need to send "flip" to update +the display after changing the image. the default mode is "flip_auto". +; +#X text 239 246 blend amount \, 0 - 255; +#X text 682 44 drag and drop your videos here; +#X text 748 291 the result; +#X msg 299 290 127; +#X obj 236 65 t b b; +#X text 196 14 frame rate. start with something modest \, like 1; +#X obj 731 257 hsl 128 15 255 0 0 0 empty empty empty -2 -6 0 8 -262144 +-1 -1 0 1; +#X obj 21 189 fs.framed blending; +#X obj 306 187 fs.framed blending; +#X obj 150 363 fs.framed blending; +#X connect 1 0 0 0; +#X connect 1 0 2 0; +#X connect 2 0 0 1; +#X connect 3 0 24 0; +#X connect 4 0 25 0; +#X connect 5 0 26 0; +#X connect 6 0 7 2; +#X connect 7 0 26 0; +#X connect 8 0 21 0; +#X connect 9 0 8 0; +#X connect 10 0 25 0; +#X connect 11 0 24 0; +#X connect 12 0 3 0; +#X connect 13 0 4 0; +#X connect 14 0 5 0; +#X connect 14 0 20 0; +#X connect 20 0 6 0; +#X connect 21 0 11 0; +#X connect 21 1 10 0; +#X connect 23 0 6 0; +#X connect 24 0 7 0; +#X connect 24 2 3 0; +#X connect 25 0 7 1; +#X connect 25 2 4 0; +#X connect 26 2 5 0; diff --git a/Patches/08 example-masking.pd b/Patches/08 example-masking.pd new file mode 100644 index 0000000..8e546a6 --- /dev/null +++ b/Patches/08 example-masking.pd @@ -0,0 +1,66 @@ +#N canvas 50 107 926 549 10; +#X obj 9 33 fs.main; +#X msg 8 8 6001; +#X msg 45 8 reset; +#X msg 115 196 412 + 104; +#X msg 18 122 next \, bang; +#X obj 18 294 fs.mask; +#X msg 248 279 601 + 104; +#X obj 18 99 fps 0; +#X floatatom 18 76 4 0 0; +#X obj 199 332 fs.draw; +#X msg 199 308 rect \$1 \$2 \$3 \$4; +#X msg 211 230 mousetrack_1 \, mouserect_1; +#X msg 219 372 pen 0 0 0 \, brush 0 0 0; +#X obj 130 173 init; +#X msg 219 395 pen 255 255 255 \, brush 255 255 255; +#X obj 18 173 fs.framed masking; +#X obj 151 257 fs.framed masking; +#X obj 18 392 fs.framed masking; +#X obj 130 392 init; +#X obj 259 257 init; +#X obj 235 421 init; +#X text 359 372 click here to draw black to the mask; +#X text 435 394 draw white; +#X text 409 51 1) drag & drop a video here:; +#X text 598 51 2) draw rectanges to this frame:; +#X text 599 262 the result is...; +#X msg 115 417 601 + 313; +#X text 116 47 fs.mask -- copy with mask; +#X text 116 66 1st inlet: fs.frame to copy from; +#X text 116 81 2nd inlet: fs.frame of the mask; +#X text 134 95 outlet: output fs.frame; +#X msg 52 76 2; +#X obj 65 99 init; +#X msg 364 443 invert; +#X text 364 423 try inverting the mask..; +#X connect 1 0 0 0; +#X connect 1 0 2 0; +#X connect 2 0 0 1; +#X connect 3 0 15 0; +#X connect 4 0 15 0; +#X connect 5 0 17 0; +#X connect 6 0 16 0; +#X connect 7 0 4 0; +#X connect 8 0 7 0; +#X connect 9 0 16 0; +#X connect 10 0 9 0; +#X connect 11 0 16 0; +#X connect 12 0 9 0; +#X connect 13 0 3 0; +#X connect 14 0 9 0; +#X connect 15 0 5 0; +#X connect 15 2 3 0; +#X connect 16 0 5 1; +#X connect 16 1 10 0; +#X connect 16 2 6 0; +#X connect 17 2 26 0; +#X connect 18 0 26 0; +#X connect 19 0 6 0; +#X connect 19 0 11 0; +#X connect 19 0 16 0; +#X connect 20 0 14 0; +#X connect 26 0 17 0; +#X connect 31 0 8 0; +#X connect 32 0 31 0; +#X connect 33 0 16 0; diff --git a/Patches/09 example-sonogram.pd b/Patches/09 example-sonogram.pd new file mode 100644 index 0000000..5c99688 --- /dev/null +++ b/Patches/09 example-sonogram.pd @@ -0,0 +1,74 @@ +#N canvas 308 -3 605 676 12; +#X obj 13 40 fs.main; +#X msg 13 13 6001; +#X msg 64 12 reset; +#X obj 330 486 fs.sonogram; +#X msg 488 452 bang; +#X obj 488 419 fps 0; +#X floatatom 488 392 5 0 0; +#X msg 488 364 5; +#N canvas 0 0 608 408 play 0; +#X graph graph2 0 -1 114739 1 70 171 270 31; +#X array music 114740 float 0; +#X pop; +#X msg 341 137 read -resize \$1 music; +#X obj 341 168 soundfiler; +#X obj 333 70 inlet; +#X obj 341 103 symbol; +#X obj 193 242 phasor~ 1; +#X obj 203 290 *~; +#X obj 209 359 outlet~; +#X obj 203 320 tabread4~ music; +#X floatatom 193 213 5 0 0; +#X obj 92 214 osc~ 0.01; +#X obj 92 239 avg~; +#X connect 1 0 2 0; +#X connect 2 0 6 1; +#X connect 3 0 4 0; +#X connect 4 0 1 0; +#X connect 5 0 6 0; +#X connect 6 0 8 0; +#X connect 8 0 7 0; +#X connect 9 0 5 0; +#X connect 10 0 11 0; +#X connect 11 0 9 0; +#X restore 330 349 pd play; +#X msg 248 48 c:/fsrel/framestein/extract.wav; +#X obj 251 480 dac~; +#X msg 364 558 200x128 \, display 200x512; +#X floatatom 355 427 5 0 0; +#X obj 263 450 *~ 0.2; +#X text 348 403 amplify display; +#X obj 295 529 fs.framed example-sonogram 20+120; +#X msg 370 587 setbits 246; +#X msg 358 100 \; pd dsp 1; +#X obj 116 13 loadbang; +#X text 441 110 must be on ..; +#X text 453 332 start drawing; +#X text 242 23 correct path and click ..; +#X text 28 617 NOTE: fs.sonogram writes temporary files to your c:/. +; +#X text 77 636 modify fs.sonogram.pd for a proper temporary path.; +#X obj 330 451 *~ 4; +#X obj 479 592 init; +#X connect 1 0 0 0; +#X connect 1 0 2 0; +#X connect 2 0 0 1; +#X connect 3 0 15 0; +#X connect 4 0 3 1; +#X connect 5 0 4 0; +#X connect 6 0 5 0; +#X connect 7 0 6 0; +#X connect 8 0 13 0; +#X connect 8 0 24 0; +#X connect 9 0 8 0; +#X connect 11 0 15 0; +#X connect 12 0 24 1; +#X connect 13 0 10 0; +#X connect 13 0 10 0; +#X connect 13 0 10 1; +#X connect 16 0 15 0; +#X connect 18 0 2 0; +#X connect 24 0 3 0; +#X connect 25 0 11 0; +#X connect 25 0 16 0; diff --git a/Patches/10 example-waveformdisplay.pd b/Patches/10 example-waveformdisplay.pd new file mode 100644 index 0000000..f44763a --- /dev/null +++ b/Patches/10 example-waveformdisplay.pd @@ -0,0 +1,126 @@ +#N canvas 197 11 743 561 12; +#X obj 5 34 fs.main; +#X msg 5 7 6001; +#X msg 45 7 reset; +#X text 155 394 drag & drop a SOUND FILE to one of the frames above +...; +#X text 234 413 then make a selection with mouse; +#N canvas 0 0 1002 426 implementation 0; +#X obj 26 260 table snd; +#X obj 108 206 fs.event; +#X msg 108 234 read -resize \$1 snd; +#X obj 159 286 soundfiler; +#X obj 125 105 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X obj 206 161 fs.waveform snd 512 256; +#X obj 197 101 fs.waveform snd 512 32; +#X obj 230 134 t b f; +#X floatatom 295 192 8 0 0; +#X floatatom 368 192 8 0 0; +#X text 288 230 selection in samples; +#N canvas 35 295 458 308 init 0; +#X obj 105 91 init; +#X obj 92 209 outlet; +#X obj 145 209 outlet; +#X msg 83 125 dock waveformd \, 118+105 \, bang; +#X msg 74 151 dock waveformd \, 118+138 \, bang; +#X connect 0 0 3 0; +#X connect 0 0 4 0; +#X connect 3 0 2 0; +#X connect 4 0 1 0; +#X restore 146 74 pd init; +#X msg 394 97 118 + 105; +#X msg 406 153 118 + 138; +#X obj 108 260 t b b a; +#X msg 128 286 0; +#X text 499 72 fs.waveform -- array display with range selection; +#X text 513 104 args: ; +#X text 513 130 inlet 1: bang or command to fs.frame; +#X text 513 166 inlet 3: endpoint of display in samples; +#X text 513 148 inlet 2: startpoint of display in samples; +#X text 513 184 inlet 4: display selection in inverse (0 or 1); +#X text 513 217 outlets 1 & 2: first two outlets of the fs.frame inside +; +#X text 513 235 outlets 3 & 4: start and end of selected range in samples +; +#X text 513 254 outlet 5: third outlet of the fs.frame inside; +#N canvas 0 0 481 421 playselection 0; +#X obj 302 117 inlet; +#X obj 348 117 inlet; +#X obj 302 182 -; +#X obj 302 210 abs; +#X obj 94 185 *~; +#X obj 94 214 +~; +#X obj 94 151 phasor~; +#X obj 334 310 /; +#X obj 327 277 samplerate~; +#X obj 302 237 t f b f; +#X obj 94 245 tabread4~ snd; +#X obj 149 283 r vol; +#X obj 94 319 dac~; +#X obj 94 283 *~ 0.1; +#X obj 123 50 inlet; +#X text 74 24 mouseup from fs.event; +#X text 301 94 range; +#X obj 94 127 f; +#X obj 123 185 f; +#X obj 123 214 f; +#X connect 0 0 2 0; +#X connect 0 0 19 1; +#X connect 1 0 2 1; +#X connect 2 0 3 0; +#X connect 3 0 9 0; +#X connect 4 0 5 0; +#X connect 5 0 10 0; +#X connect 6 0 4 0; +#X connect 7 0 17 1; +#X connect 8 0 7 0; +#X connect 9 0 18 1; +#X connect 9 1 8 0; +#X connect 9 2 7 1; +#X connect 10 0 13 0; +#X connect 11 0 13 1; +#X connect 13 0 12 0; +#X connect 13 0 12 1; +#X connect 14 0 17 0; +#X connect 14 0 18 0; +#X connect 14 0 19 0; +#X connect 17 0 6 0; +#X connect 18 0 4 1; +#X connect 19 0 5 1; +#X restore 294 299 pd playselection; +#X text 195 353 Sorry about the mess..; +#X connect 1 0 2 0; +#X connect 1 2 25 0; +#X connect 2 0 14 0; +#X connect 4 0 6 0; +#X connect 5 0 1 0; +#X connect 5 2 8 0; +#X connect 5 2 25 1; +#X connect 5 3 9 0; +#X connect 5 3 25 2; +#X connect 5 4 13 0; +#X connect 6 0 1 0; +#X connect 6 2 7 0; +#X connect 6 3 5 2; +#X connect 6 4 12 0; +#X connect 7 0 5 0; +#X connect 7 1 5 1; +#X connect 11 0 5 0; +#X connect 11 1 6 0; +#X connect 14 0 6 0; +#X connect 14 0 5 0; +#X connect 14 1 15 0; +#X connect 14 2 3 0; +#X connect 15 0 6 1; +#X connect 15 0 6 2; +#X connect 15 0 5 1; +#X connect 15 0 5 2; +#X restore 252 475 pd implementation and docs; +#X obj 32 388 vsl 15 128 0 1 0 0 vol empty volume 0 -8 128 8 -262144 +-1 -1 7800 1; +#X msg 54 497 \; pd dsp 1; +#X text 57 472 play it ...; +#X connect 1 0 0 0; +#X connect 1 0 2 0; +#X connect 2 0 0 1; diff --git a/Patches/11 example-browser.pd b/Patches/11 example-browser.pd new file mode 100644 index 0000000..3e68922 --- /dev/null +++ b/Patches/11 example-browser.pd @@ -0,0 +1,30 @@ +#N canvas 335 300 661 349 12; +#X obj 11 37 fs.main; +#X obj 88 185 fs.browser; +#X msg 11 8 6001; +#X msg 62 8 reset; +#X obj 88 255 fs.frame; +#X msg 88 133 bang; +#X msg 190 82 1000x480; +#X obj 88 221 fs.copy; +#X msg 164 282 xbend 110 120; +#X floatatom 287 273 4 0 0; +#X obj 287 299 bangx; +#X msg 287 247 10; +#X text 54 110 click here; +#X obj 181 15 init; +#X msg 181 122 http://pinktwins.com; +#X connect 1 0 7 0; +#X connect 2 0 0 0; +#X connect 2 0 3 0; +#X connect 3 0 0 1; +#X connect 5 0 1 0; +#X connect 6 0 1 0; +#X connect 7 0 4 0; +#X connect 8 0 4 0; +#X connect 9 0 10 0; +#X connect 10 0 8 0; +#X connect 11 0 9 0; +#X connect 13 0 6 0; +#X connect 13 0 14 0; +#X connect 14 0 1 0; diff --git a/Patches/12 example-network.pd b/Patches/12 example-network.pd new file mode 100644 index 0000000..81490d1 --- /dev/null +++ b/Patches/12 example-network.pd @@ -0,0 +1,62 @@ +#N canvas 242 39 740 613 12; +#X obj 15 44 fs.main; +#X msg 15 14 6001; +#X msg 66 14 reset; +#X obj 108 221 fs.frame; +#X msg 143 113 buffer c:/fsrel/Framestein/Reija; +#X msg 207 179 next; +#X obj 82 520 fs.frame; +#X msg 29 481 receive hello; +#X text 162 511 use "receive " on the receiving end to control +where your frames go.; +#X text 208 234 send ; +#X text 357 142 connect
; +#X text 208 259 use "pure" as jpeg quality to send uncompressed frames. +this will take much more bandwidth but less cpu.; +#X msg 207 209 send hello 33; +#X msg 24 311 disconnect; +#X text 443 328 use send_auto to automate sending (send frame on each +flip); +#X msg 397 303 send_auto hello 33; +#X msg 397 328 next; +#X obj 336 465 fs.copy; +#X msg 347 440 bang; +#X msg 398 378 bang; +#X msg 398 465 source_random \, dest_random \, srcand; +#N canvas 519 266 380 369 test 0; +#X obj 110 209 outlet; +#X obj 113 54 inlet; +#X msg 122 87 bang; +#X obj 115 122 random 20; +#X obj 115 149 bangx; +#X connect 1 0 2 0; +#X connect 2 0 3 0; +#X connect 3 0 4 0; +#X connect 4 0 0 0; +#X restore 398 402 pd test; +#X msg 172 142 connect localhost 6010; +#X obj 29 454 reset; +#X obj 398 440 init; +#X text 414 112 correct this path; +#X text 139 37 -- Sending frames through network --; +#X connect 1 0 0 0; +#X connect 1 0 2 0; +#X connect 2 0 0 1; +#X connect 3 0 17 0; +#X connect 4 0 3 0; +#X connect 5 0 3 0; +#X connect 5 0 12 0; +#X connect 7 0 6 0; +#X connect 12 0 3 0; +#X connect 13 0 3 0; +#X connect 15 0 3 0; +#X connect 16 0 3 0; +#X connect 17 0 3 0; +#X connect 18 0 3 0; +#X connect 19 0 16 0; +#X connect 19 0 21 0; +#X connect 20 0 17 1; +#X connect 21 0 3 0; +#X connect 22 0 3 0; +#X connect 23 0 7 0; +#X connect 24 0 20 0; diff --git a/Patches/13 example-avioutput.pd b/Patches/13 example-avioutput.pd new file mode 100644 index 0000000..b7fad86 --- /dev/null +++ b/Patches/13 example-avioutput.pd @@ -0,0 +1,61 @@ +#N canvas 252 23 721 631 12; +#X obj 13 39 fs.main; +#X msg 13 12 6001; +#X msg 64 13 reset; +#X obj 247 147 fs.framed aviout; +#X msg 385 147 37 + 127; +#X msg 75 39 path c:/fsrel/framestein; +#X obj 282 204 fs.copy; +#X msg 385 190 source_random; +#X obj 385 59 init; +#X msg 247 102 head.avi \, flip_manual; +#X msg 502 127 next \, bang \, flip; +#X floatatom 521 76 5 0 0; +#X obj 247 178 t s s; +#X obj 502 103 fps 0; +#X msg 484 76 5; +#X obj 269 361 fs.avi; +#X floatatom 269 387 5 0 0; +#X text 326 388 # of frames saved; +#X msg 349 273 fps 10; +#X text 412 273 set frames per second; +#X obj 349 249 init; +#X msg 349 318 write; +#X text 400 318 apply compression and finish; +#X text 482 50 start writing!; +#X text 158 481 Bang fs.frame to fs.avi to save one frame of video +; +#X text 158 508 Finish it off with "write [filename.avi]"; +#X msg 434 220 xbend \$1; +#X floatatom 507 220 5 0 0; +#X msg 507 195 75; +#X msg 550 103 0; +#X text 584 102 stop; +#X connect 1 0 0 0; +#X connect 1 0 2 0; +#X connect 2 0 0 1; +#X connect 2 0 5 0; +#X connect 3 0 12 0; +#X connect 3 2 4 0; +#X connect 4 0 3 0; +#X connect 5 0 0 1; +#X connect 6 0 3 0; +#X connect 7 0 6 1; +#X connect 8 0 9 0; +#X connect 8 0 4 0; +#X connect 8 0 7 0; +#X connect 9 0 3 0; +#X connect 10 0 3 0; +#X connect 11 0 13 0; +#X connect 12 0 15 0; +#X connect 12 1 6 0; +#X connect 13 0 10 0; +#X connect 14 0 13 0; +#X connect 15 0 16 0; +#X connect 18 0 15 0; +#X connect 20 0 18 0; +#X connect 21 0 15 0; +#X connect 26 0 6 1; +#X connect 27 0 26 0; +#X connect 28 0 27 0; +#X connect 29 0 13 0; diff --git a/Patches/14 example-hist.pd b/Patches/14 example-hist.pd new file mode 100644 index 0000000..e9c378c --- /dev/null +++ b/Patches/14 example-hist.pd @@ -0,0 +1,46 @@ +#N canvas 276 11 723 503 12; +#X obj 243 98 videoscrub; +#X floatatom 230 39 5 0 0; +#X obj 279 40 play 0; +#X msg 332 40 mousetrack_1; +#X graph graph1 0 -1 255 1 498 164 698 24; +#X array red 256 float 0; +#X pop; +#X msg 212 11 bang; +#X obj 9 39 fs.main; +#X msg 9 13 6001; +#X msg 60 13 reset; +#X obj 212 70 fs.framed example-hist 11+97; +#X graph graph2 0 -1 255 1 498 311 698 171; +#X array green 256 float 0; +#X pop; +#X graph graph3 0 -1 255 1 498 459 698 319; +#X array blue 256 float 0; +#X pop; +#X obj 217 183 fs.hist 0 red; +#X obj 230 208 fs.hist 1 green; +#X obj 245 234 fs.hist 2 blue; +#X text 110 13 click reset; +#X text 6 271 drop your favorite videofile to the frame .. then scrub +it!; +#X text 6 442 NOTE: fs.hist writes temporary files to your c:/.; +#X text 55 461 modify fs.hist.pd for a proper temporary path.; +#X obj 332 14 init; +#X msg 243 127 HARMON.JPG; +#X connect 0 0 9 0; +#X connect 1 0 2 0; +#X connect 2 0 9 0; +#X connect 3 0 9 0; +#X connect 5 0 9 0; +#X connect 7 0 6 0; +#X connect 7 0 8 0; +#X connect 8 0 6 1; +#X connect 9 0 0 0; +#X connect 9 0 12 0; +#X connect 9 0 13 0; +#X connect 9 0 14 0; +#X connect 9 1 0 1; +#X connect 9 1 5 0; +#X connect 19 0 3 0; +#X connect 19 0 20 0; +#X connect 20 0 9 0; diff --git a/Patches/15 example-searchpath.pd b/Patches/15 example-searchpath.pd new file mode 100644 index 0000000..ed1bd25 --- /dev/null +++ b/Patches/15 example-searchpath.pd @@ -0,0 +1,28 @@ +#N canvas 309 76 603 483 12; +#X obj 16 42 fs.main; +#X msg 16 16 6001; +#X msg 67 16 reset; +#X obj 270 314 fs.framed searchpath; +#X msg 435 314 35 + 148; +#X msg 163 60 path /framestein \, path /fsrel/framestein; +#X text 162 32 use "path " to tell where to search for images +; +#X msg 276 186 harmon.jpg; +#X msg 296 216 virvezoom.jpg; +#X msg 311 247 yska320x240.jpg; +#X msg 259 159 head.avi; +#X text 68 380 The dir where Framestein.exe was started from is always +in the search path.; +#X obj 435 290 init; +#X text 260 131 .. to make it easy to load them:; +#X connect 1 0 0 0; +#X connect 1 0 2 0; +#X connect 2 0 0 1; +#X connect 3 2 4 0; +#X connect 4 0 3 0; +#X connect 5 0 0 1; +#X connect 7 0 3 0; +#X connect 8 0 3 0; +#X connect 9 0 3 0; +#X connect 10 0 3 0; +#X connect 12 0 4 0; diff --git a/Patches/README.txt b/Patches/README.txt new file mode 100644 index 0000000..0fa86fe --- /dev/null +++ b/Patches/README.txt @@ -0,0 +1 @@ +See externals-documentation.pd in this folder. diff --git a/Patches/arraysize.c b/Patches/arraysize.c new file mode 100644 index 0000000..3393e8f --- /dev/null +++ b/Patches/arraysize.c @@ -0,0 +1,44 @@ +#include + +static t_class *arraysize_class; + +typedef struct _arraysize { + t_object x_obj; + t_symbol *array_name; +} t_arraysize; + +void arraysize_set(t_arraysize *x, t_symbol *s) +{ + x->array_name = s; +} + +void arraysize_bang(t_arraysize *x) +{ + t_garray *garray; + + if(!(garray = (t_garray *)pd_findbyclass(x->array_name,garray_class))) { + pd_error(x, "%s: no such table", x->array_name->s_name); + } else { + outlet_float(x->x_obj.ob_outlet, garray_npoints(garray)); + } +} + +void *arraysize_new(t_symbol *s) +{ + t_arraysize *x = (t_arraysize *)pd_new(arraysize_class); + + outlet_new(&x->x_obj, gensym("float")); + + x->array_name = s; + + return (void *)x; +} + +void arraysize_setup(void) +{ + + arraysize_class = class_new(gensym("arraysize"), (t_newmethod)arraysize_new, 0, sizeof(t_arraysize), CLASS_DEFAULT, A_DEFSYMBOL, 0); + + class_addmethod(arraysize_class,arraysize_set,gensym("set"), A_DEFSYM, 0); + class_addbang(arraysize_class,arraysize_bang); +} diff --git a/Patches/arraysize.dll b/Patches/arraysize.dll new file mode 100644 index 0000000..ffa3c8f Binary files /dev/null and b/Patches/arraysize.dll differ diff --git a/Patches/arraysize.exp b/Patches/arraysize.exp new file mode 100644 index 0000000..6292542 Binary files /dev/null and b/Patches/arraysize.exp differ diff --git a/Patches/arraysize.lib b/Patches/arraysize.lib new file mode 100644 index 0000000..c0342cf Binary files /dev/null and b/Patches/arraysize.lib differ diff --git a/Patches/arraysize.obj b/Patches/arraysize.obj new file mode 100644 index 0000000..8c664e8 Binary files /dev/null and b/Patches/arraysize.obj differ diff --git a/Patches/bangx.pd b/Patches/bangx.pd new file mode 100644 index 0000000..2bd5f82 --- /dev/null +++ b/Patches/bangx.pd @@ -0,0 +1,10 @@ +#N canvas 286 240 264 239 12; +#X obj 42 89 until; +#X obj 42 61 f 1; +#X obj 42 32 inlet; +#X obj 42 152 outlet; +#X msg 42 118 bang; +#X connect 0 0 4 0; +#X connect 1 0 0 0; +#X connect 2 0 1 0; +#X connect 4 0 3 0; diff --git a/Patches/buildstr.c b/Patches/buildstr.c new file mode 100644 index 0000000..6ba6b15 --- /dev/null +++ b/Patches/buildstr.c @@ -0,0 +1,51 @@ +#include + +#define MAXLEN 500 + +static t_class *buildstr_class; + +typedef struct _buildstr { + t_object x_obj; + t_symbol s; + char buf[MAXLEN]; + int pos; +} t_buildstr; + +void buildstr_bang(t_buildstr *x) +{ + x->s.s_name = t_getbytes(strlen(x->buf)+1); + strcpy(x->s.s_name, x->buf); + outlet_symbol(x->x_obj.ob_outlet, &x->s); + t_freebytes(x->s.s_name, strlen(x->buf)+1); +} + +void buildstr_float(t_buildstr *x, t_float f) +{ + x->buf[x->pos] = (char)f; + x->pos++; + + if(f==0) + { + x->pos=0; + buildstr_bang(x); + } +} + +void *buildstr_new(t_symbol *s) +{ + t_buildstr *x = (t_buildstr *)pd_new(buildstr_class); + + x->pos = 0; + + outlet_new(&x->x_obj, gensym("symbol")); + + return (void *)x; +} + +void buildstr_setup(void) +{ + buildstr_class = class_new(gensym("buildstr"), (t_newmethod)buildstr_new, 0, sizeof(t_buildstr), CLASS_DEFAULT, A_DEFSYMBOL, 0); + + class_addbang(buildstr_class, buildstr_bang); + class_addfloat(buildstr_class, buildstr_float); +} diff --git a/Patches/buildstr.dll b/Patches/buildstr.dll new file mode 100644 index 0000000..92de6a3 Binary files /dev/null and b/Patches/buildstr.dll differ diff --git a/Patches/buildstr.exp b/Patches/buildstr.exp new file mode 100644 index 0000000..38c60e9 Binary files /dev/null and b/Patches/buildstr.exp differ diff --git a/Patches/buildstr.lib b/Patches/buildstr.lib new file mode 100644 index 0000000..d1aa14c Binary files /dev/null and b/Patches/buildstr.lib differ diff --git a/Patches/buildstr.obj b/Patches/buildstr.obj new file mode 100644 index 0000000..a916941 Binary files /dev/null and b/Patches/buildstr.obj differ diff --git a/Patches/count.pd b/Patches/count.pd new file mode 100644 index 0000000..a627e99 --- /dev/null +++ b/Patches/count.pd @@ -0,0 +1,17 @@ +#N canvas 0 0 454 304 10; +#X obj 170 53 inlet; +#X text 177 7 count to n; +#X obj 170 168 f; +#X obj 170 211 outlet; +#X obj 170 85 t f b; +#X obj 145 131 bangx; +#X obj 198 168 + 1; +#X msg 203 116 1; +#X connect 0 0 4 0; +#X connect 2 0 6 0; +#X connect 2 0 3 0; +#X connect 4 0 5 0; +#X connect 4 1 7 0; +#X connect 5 0 2 0; +#X connect 6 0 2 1; +#X connect 7 0 2 1; diff --git a/Patches/displaydepth.h b/Patches/displaydepth.h new file mode 100644 index 0000000..3df0471 --- /dev/null +++ b/Patches/displaydepth.h @@ -0,0 +1,19 @@ +#ifndef __DISPLAYDEPTH_H +#define __DISPLAYDEPTH_H + +#include "windows.h" + +int getdisplaydepth(void) +{ + DEVMODE dm; + + dm.dmSize = sizeof(DEVMODE); + dm.dmDriverExtra = 0; + + if(!EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm)) + return(0); + + return(dm.dmBitsPerPel); +} + +#endif diff --git a/Patches/dllcall.h b/Patches/dllcall.h new file mode 100644 index 0000000..ab7b128 --- /dev/null +++ b/Patches/dllcall.h @@ -0,0 +1,46 @@ +#ifndef __DLLCALL_H +#define __DLLCALL_H + +#include "windows.h" + +void loadeffect(HMODULE *lib, FARPROC *proc, char *name) +{ + if(*lib) FreeLibrary(*lib); + + *lib = LoadLibrary(name); + if(!*lib) + { + post("loadeffect: failed to load %s", name); + return; + } + *proc = GetProcAddress(*lib, "perform_effect"); + if(!*proc) + { + post("loadeffect: failed to get perform_effect from %s", name); + FreeLibrary(*lib); + *lib=NULL; + return; + } +} + +void loadcopy(HMODULE *lib, FARPROC *proc, char *name) +{ + if(*lib) FreeLibrary(*lib); + + *lib = LoadLibrary(name); + if(!*lib) + { + post("loadcopy: failed to load %s", name); + return; + } + *proc = GetProcAddress(*lib, "perform_copy"); + if(!*proc) + { + post("loadcopy: failed to get perform_copy from %s", name); + FreeLibrary(*lib); + *lib=NULL; + return; + } +} + +#endif diff --git a/Patches/externals-documentation.pd b/Patches/externals-documentation.pd new file mode 100644 index 0000000..f065834 --- /dev/null +++ b/Patches/externals-documentation.pd @@ -0,0 +1,342 @@ +#N canvas 438 30 545 591 12; +#X text 21 21 Externals for video:; +#N canvas 148 3 734 663 vframe 0; +#X obj 34 275 fs.frame; +#X obj 55 377 vimport; +#X obj 221 427 fs.frame; +#X msg 244 398 320x240; +#X msg 253 178 bang; +#X text 302 176 set vframe to import to; +#X text 26 509 Connect vframe directly to fs.frame to display it with +a bang.; +#X msg 253 206 bang; +#X text 302 198 import image \, and bang vframe again to display it +; +#X obj 150 331 vframe 640 480; +#X msg 34 245 320x240 \, noize \, colortv; +#X text 17 14 vframe holds memory for a single image and is the basis +of Pure Data-externals-based image handling in Framestein.; +#X text 26 553 Here \, vframe is bigger (640x480) than the two fs.frames +(320x240). This is okay - as long as the fs.frames you import from +and to are of the same size \, the image will be right. If you import +to fs.frame of a different size than the fs.frame you imported from +-> garbage.; +#X text 17 109 vframe has no image loading and display functionality. +Images can be imported to and from fs.frame:; +#X msg 349 423 dock vframe \, 330+260; +#X text 16 59 Initialization arguments determine the width and height +of the image \, as in below. Defaults are 176 and 144; +#X obj 34 220 init; +#X obj 244 373 init; +#X connect 0 0 1 0; +#X connect 3 0 2 0; +#X connect 4 0 9 0; +#X connect 7 0 0 0; +#X connect 7 0 9 0; +#X connect 9 0 1 1; +#X connect 9 0 2 0; +#X connect 10 0 0 0; +#X connect 14 0 2 0; +#X connect 16 0 10 0; +#X connect 17 0 3 0; +#X restore 64 216 pd vframe; +#X obj 67 122 fs.main; +#X msg 67 86 6001; +#X text 160 215 basic image container; +#N canvas 256 206 618 418 vplugin 0; +#X obj 94 226 vframe; +#X obj 143 156 vplugin; +#X text 13 10 vframe can execute Framestein-plugins. vplugin has the +path to these plugins - open it up \, correct the path \, and try it. +; +#X msg 161 99 noize; +#X msg 218 99 colortv; +#X obj 94 286 fs.frame; +#X msg 201 240 dock vplugin \, 200+235; +#X connect 0 0 5 0; +#X connect 1 0 0 0; +#X connect 3 0 1 0; +#X connect 4 0 1 0; +#X connect 6 0 5 0; +#X restore 64 262 pd vplugin; +#X text 158 261 execute Framestein-plugins; +#N canvas 187 -3 640 677 vcopy 0; +#X obj 87 204 vcopy; +#X msg 240 145 tile \$1; +#X floatatom 240 116 5 0 0; +#X floatatom 240 176 5 0 0; +#X msg 240 201 xbend \$1; +#X obj 87 341 fs.frame; +#X obj 114 61 r vcopyexample; +#X obj 87 129 vref; +#X msg 87 98 bang; +#X floatatom 97 159 5 0 0; +#X msg 167 341 320x240; +#X obj 87 294 vframe 320 240; +#X msg 240 283 xbend \$1 \$2; +#X obj 240 258 pack f f; +#X floatatom 240 233 5 0 0; +#X floatatom 299 233 5 0 0; +#X msg 311 259 bang; +#X obj 386 201 random 320; +#X obj 386 227 random 320; +#X floatatom 386 113 5 0 0; +#X msg 118 379 dock vcopy \, 90+400; +#X text 17 9 Some plugins operate on two images. This is done with +vcopy:; +#X obj 167 315 init; +#X obj 386 139 fps 0.25; +#X connect 0 0 11 0; +#X connect 1 0 0 1; +#X connect 1 0 8 0; +#X connect 2 0 1 0; +#X connect 3 0 4 0; +#X connect 4 0 0 1; +#X connect 4 0 8 0; +#X connect 6 0 7 1; +#X connect 7 0 0 0; +#X connect 7 0 9 0; +#X connect 8 0 7 0; +#X connect 10 0 5 0; +#X connect 11 0 5 0; +#X connect 12 0 0 1; +#X connect 12 0 8 0; +#X connect 13 0 12 0; +#X connect 14 0 13 0; +#X connect 15 0 13 1; +#X connect 15 0 16 0; +#X connect 16 0 13 0; +#X connect 17 0 14 0; +#X connect 18 0 15 0; +#X connect 19 0 23 0; +#X connect 20 0 5 0; +#X connect 22 0 10 0; +#X connect 23 0 17 0; +#X connect 23 0 18 0; +#X restore 64 310 pd vcopy; +#X text 159 309 execute plugins that use two images; +#N canvas 148 7 833 572 vsig~ 0; +#X text 14 9 vsig~: convert image to signal; +#X obj 201 140 vframe; +#X obj 209 182 vsig~; +#X obj 209 446 vsnapshot~; +#X obj 257 185 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X obj 201 109 vplugin; +#X obj 284 413 vframe; +#X msg 201 75 noize \, colortv; +#X msg 378 99 \; pd dsp 1; +#X obj 209 485 fs.frame; +#X msg 284 387 bang; +#X text 402 204 - image signal; +#X text 403 228 - sync signal; +#X text 403 253 - bang when bottomright of image is reached; +#X text 383 302 vsnapshot~ inlets:; +#X text 382 180 vsig~ outlets:; +#X text 402 330 - image signal; +#X text 403 354 - sync signal; +#X text 403 380 - vframe to write image to; +#X obj 45 289 dac~; +#X floatatom 89 255 5 0 0; +#X text 83 289 sounds great!; +#X obj 45 255 *~ 0; +#X text 14 25 vsnapshot~: convert signal to image; +#X msg 273 102 black; +#X obj 44 370 osc~ 2; +#X obj 44 397 *~ 0; +#X floatatom 86 397 5 0 0; +#X text 100 372 looks great!; +#X floatatom 44 345 5 0 0; +#X msg 44 485 dock vsig~ \, 12+87; +#X obj 378 72 init; +#X obj 284 361 init; +#X connect 1 0 2 0; +#X connect 2 0 22 0; +#X connect 2 0 3 0; +#X connect 2 1 3 1; +#X connect 2 2 4 0; +#X connect 3 0 9 0; +#X connect 5 0 1 0; +#X connect 6 0 3 2; +#X connect 7 0 5 0; +#X connect 10 0 6 0; +#X connect 20 0 22 1; +#X connect 22 0 19 0; +#X connect 22 0 19 1; +#X connect 24 0 5 0; +#X connect 25 0 26 0; +#X connect 26 0 3 0; +#X connect 27 0 26 1; +#X connect 29 0 25 0; +#X connect 30 0 9 0; +#X connect 31 0 8 0; +#X connect 31 0 7 0; +#X connect 32 0 10 0; +#X restore 64 360 pd vsig~ and vsnapshot~; +#X text 161 392 convert image to signal and back; +#N canvas 239 28 735 584 vrgb~ 0; +#X obj 389 140 vframe 320 240; +#X obj 389 171 vsig~; +#X text 9 7 vrgb~: separate red \, green and blue channels; +#X obj 240 239 vimport; +#X obj 181 188 fs.frame; +#X obj 188 77 reset; +#X obj 188 102 t b b b; +#X msg 234 77 bang; +#X msg 277 77 \; pd dsp 1; +#X obj 435 174 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X obj 389 221 vrgb~; +#X obj 389 345 vsnapshot~; +#X obj 482 327 vframe 320 240; +#X obj 482 277 reset; +#X msg 482 302 bang; +#X obj 389 387 fs.frame; +#X msg 482 379 320x240; +#X obj 427 269 *~ 1; +#X obj 571 88 phasor~ 1; +#X obj 571 112 avg~; +#X obj 571 141 < 0.5; +#X obj 571 166 * -1; +#X obj 616 141 >= 0.5; +#X obj 616 166 * 1; +#X obj 571 191 +; +#X floatatom 571 216 5 0 0; +#X floatatom 571 63 5 0 0; +#X msg 367 429 dock vrgb~ \, 25+300; +#X obj 567 360 s vcopyexample; +#X obj 389 304 vcolor~; +#X obj 389 269 *~ 1; +#X text 8 26 vcolor~: merge red \, green and blue channels; +#X msg 41 152 yska320x240.jpg \, bang; +#X connect 0 0 1 0; +#X connect 0 0 3 1; +#X connect 1 0 10 0; +#X connect 1 1 11 1; +#X connect 1 2 9 0; +#X connect 4 0 3 0; +#X connect 5 0 6 0; +#X connect 5 0 7 0; +#X connect 6 0 0 0; +#X connect 6 1 32 0; +#X connect 6 2 0 0; +#X connect 7 0 6 0; +#X connect 7 0 8 0; +#X connect 7 0 6 0; +#X connect 10 0 30 0; +#X connect 10 1 17 0; +#X connect 11 0 15 0; +#X connect 12 0 11 2; +#X connect 12 0 28 0; +#X connect 13 0 14 0; +#X connect 14 0 12 0; +#X connect 14 0 16 0; +#X connect 16 0 15 0; +#X connect 17 0 29 1; +#X connect 18 0 19 0; +#X connect 19 0 22 0; +#X connect 19 0 20 0; +#X connect 20 0 21 0; +#X connect 21 0 24 0; +#X connect 22 0 23 0; +#X connect 23 0 24 1; +#X connect 24 0 25 0; +#X connect 25 0 17 1; +#X connect 25 0 30 1; +#X connect 26 0 18 0; +#X connect 27 0 15 0; +#X connect 29 0 11 0; +#X connect 30 0 29 0; +#X connect 32 0 4 0; +#X restore 64 440 pd vrgb~; +#X text 162 439 separate red \, green and blue channels; +#X text 159 144 ... click on "dock" on subpatches.; +#X msg 118 86 reset; +#X msg 339 82 minimizeall; +#X text 159 122 start by clicking reset... and minimizeall; +#N canvas 233 -13 700 660 vframeread~ 0; +#X text 11 7 vframeread~ uses a sync-signal to read the image:; +#X obj 212 308 vframe; +#X obj 161 337 vimport; +#X obj 71 297 fs.frame; +#X obj 71 326 fs.copy; +#X obj 71 353 fs.frame; +#X msg 212 280 bang; +#X obj 212 251 reset; +#X msg 71 116 dock vframeread~ \, 10+100; +#X text 13 47 drop a movie (.avi) here...; +#X text 82 96 click here; +#X obj 361 92 vframeread~; +#X obj 361 312 vsnapshot~; +#X obj 14 307 fps 5; +#X floatatom 53 427 5 0 0; +#X msg 81 270 next \, bang; +#X obj 361 372 fs.frame; +#X msg 361 469 dock vframeread~ \, 330+440; +#X text 380 445 click here; +#X obj 436 287 vframe; +#X obj 436 237 reset; +#X msg 436 262 bang; +#X obj 361 344 vref; +#X floatatom 482 130 5 0 0; +#X obj 482 159 phasor~ 1; +#X obj 491 259 vplugin; +#X msg 491 235 black; +#X text 107 426 set framerate; +#X msg 482 104 14.9; +#X obj 482 79 reset; +#X text 534 130 see how it's done; +#X text 17 595 This gives a better frame-rate \, compromizing the image +quality..; +#X obj 361 204 *~ 1; +#X floatatom 388 179 5 0 0; +#X msg 87 398 25; +#X msg 524 104 25.19; +#X msg 388 152 1; +#X msg 419 152 -1; +#X msg 53 398 15; +#X connect 1 0 2 1; +#X connect 1 0 11 0; +#X connect 3 0 4 0; +#X connect 4 0 5 0; +#X connect 5 0 2 0; +#X connect 6 0 1 0; +#X connect 6 0 5 0; +#X connect 7 0 6 0; +#X connect 8 0 3 0; +#X connect 11 0 32 0; +#X connect 12 0 22 1; +#X connect 13 0 15 0; +#X connect 13 0 5 0; +#X connect 13 0 22 0; +#X connect 14 0 13 0; +#X connect 15 0 3 0; +#X connect 17 0 16 0; +#X connect 19 0 12 2; +#X connect 20 0 21 0; +#X connect 21 0 19 0; +#X connect 22 0 16 0; +#X connect 23 0 24 0; +#X connect 23 0 26 0; +#X connect 24 0 12 1; +#X connect 24 0 11 0; +#X connect 25 0 19 0; +#X connect 26 0 25 0; +#X connect 28 0 23 0; +#X connect 29 0 28 0; +#X connect 32 0 12 0; +#X connect 33 0 32 1; +#X connect 34 0 14 0; +#X connect 35 0 23 0; +#X connect 36 0 33 0; +#X connect 37 0 33 0; +#X connect 38 0 14 0; +#X restore 64 487 pd vframeread~; +#X text 195 486 read image with a sync-signal; +#X obj 339 57 init; +#X text 65 530 vdrawarray is documented on example-vdrawarray.; +#X connect 3 0 2 0; +#X connect 3 0 14 0; +#X connect 14 0 2 1; +#X connect 15 0 2 1; +#X connect 19 0 15 0; diff --git a/Patches/fps.pd b/Patches/fps.pd new file mode 100644 index 0000000..3e61074 --- /dev/null +++ b/Patches/fps.pd @@ -0,0 +1,25 @@ +#N canvas 17 261 466 316 12; +#X obj 307 192 /; +#X obj 319 128 t b f; +#X obj 67 27 inlet; +#X msg 293 157 1000; +#X obj 87 222 outlet; +#X obj 87 112 metro 1000; +#X text 10 -1 sends bangs to make "frames per second"; +#X obj 226 62 float \$1; +#X obj 226 32 loadbang; +#X obj 307 218 abs; +#X obj 344 37 inlet; +#X text 354 61 "cold" inlet; +#X connect 0 0 9 0; +#X connect 1 0 3 0; +#X connect 1 1 0 1; +#X connect 2 0 1 0; +#X connect 2 0 5 0; +#X connect 3 0 0 0; +#X connect 5 0 4 0; +#X connect 7 0 1 0; +#X connect 7 0 5 0; +#X connect 8 0 7 0; +#X connect 9 0 5 1; +#X connect 10 0 1 0; diff --git a/Patches/fs.avi.pd b/Patches/fs.avi.pd new file mode 100644 index 0000000..909e4d9 --- /dev/null +++ b/Patches/fs.avi.pd @@ -0,0 +1,33 @@ +#N canvas 237 45 692 382 12; +#X obj 172 80 loadbang; +#X obj 126 275 fs_sender; +#X obj 51 27 inlet; +#X obj 51 55 l2s; +#X obj 51 102 pack s s; +#X obj 172 203 symbol; +#X obj 189 147 r fs_reset; +#X msg 189 172 bang; +#X text 287 28 commands:; +#X obj 172 110 symbol \$0A; +#X msg 172 228 avi \$1; +#X msg 51 137 \$2 \$1; +#X text 103 28 command; +#X text 318 56 fs.frame id to save one frame of video; +#X obj 59 310 r \$0Apos; +#X obj 59 340 outlet; +#X text 326 96 write to write it out; +#X text 323 115 (without filename a dialog will pop); +#X text 330 161 "fps 10" to set frames per second.; +#X text 318 182 (only effective before adding frames); +#X connect 0 0 9 0; +#X connect 2 0 3 0; +#X connect 3 0 4 0; +#X connect 4 0 11 0; +#X connect 5 0 10 0; +#X connect 6 0 7 0; +#X connect 7 0 5 0; +#X connect 9 0 4 1; +#X connect 9 0 5 0; +#X connect 10 0 1 0; +#X connect 11 0 1 0; +#X connect 14 0 15 0; diff --git a/Patches/fs.blend.pd b/Patches/fs.blend.pd new file mode 100644 index 0000000..32ce7e0 --- /dev/null +++ b/Patches/fs.blend.pd @@ -0,0 +1,37 @@ +#N canvas 30 209 749 354 10; +#X obj 55 42 inlet; +#X obj 159 301 outlet; +#X obj 239 43 inlet; +#X obj 90 143 fs.copy; +#X obj 173 146 fs.copy; +#X obj 192 104 symbol; +#X obj 330 44 inlet; +#X msg 329 100 alpha \$1; +#X msg 289 176 127; +#X msg 286 215 flip_manual; +#X obj 346 174 init; +#X obj 63 91 t b s b; +#X msg 24 134 flip; +#X text 47 20 fs.frame; +#X text 229 19 fs.frame; +#X text 152 322 fs.frame; +#X text 314 21 blend amount; +#X text 447 21 fs.blend -- mix two images with parameter; +#X text 447 44 see example-blending.pd!; +#X obj 330 71 int; +#X connect 0 0 11 0; +#X connect 2 0 5 1; +#X connect 3 0 1 0; +#X connect 4 0 1 0; +#X connect 5 0 4 0; +#X connect 6 0 19 0; +#X connect 7 0 3 1; +#X connect 8 0 7 0; +#X connect 9 0 1 0; +#X connect 10 0 8 0; +#X connect 10 0 9 0; +#X connect 11 0 12 0; +#X connect 11 1 3 0; +#X connect 11 2 5 0; +#X connect 12 0 1 0; +#X connect 19 0 7 0; diff --git a/Patches/fs.browser.pd b/Patches/fs.browser.pd new file mode 100644 index 0000000..cac5233 --- /dev/null +++ b/Patches/fs.browser.pd @@ -0,0 +1,48 @@ +#N canvas 43 99 953 532 12; +#X obj 444 24 loadbang; +#X obj 276 380 fs_sender; +#X obj 76 25 inlet; +#X obj 76 55 route bang; +#X obj 76 91 symbol; +#X obj 151 111 route fs_op; +#X obj 151 153 pack s s s; +#X obj 76 125 outlet; +#X obj 276 193 l2s; +#X obj 276 226 pack s s; +#X msg 276 259 \$2 \$1; +#X text 450 149 inlet accepts:; +#X obj 444 91 symbol; +#X obj 538 83 r fs_reset; +#X msg 538 108 bang; +#X obj 444 54 symbol \$0fs.browser; +#X msg 444 119 browser \$1; +#X text 492 181 or "open "; +#X text 491 210 "refresh" "stop"; +#X text 491 240 "640x480" to set display size; +#X obj 461 327 r \$0fs.browserlink; +#X obj 461 380 symbol; +#X obj 461 406 outlet; +#X text 461 304 report clicked links starting with "fs:"; +#X obj 461 353 buildstr; +#X connect 0 0 15 0; +#X connect 2 0 3 0; +#X connect 3 0 4 0; +#X connect 3 1 5 0; +#X connect 4 0 7 0; +#X connect 5 0 6 0; +#X connect 5 1 8 0; +#X connect 6 0 1 0; +#X connect 8 0 9 0; +#X connect 9 0 10 0; +#X connect 10 0 1 0; +#X connect 12 0 16 0; +#X connect 13 0 14 0; +#X connect 14 0 12 0; +#X connect 15 0 4 1; +#X connect 15 0 6 2; +#X connect 15 0 9 1; +#X connect 15 0 12 0; +#X connect 16 0 1 0; +#X connect 20 0 24 0; +#X connect 21 0 22 0; +#X connect 24 0 21 0; diff --git a/Patches/fs.copy.pd b/Patches/fs.copy.pd new file mode 100644 index 0000000..8598ae9 --- /dev/null +++ b/Patches/fs.copy.pd @@ -0,0 +1,51 @@ +#N canvas 205 60 932 444 12; +#X obj 173 21 loadbang; +#X obj 208 271 fs_sender; +#X msg 173 204 copy \$1; +#X obj 352 14 inlet; +#X text 465 118 dest_all; +#X text 465 132 dest_random; +#X text 465 152 copy; +#X text 465 167 alpha ; +#X text 466 197 sub ; +#X text 465 183 add ; +#X text 466 62 source_all; +#X text 466 79 source_random; +#X obj 23 22 inlet; +#X obj 23 155 outlet; +#X obj 23 62 pack s s; +#X msg 23 95 fs_op \$2 \$1; +#X obj 352 156 pack s s; +#X msg 352 185 \$2 \$1; +#X obj 352 127 l2s; +#X text 466 47 source ; +#X text 465 104 dest ; +#X text 399 15 for these commands:; +#X obj 173 174 symbol; +#X obj 194 114 r fs_reset; +#X msg 194 140 bang; +#X text 467 267 blackness dstinvert mergecopy mergepaint notsrccopy +notsrcerase patcopy patinvert patpaint srcand srccopy srcerase srcinvert +srcpaint whiteness; +#X text 466 226 try these raster operations: (some of them do nothing) +; +#X text 468 329 transparent_0/1 mirrorleftright_0/1 mirrorupdown_0/1 +; +#X text 467 358 "plugin_name" (see example-plugins.pd); +#X obj 173 51 symbol \$0C; +#X text 467 389 "filter_name" (see example-photoshopfilters.pd); +#X connect 0 0 29 0; +#X connect 2 0 1 0; +#X connect 3 0 18 0; +#X connect 12 0 14 0; +#X connect 14 0 15 0; +#X connect 15 0 13 0; +#X connect 16 0 17 0; +#X connect 17 0 1 0; +#X connect 18 0 16 0; +#X connect 22 0 2 0; +#X connect 23 0 24 0; +#X connect 24 0 29 0; +#X connect 29 0 14 1; +#X connect 29 0 16 1; +#X connect 29 0 22 0; diff --git a/Patches/fs.draw.pd b/Patches/fs.draw.pd new file mode 100644 index 0000000..cc9ea77 --- /dev/null +++ b/Patches/fs.draw.pd @@ -0,0 +1,32 @@ +#N canvas 301 30 843 370 12; +#X obj 172 80 loadbang; +#X obj 126 275 fs_sender; +#X obj 51 27 inlet; +#X obj 51 55 l2s; +#X obj 51 102 pack s s; +#X msg 51 137 fs_op \$2 \$1; +#X obj 172 203 symbol; +#X obj 189 147 r fs_reset; +#X msg 189 172 bang; +#X text 100 28 command; +#X text 344 89 commands:; +#X text 363 123 rect ; +#X msg 172 228 draw \$1; +#X obj 51 176 outlet; +#X text 362 143 line ; +#X text 363 162 plot ; +#X text 363 234 mode_solid mode_clear; +#X text 362 196 pen (to set pen color); +#X text 362 215 brush (to set brush color); +#X obj 172 110 symbol \$0D; +#X connect 0 0 19 0; +#X connect 2 0 3 0; +#X connect 3 0 4 0; +#X connect 4 0 5 0; +#X connect 5 0 13 0; +#X connect 6 0 12 0; +#X connect 7 0 8 0; +#X connect 8 0 6 0; +#X connect 12 0 1 0; +#X connect 19 0 4 1; +#X connect 19 0 6 0; diff --git a/Patches/fs.event.pd b/Patches/fs.event.pd new file mode 100644 index 0000000..fa56b61 --- /dev/null +++ b/Patches/fs.event.pd @@ -0,0 +1,30 @@ +#N canvas 381 52 466 526 12; +#X obj 37 50 inlet; +#X text 86 50 fs.frame 1st outlet; +#X obj 96 107 symbol \$0E; +#X obj 37 132 pack s s; +#X obj 96 83 loadbang; +#X msg 37 166 \; \$1event \$2; +#X obj 323 373 r \$0Emouseup; +#X obj 323 459 outlet; +#X obj 38 460 outlet; +#X text 323 350 report mouseup; +#X obj 169 461 outlet; +#X text 168 350 report mousedown; +#X obj 169 375 r \$0Emousedown; +#X text 16 13 fs.event - events from fs.frame; +#X text 38 334 report drag&drop filename; +#X obj 38 374 r \$0Efile; +#X obj 38 431 symbol; +#X msg 169 430 bang; +#X msg 323 428 bang; +#X connect 0 0 3 0; +#X connect 2 0 3 1; +#X connect 3 0 5 0; +#X connect 4 0 2 0; +#X connect 6 0 18 0; +#X connect 12 0 17 0; +#X connect 15 0 16 0; +#X connect 16 0 8 0; +#X connect 17 0 10 0; +#X connect 18 0 7 0; diff --git a/Patches/fs.film.pd b/Patches/fs.film.pd new file mode 100644 index 0000000..84d64e8 --- /dev/null +++ b/Patches/fs.film.pd @@ -0,0 +1,47 @@ +#N canvas 31 111 536 458 12; +#X obj 121 289 fs.frame; +#X obj 323 218 reset; +#X msg 323 246 hide; +#X obj 28 31 inlet; +#X obj 121 374 outlet; +#X obj 180 374 outlet; +#X obj 25 332 fs.info; +#X msg 247 211 bang; +#X obj 28 68 route open start stop; +#X obj 28 128 openpanel; +#X msg 56 156 bang; +#X msg 221 129 bang; +#X msg 273 128 0; +#X obj 234 182 play 0; +#X msg 209 69 bang; +#X obj 221 154 int; +#X floatatom 42 360 5 0 0; +#X msg 28 103 bang; +#X obj 121 331 symbol; +#X floatatom 318 154 5 0 0; +#X connect 0 0 6 0; +#X connect 0 0 18 1; +#X connect 0 1 5 0; +#X connect 1 0 2 0; +#X connect 2 0 0 0; +#X connect 3 0 8 0; +#X connect 6 3 15 1; +#X connect 6 3 16 0; +#X connect 7 0 18 0; +#X connect 8 0 17 0; +#X connect 8 1 11 0; +#X connect 8 2 12 0; +#X connect 8 3 0 0; +#X connect 8 3 14 0; +#X connect 9 0 0 0; +#X connect 9 0 10 0; +#X connect 10 0 0 0; +#X connect 11 0 15 0; +#X connect 12 0 13 0; +#X connect 13 0 0 0; +#X connect 13 0 7 0; +#X connect 14 0 0 0; +#X connect 15 0 13 0; +#X connect 17 0 9 0; +#X connect 18 0 4 0; +#X connect 19 0 13 0; diff --git a/Patches/fs.frame.pd b/Patches/fs.frame.pd new file mode 100644 index 0000000..bac2004 --- /dev/null +++ b/Patches/fs.frame.pd @@ -0,0 +1,137 @@ +#N canvas 19 -3 1010 686 12; +#X msg 444 119 frame \$1; +#X obj 276 355 fs_sender; +#X obj 76 25 inlet; +#X obj 76 145 symbol; +#X obj 151 126 route fs_op; +#X obj 151 168 pack s s s; +#X obj 76 192 outlet; +#X obj 276 193 l2s; +#X obj 276 226 pack s s; +#X msg 276 259 \$2 \$1; +#X text 468 227 "next" "prev" "random" "seek " to show frames +in video or buffered images.; +#X text 469 264 "clear" to flush buffered images.; +#X text 468 300 "flip_auto" "flip_manual" "flip" controls how the display +should reflect changes in the image.; +#X text 468 343 "320x240" to set image size "100+100" to set frame +position "display 600x450" to set display size; +#X text 469 382 "borders_0" "borders_1" "stayontop_0"/1 "mute_0"/1 +\, also right-click the image for display options.; +#X text 450 149 inlet accepts:; +#X obj 444 91 symbol; +#X text 469 428 "save <"bmp" or number for jpeg quality>" +save image in directory under name fs000001 \, fs000002 ...; +#X text 467 470 "plugin_name" (see example-plugins.pd); +#X text 471 494 mousetrack_1 and mousetrack_0 to report mouse x \, +y thru second outlet; +#X msg 19 295 bang; +#X text 27 244 drag&drop will bang; +#X obj 275 482 outlet; +#X text 471 530 mouserect_1 and mouserect_0 to report dragged rectangle +; +#X obj 444 24 reset; +#X obj 76 55 route bang float; +#X msg 137 98 vf2fs \$1; +#N canvas 0 0 646 581 report 0; +#X obj 54 94 pack f f; +#X obj 88 248 pack f f f f; +#X text 58 17 report mouse x \, y; +#X text 88 130 report mouse rect; +#X text 115 297 report moving the window; +#X obj 15 522 outlet; +#X obj 126 382 pack f f; +#X msg 126 411 set \$1 + \$2; +#X obj 54 39 r \$0Fx; +#X obj 61 63 r \$0Fy; +#X obj 84 151 r \$0Fx1; +#X obj 84 175 r \$0Fy1; +#X obj 84 198 r \$0Fx2; +#X obj 85 222 r \$0Fy2; +#X obj 142 324 r \$0Fwinx; +#X obj 142 348 r \$0Fwiny; +#X obj 68 522 outlet; +#X obj 383 101 pack f s; +#X obj 497 57 r \$0Fevent; +#X obj 453 101 symbol; +#X text 383 164 report mouseup; +#X obj 383 187 r \$0Fmouseup; +#X obj 383 248 pack f s; +#X obj 497 204 r \$0Fevent; +#X msg 383 275 \; \$2mouseup \$1; +#X obj 453 248 symbol; +#X text 383 17 report mousedown; +#X msg 383 128 \; \$2mousedown \$1; +#X obj 383 40 r \$0Fmousedown; +#X text 384 341 report drag&drop filename; +#X obj 384 366 r \$0Ffile; +#X obj 384 419 buildstr; +#X obj 384 456 pack s s; +#X obj 493 412 r \$0Fevent; +#X obj 454 456 symbol; +#X msg 384 487 \; \$2file \$1; +#X obj 384 392 f; +#X connect 0 0 5 0; +#X connect 1 0 5 0; +#X connect 6 0 7 0; +#X connect 7 0 16 0; +#X connect 8 0 0 0; +#X connect 9 0 0 1; +#X connect 10 0 1 0; +#X connect 11 0 1 1; +#X connect 12 0 1 2; +#X connect 13 0 1 3; +#X connect 14 0 6 0; +#X connect 15 0 6 1; +#X connect 17 0 27 0; +#X connect 18 0 19 0; +#X connect 19 0 17 1; +#X connect 21 0 22 0; +#X connect 22 0 24 0; +#X connect 23 0 25 0; +#X connect 25 0 22 1; +#X connect 28 0 17 0; +#X connect 30 0 36 0; +#X connect 31 0 32 0; +#X connect 32 0 35 0; +#X connect 33 0 34 0; +#X connect 34 0 32 1; +#X connect 36 0 31 0; +#X restore 275 440 pd report; +#X obj 444 54 symbol \$0F; +#X obj 140 25 r \$0Finlet; +#X obj 19 269 r \$0Fbang; +#X obj 327 482 outlet; +#X text 472 575 minimize \, maximize \, bringtofront; +#X text 471 553 bufferize will copy the current image to image buffer +; +#X text 471 600 hidecursor_1 \, hidecursor_0; +#X text 470 622 use "directory" - like buffer \, without buffering +(load on demand); +#X text 468 190 "buffer " to load to memory; +#X text 469 171 filename to load and display (.avi .bmp .jpg); +#X text 468 208 "buffer " to load all images in dir; +#X connect 0 0 1 0; +#X connect 2 0 25 0; +#X connect 3 0 6 0; +#X connect 4 0 5 0; +#X connect 4 1 7 0; +#X connect 5 0 1 0; +#X connect 7 0 8 0; +#X connect 8 0 9 0; +#X connect 9 0 1 0; +#X connect 16 0 0 0; +#X connect 20 0 3 0; +#X connect 24 0 28 0; +#X connect 25 0 3 0; +#X connect 25 1 26 0; +#X connect 25 2 4 0; +#X connect 26 0 4 0; +#X connect 27 0 22 0; +#X connect 27 1 31 0; +#X connect 28 0 3 1; +#X connect 28 0 5 2; +#X connect 28 0 8 1; +#X connect 28 0 16 0; +#X connect 29 0 25 0; +#X connect 30 0 20 0; diff --git a/Patches/fs.framed.pd b/Patches/fs.framed.pd new file mode 100644 index 0000000..14c4fb4 --- /dev/null +++ b/Patches/fs.framed.pd @@ -0,0 +1,24 @@ +#N canvas 61 76 511 375 12; +#X obj 92 199 fs.frame; +#X obj 263 129 symbol \$1; +#X obj 92 91 inlet; +#X obj 92 291 outlet; +#X msg 263 155 dock \$1; +#X text 9 5 fs.framed - docked fs.frame; +#X obj 151 291 outlet; +#X obj 186 129 symbol \$2; +#X obj 186 93 t b b; +#X obj 209 291 outlet; +#X obj 186 68 reset; +#X text 35 30 usage: fs.framed +; +#X connect 0 0 3 0; +#X connect 0 1 6 0; +#X connect 0 2 9 0; +#X connect 1 0 4 0; +#X connect 2 0 0 0; +#X connect 4 0 0 0; +#X connect 7 0 0 0; +#X connect 8 0 7 0; +#X connect 8 1 1 0; +#X connect 10 0 8 0; diff --git a/Patches/fs.fx.pd b/Patches/fs.fx.pd new file mode 100644 index 0000000..f6bedc2 --- /dev/null +++ b/Patches/fs.fx.pd @@ -0,0 +1,21 @@ +#N canvas 275 32 645 476 12; +#X obj 22 171 outlet; +#X obj 22 138 inlet; +#X text 114 91 - effects:; +#X text 130 115 mosaic ; +#X text 129 265 saturation ; +#X text 129 290 addition ; +#X text 130 313 gamma ; +#X text 130 337 contrast ; +#X text 130 361 lightness ; +#X text 130 235 without parameters: invert \, soft \, sharp \, emboss +; +#X text 129 139 rotate ; +#X text 130 163 rotozoom +; +#X text 130 190 "smooth_1" and "smooth_0" sets smoothing on/off for +rotate and rotozoom (default is on).; +#X text 9 34 (you can send these commands directly to fs.frame \, but +using fs.fx might make your patches more clear); +#X text 10 6 Yeah \, quite an abstraction!; +#X connect 1 0 0 0; diff --git a/Patches/fs.hist.pd b/Patches/fs.hist.pd new file mode 100644 index 0000000..93f875f --- /dev/null +++ b/Patches/fs.hist.pd @@ -0,0 +1,39 @@ +#N canvas 283 252 725 432 12; +#X text 13 9 fs.hist - an array of 256 elements \, where x = intensity +and y = number of colors with that intensity; +#X obj 40 70 inlet; +#X obj 40 148 pack s f s s; +#X obj 252 135 reset; +#X obj 252 161 symbol \$0hist; +#X obj 227 69 inlet; +#X text 277 70 0=red 1=green 2=blue; +#X text 94 70 fs.frame; +#X obj 252 193 makefilename c:/%s; +#X text 249 223 if you run pd and fs on separate machines \, you need +a mapped network drive to pass the data. sorry.; +#X obj 111 248 r \$0histbang; +#X msg 111 273 bang; +#X obj 40 209 fs_sender; +#X msg 40 180 \$1 hist \$2 \$3 \$4bang; +#X obj 227 96 float \$1; +#X obj 213 298 symbol \$2; +#X obj 111 304 pack f s s; +#X msg 111 348 \; \$2 read16 \$3; +#X text 220 357 2nd arg must be name of table with 256 elements.; +#X text 383 170 change c:/ to some temp-directory..; +#X connect 1 0 2 0; +#X connect 2 0 13 0; +#X connect 3 0 4 0; +#X connect 3 0 14 0; +#X connect 3 0 15 0; +#X connect 4 0 2 3; +#X connect 4 0 8 0; +#X connect 5 0 2 1; +#X connect 8 0 2 2; +#X connect 8 0 16 2; +#X connect 10 0 11 0; +#X connect 11 0 16 0; +#X connect 13 0 12 0; +#X connect 14 0 2 1; +#X connect 15 0 16 1; +#X connect 16 0 17 0; diff --git a/Patches/fs.info.pd b/Patches/fs.info.pd new file mode 100644 index 0000000..0eeb1e1 --- /dev/null +++ b/Patches/fs.info.pd @@ -0,0 +1,33 @@ +#N canvas 19 200 713 421 12; +#X obj 49 37 inlet; +#X obj 46 348 outlet; +#X obj 256 114 symbol; +#X msg 256 142 info \$1; +#X obj 49 124 pack s s; +#X text 14 7 connection from fs.frame; +#X obj 49 219 fs_sender; +#X obj 181 344 outlet; +#X obj 324 340 outlet; +#X msg 49 190 \$2 \$1 \$2width \$2height \$2framecount \$2framerate +; +#X obj 499 339 outlet; +#X obj 256 69 symbol \$0I; +#X obj 46 283 r \$0Iwidth; +#X obj 181 283 r \$0Iheight; +#X obj 324 283 r \$0Iframecount; +#X obj 499 283 r \$0Iframerate; +#X obj 256 39 reset; +#X text 47 258 report frame width \, height \, video framecount and +framerate:; +#X connect 0 0 4 0; +#X connect 2 0 3 0; +#X connect 3 0 6 0; +#X connect 4 0 9 0; +#X connect 9 0 6 0; +#X connect 11 0 2 0; +#X connect 11 0 4 1; +#X connect 12 0 1 0; +#X connect 13 0 7 0; +#X connect 14 0 8 0; +#X connect 15 0 10 0; +#X connect 16 0 11 0; diff --git a/Patches/fs.main.pd b/Patches/fs.main.pd new file mode 100644 index 0000000..845121d --- /dev/null +++ b/Patches/fs.main.pd @@ -0,0 +1,52 @@ +#N canvas 278 0 700 494 12; +#X obj 27 293 netsend; +#X floatatom 27 322 4 0 0; +#X obj 207 160 loadbang; +#X msg 206 254 disconnect; +#X msg 27 253 send \$1; +#X obj 27 203 r fs_main; +#X msg 207 185 6001; +#X obj 127 128 inlet; +#X text 175 126 port; +#X obj 127 170 t f b; +#X text 9 30 only one fs.main at a time \,; +#X text 9 46 or your commands will be doubled.; +#X obj 393 42 inlet; +#X text 439 42 reset; +#X obj 393 132 t b b; +#X msg 428 158 send reset; +#X obj 157 382 pack s f; +#X floatatom 272 378 4 0 0; +#X text 10 7 fs.main - handles communication with Framestein.; +#X msg 157 411 \; \$1 \$2; +#X text 149 291 you can run framestein and the control-patches on separate +machines by changing "localhost" to "your.windows.slave" above and +configuring fs likewise (right-click fs).; +#X msg 393 199 \; fs_reset bang; +#X obj 393 78 route reset; +#X obj 476 114 fs_sender; +#X obj 157 353 netreceive 6002; +#X msg 207 225 connect localhost \$1; +#X obj 408 385 r symbolmousedown; +#X obj 408 408 r symbolmouseup; +#X text 404 364 ignore some errors; +#X obj 408 431 r symbolfile; +#X connect 0 0 1 0; +#X connect 2 0 6 0; +#X connect 3 0 0 0; +#X connect 4 0 0 0; +#X connect 5 0 4 0; +#X connect 6 0 25 0; +#X connect 7 0 9 0; +#X connect 9 0 25 0; +#X connect 9 1 3 0; +#X connect 12 0 22 0; +#X connect 14 0 21 0; +#X connect 14 1 15 0; +#X connect 15 0 0 0; +#X connect 16 0 19 0; +#X connect 22 0 14 0; +#X connect 22 1 23 0; +#X connect 24 0 16 0; +#X connect 24 1 17 0; +#X connect 25 0 0 0; diff --git a/Patches/fs.mask.pd b/Patches/fs.mask.pd new file mode 100644 index 0000000..b17dee9 --- /dev/null +++ b/Patches/fs.mask.pd @@ -0,0 +1,39 @@ +#N canvas 484 206 513 402 10; +#X obj 33 22 inlet; +#X obj 51 200 fs.copy; +#X obj 51 351 outlet; +#X obj 115 22 inlet; +#X msg 142 166 srcand; +#X obj 51 249 fs.frame; +#X obj 51 158 symbol; +#X obj 73 116 fs.copy; +#X obj 51 287 fs.copy; +#X obj 33 79 t b b s; +#X obj 180 132 init; +#X msg 157 190 transparent_1; +#X msg 168 218 mute_1 \, hide; +#X msg 168 244 mute_0 \, show; +#X text 223 42 fs.mask -- copy with mask; +#X text 223 61 1st inlet: fs.frame to copy from; +#X text 223 76 2nd inlet: fs.frame of the mask; +#X text 241 106 outlet: output fs.frame; +#X obj 165 22 inlet; +#X text 223 91 3rd inlet: commands to the internal fs.frame; +#X connect 0 0 9 0; +#X connect 1 0 5 0; +#X connect 3 0 6 1; +#X connect 4 0 1 1; +#X connect 5 0 8 0; +#X connect 6 0 1 0; +#X connect 7 0 5 0; +#X connect 8 0 2 0; +#X connect 9 0 5 0; +#X connect 9 1 6 0; +#X connect 9 2 7 0; +#X connect 10 0 4 0; +#X connect 10 0 11 0; +#X connect 10 0 12 0; +#X connect 11 0 8 1; +#X connect 12 0 5 0; +#X connect 13 0 5 0; +#X connect 18 0 5 0; diff --git a/Patches/fs.rgb.pd b/Patches/fs.rgb.pd new file mode 100644 index 0000000..164085c --- /dev/null +++ b/Patches/fs.rgb.pd @@ -0,0 +1,31 @@ +#N canvas 46 193 827 465 12; +#X obj 53 97 inlet; +#X obj 54 386 outlet; +#X text 26 414 outputs red \, green and blue; +#X text 21 61 connection from fs.frame | x and y packed; +#X obj 244 95 inlet; +#X obj 53 241 fs_sender; +#X text 159 187 tell plugin where to send results!; +#X obj 77 343 pack f f f; +#X obj 339 150 symbol \$0rgb; +#X obj 77 310 r \$0rgbred; +#X obj 162 310 r \$0rgbgreen; +#X obj 263 310 r \$0rgbblue; +#X obj 53 164 pack s f f s; +#X msg 53 209 \$1 rgb \$2 \$3 \$4red \$4green \$4blue; +#X obj 122 132 unpack f f; +#X obj 339 126 reset; +#X text 23 16 fs.rgb -- output red \, green and blue from a given position. +; +#X connect 0 0 12 0; +#X connect 4 0 14 0; +#X connect 7 0 1 0; +#X connect 8 0 12 3; +#X connect 9 0 7 0; +#X connect 10 0 7 1; +#X connect 11 0 7 2; +#X connect 12 0 13 0; +#X connect 13 0 5 0; +#X connect 14 0 12 1; +#X connect 14 1 12 2; +#X connect 15 0 8 0; diff --git a/Patches/fs.sonogram.pd b/Patches/fs.sonogram.pd new file mode 100644 index 0000000..543e91e --- /dev/null +++ b/Patches/fs.sonogram.pd @@ -0,0 +1,63 @@ +#N canvas 143 280 484 334 12; +#X msg 188 80 bang; +#X obj 28 47 inlet~; +#X text 86 48 sound data; +#X obj 188 48 inlet; +#X text 243 49 bang to get sonogram; +#X obj 70 225 outlet; +#X text 134 224 to fs.frame; +#N canvas 211 133 544 441 writesono 0; +#X obj 46 48 inlet~; +#X obj 144 50 inlet; +#X obj 46 78 rfft~; +#X obj 46 111 *~; +#X obj 77 111 *~; +#X obj 46 141 sqrt~; +#X obj 382 17 block~ 1024 1; +#X obj 218 309 table \$0spectrum; +#X obj 46 187 tabwrite~ \$0spectrum; +#X obj 67 359 outlet; +#X obj 144 92 t b b b; +#X msg 99 308 sonogram \$1; +#X obj 218 241 symbol; +#X msg 301 51 bang; +#X obj 301 24 reset; +#X obj 99 241 symbol; +#X obj 301 106 makefilename c:/%s; +#X obj 301 77 symbol \$0sono; +#X msg 317 363 resize 128; +#X obj 366 333 reset; +#X msg 317 389 bounds 0 0 128 500; +#X msg 218 276 write \$1; +#X text 365 130 maybe c:/temp/?; +#X obj 291 276 s \$0spectrum; +#X connect 0 0 2 0; +#X connect 1 0 10 0; +#X connect 2 0 3 0; +#X connect 2 0 3 1; +#X connect 2 1 4 0; +#X connect 2 1 4 1; +#X connect 3 0 5 0; +#X connect 4 0 5 0; +#X connect 5 0 8 0; +#X connect 10 0 15 0; +#X connect 10 1 12 0; +#X connect 10 2 8 0; +#X connect 11 0 9 0; +#X connect 12 0 21 0; +#X connect 13 0 17 0; +#X connect 14 0 13 0; +#X connect 15 0 11 0; +#X connect 16 0 12 1; +#X connect 16 0 15 1; +#X connect 17 0 16 0; +#X connect 18 0 23 0; +#X connect 19 0 18 0; +#X connect 19 0 20 0; +#X connect 20 0 23 0; +#X connect 21 0 23 0; +#X restore 78 151 pd writesono; +#X connect 0 0 7 1; +#X connect 1 0 7 0; +#X connect 3 0 0 0; +#X connect 7 0 5 0; diff --git a/Patches/fs.text.pd b/Patches/fs.text.pd new file mode 100644 index 0000000..d666c99 --- /dev/null +++ b/Patches/fs.text.pd @@ -0,0 +1,29 @@ +#N canvas 90 92 825 352 12; +#X obj 172 80 loadbang; +#X obj 126 275 fs_sender; +#X obj 51 27 inlet; +#X msg 172 228 text \$1; +#X obj 172 110 symbol \$0fs.text; +#X obj 51 55 l2s; +#X obj 51 102 pack s s; +#X msg 51 137 fs_op \$2 \$1; +#X obj 51 175 outlet; +#X obj 172 203 symbol; +#X obj 189 147 r fs_reset; +#X msg 189 172 bang; +#X text 100 28 text to write \, or one of these commands:; +#X text 430 95 size ; +#X text 430 117 font (look in your /winnt/fonts-dir); +#X text 429 141 pos ; +#X text 430 73 color ; +#X connect 0 0 4 0; +#X connect 2 0 5 0; +#X connect 3 0 1 0; +#X connect 4 0 6 1; +#X connect 4 0 9 0; +#X connect 5 0 6 0; +#X connect 6 0 7 0; +#X connect 7 0 8 0; +#X connect 9 0 3 0; +#X connect 10 0 11 0; +#X connect 11 0 9 0; diff --git a/Patches/fs.waveform.pd b/Patches/fs.waveform.pd new file mode 100644 index 0000000..1b6d39a --- /dev/null +++ b/Patches/fs.waveform.pd @@ -0,0 +1,146 @@ +#N canvas 107 0 702 664 12; +#X obj 75 360 fs.frame; +#X obj 40 130 inlet; +#X obj 27 588 outlet; +#X obj 215 587 outlet; +#X obj 126 129 inlet; +#X obj 270 283 init; +#X obj 408 586 outlet; +#X obj 107 326 vdrawarray \$1; +#X obj 107 295 vframe \$2 \$3; +#X text 10 50 args: ; +#X obj 270 340 f \$2; +#X obj 306 340 f \$3; +#X obj 270 368 pack f f; +#X obj 270 310 t b b b; +#X obj 40 174 route bang; +#X obj 110 395 fs.waveselection; +#X obj 171 370 spigot; +#X obj 330 161 loadbang; +#X msg 330 186 1; +#X obj 310 128 inlet; +#X text 309 105 show selection (0 / 1); +#X text 215 612 selection in samples; +#X text 410 610 fs.frame position; +#X msg 270 395 \$1 x \$2 \, mousetrack_1 \, mouserect_1 \, flip_manual +; +#X msg 33 360 flip; +#X text 11 69 note that the fs.frame here is in flip_manual-mode; +#X text 9 5 fs.waveform - wrapper to display array in fs.frame with +selection features; +#X text 39 104 bang; +#N canvas 147 197 699 425 samples 0; +#X obj 120 50 inlet; +#X obj 172 50 inlet; +#X obj 148 324 outlet; +#X obj 202 324 outlet; +#X obj 102 153 fs.info; +#X obj 172 216 /; +#X obj 172 123 unpack f f f f; +#X obj 202 216 /; +#X obj 202 244 *; +#X obj 172 244 *; +#X obj 256 194 arraysize \$1; +#X obj 302 139 init; +#X msg 302 164 bang; +#X obj 270 52 inlet; +#X text 120 24 fs.frame; +#X text 268 24 reset to arraysize; +#X text 447 24 offsets in samples; +#X obj 452 50 inlet; +#X obj 500 50 inlet; +#X obj 481 124 -; +#X obj 481 149 abs; +#X obj 172 273 + 0; +#X obj 202 273 + 0; +#X obj 339 80 f; +#X obj 500 85 t f f; +#X obj 430 85 t b f f; +#X obj 339 108 sel 0; +#X msg 302 236 0; +#X connect 0 0 4 0; +#X connect 1 0 6 0; +#X connect 4 0 5 1; +#X connect 4 0 7 1; +#X connect 5 0 9 0; +#X connect 6 0 5 0; +#X connect 6 2 7 0; +#X connect 7 0 8 0; +#X connect 8 0 22 0; +#X connect 9 0 21 0; +#X connect 10 0 8 1; +#X connect 10 0 9 1; +#X connect 10 0 27 0; +#X connect 11 0 12 0; +#X connect 12 0 10 0; +#X connect 12 0 27 0; +#X connect 13 0 12 0; +#X connect 17 0 25 0; +#X connect 18 0 24 0; +#X connect 19 0 20 0; +#X connect 20 0 8 1; +#X connect 20 0 9 1; +#X connect 21 0 2 0; +#X connect 22 0 3 0; +#X connect 23 0 26 0; +#X connect 24 0 19 1; +#X connect 24 1 23 1; +#X connect 25 0 23 0; +#X connect 25 1 22 1; +#X connect 25 1 21 1; +#X connect 25 2 19 0; +#X connect 26 0 12 0; +#X connect 27 0 22 1; +#X connect 27 0 21 1; +#X restore 143 520 pd samples; +#X obj 123 267 vplugin; +#X msg 123 244 black; +#X obj 40 201 t b b b b b; +#X obj 184 489 minmax; +#X obj 184 463 pack f f; +#X obj 173 129 inlet; +#X text 123 104 offsets in samples; +#X obj 273 587 outlet; +#X obj 85 588 outlet; +#X text 25 613 fs.frame outlets 1&2; +#X connect 0 0 2 0; +#X connect 0 0 15 0; +#X connect 0 0 28 0; +#X connect 0 1 16 0; +#X connect 0 1 28 1; +#X connect 0 1 37 0; +#X connect 0 2 6 0; +#X connect 1 0 14 0; +#X connect 4 0 7 1; +#X connect 4 0 33 0; +#X connect 5 0 13 0; +#X connect 7 0 0 0; +#X connect 8 0 7 0; +#X connect 10 0 12 0; +#X connect 11 0 12 1; +#X connect 12 0 23 0; +#X connect 13 0 31 0; +#X connect 13 1 10 0; +#X connect 13 2 11 0; +#X connect 14 0 31 0; +#X connect 14 1 0 0; +#X connect 15 0 0 0; +#X connect 16 0 15 1; +#X connect 17 0 18 0; +#X connect 18 0 16 1; +#X connect 19 0 16 1; +#X connect 23 0 0 0; +#X connect 24 0 0 0; +#X connect 28 0 3 0; +#X connect 28 1 36 0; +#X connect 29 0 8 0; +#X connect 30 0 29 0; +#X connect 31 0 15 2; +#X connect 31 1 0 0; +#X connect 31 2 24 0; +#X connect 31 3 30 0; +#X connect 32 0 28 3; +#X connect 32 1 28 4; +#X connect 33 0 32 0; +#X connect 34 0 7 2; +#X connect 34 0 33 1; diff --git a/Patches/fs.waveselection.pd b/Patches/fs.waveselection.pd new file mode 100644 index 0000000..440e500 --- /dev/null +++ b/Patches/fs.waveselection.pd @@ -0,0 +1,47 @@ +#N canvas 0 0 626 444 12; +#X obj 188 80 inlet; +#X obj 223 279 fs.copy; +#X msg 328 296 dstinvert; +#X obj 363 324 init; +#X obj 223 376 outlet; +#X obj 21 80 inlet; +#X obj 223 219 symbol; +#X obj 188 112 t l b; +#X obj 358 79 inlet; +#X text 12 8 fs.waveselection - show fs.waveform selection by inverting +the selected area; +#X text 71 81 fs.frame 1st; +#X text 241 80 fs.frame 2nd; +#X text 410 78 reset; +#X text 280 377 to fs.frame 1st inlet; +#X obj 185 155 t b b l l; +#X msg 185 312 flip; +#X msg 289 247 source \$1 0 \$3 \$5; +#X msg 432 247 dest \$1 0 \$3 \$5; +#X obj 289 219 pack f f f f f; +#X obj 442 150 fs.info; +#X msg 358 106 0 0 0 0 0; +#X obj 432 217 pack f f f f f; +#X connect 0 0 7 0; +#X connect 1 0 4 0; +#X connect 2 0 1 1; +#X connect 3 0 2 0; +#X connect 5 0 6 1; +#X connect 5 0 19 0; +#X connect 6 0 1 0; +#X connect 7 0 14 0; +#X connect 7 1 6 0; +#X connect 8 0 20 0; +#X connect 14 0 15 0; +#X connect 14 1 6 0; +#X connect 14 2 21 0; +#X connect 14 3 18 0; +#X connect 15 0 4 0; +#X connect 16 0 1 1; +#X connect 17 0 1 1; +#X connect 18 0 16 0; +#X connect 19 1 18 4; +#X connect 19 1 21 4; +#X connect 20 0 18 0; +#X connect 20 0 21 0; +#X connect 21 0 17 0; diff --git a/Patches/fs_sender.pd b/Patches/fs_sender.pd new file mode 100644 index 0000000..e53a3b6 --- /dev/null +++ b/Patches/fs_sender.pd @@ -0,0 +1,7 @@ +#N canvas 595 435 271 174 12; +#X obj 37 13 inlet; +#X obj 37 77 s fs_main; +#X obj 93 42 print sender; +#X obj 37 43 l2s; +#X connect 0 0 3 0; +#X connect 3 0 1 0; diff --git a/Patches/init.pd b/Patches/init.pd new file mode 100644 index 0000000..7a1b9d8 --- /dev/null +++ b/Patches/init.pd @@ -0,0 +1,9 @@ +#N canvas 361 230 591 286 12; +#X obj 44 177 outlet; +#X obj 44 81 reset; +#X text 14 10 use init to set parameters at load time; +#X msg 44 152 bang; +#X obj 44 126 pipe 1000; +#X connect 1 0 4 0; +#X connect 3 0 0 0; +#X connect 4 0 3 0; diff --git a/Patches/l2s.c b/Patches/l2s.c new file mode 100644 index 0000000..b8a7701 --- /dev/null +++ b/Patches/l2s.c @@ -0,0 +1,89 @@ +/* + l2s is from ZEXY, the excellent pure data library by Johannes Zmoelnig. + Get it from ftp://iem.kug.ac.at/pd/Externals/ZEXY/ +*/ + +/* not needed #include "zexy.h" */ +#include "m_pd.h" +#include + +#ifdef NT +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) +#define sqrtf sqrt +#endif + +/* ------------------------- list2symbol ------------------------------- */ + +/* compare 2 lists ( == for lists) */ + +static t_class *list2symbol_class; + +typedef struct _list2symbol +{ + t_object x_obj; + + t_binbuf *bbuf; +} t_list2symbol; + +static void list2symbol_bang(t_list2symbol *x) +{ + char *str=0, *s2; + int n=0; + + binbuf_gettext(x->bbuf, &str, &n); + /* memory bug ! detected and fixed by Jusu */ + s2 = copybytes(str, n+1); + s2[n]=0; + + outlet_symbol(x->x_obj.ob_outlet, gensym(s2)); + freebytes(str, n); + freebytes(s2,n+1); +} + +static void list2symbol_list(t_list2symbol *x, t_symbol *s, int argc, t_atom *argv) +{ + binbuf_clear(x->bbuf); + binbuf_add(x->bbuf, argc, argv); + + list2symbol_bang(x); +} +static void list2symbol_anything(t_list2symbol *x, t_symbol *s, int argc, t_atom *argv) +{ + t_atom ap; + binbuf_clear(x->bbuf); + SETSYMBOL(&ap, s); + binbuf_add(x->bbuf, 1, &ap); + binbuf_add(x->bbuf, argc, argv); + + list2symbol_bang(x); +} + +static void *list2symbol_new(t_symbol *s, int argc, t_atom *argv) +{ + t_list2symbol *x = (t_list2symbol *)pd_new(list2symbol_class); + + outlet_new(&x->x_obj, 0); + x->bbuf = binbuf_new(); + binbuf_add(x->bbuf, argc, argv); + + return (x); +} + +static void list2symbol_free(t_list2symbol *x) +{ + binbuf_free(x->bbuf); +} + +void l2s_setup(void) +{ + list2symbol_class = class_new(gensym("l2s"), (t_newmethod)list2symbol_new, + (t_method)list2symbol_free, sizeof(t_list2symbol), 0, A_GIMME, 0); + + class_addcreator((t_newmethod)list2symbol_new, gensym("list2symbol"), A_GIMME, 0); + class_addbang (list2symbol_class, list2symbol_bang); + class_addlist (list2symbol_class, list2symbol_list); + class_addanything(list2symbol_class, list2symbol_anything); + + class_sethelpsymbol(list2symbol_class, gensym("zexy/list2symbol")); +} diff --git a/Patches/l2s.dll b/Patches/l2s.dll new file mode 100644 index 0000000..c46d150 Binary files /dev/null and b/Patches/l2s.dll differ diff --git a/Patches/l2s.exp b/Patches/l2s.exp new file mode 100644 index 0000000..18ec776 Binary files /dev/null and b/Patches/l2s.exp differ diff --git a/Patches/l2s.lib b/Patches/l2s.lib new file mode 100644 index 0000000..b875e0b Binary files /dev/null and b/Patches/l2s.lib differ diff --git a/Patches/l2s.obj b/Patches/l2s.obj new file mode 100644 index 0000000..c4e67b2 Binary files /dev/null and b/Patches/l2s.obj differ diff --git a/Patches/makefile b/Patches/makefile new file mode 100644 index 0000000..55d610f --- /dev/null +++ b/Patches/makefile @@ -0,0 +1,38 @@ +all: vframe vsig vsnapshot vrgb vcolor vframeread vdrawarray arraysize buildstr l2s + +# FLAGS: +# +# note: maximum optimization (/Ox) causes crashes with plugins.. + +F = /DNT /DPD /LD /Gd /GD /Ogitb1 /Gs /I\system\pd\src /I..\Plugins +L = \system\pdt17\bin\pd.lib + +vframe: + cl vframe.c $(F) /link /export:vframe_setup $(L) user32.lib + +vsig: + cl vsig~.c $(F) /link /export:vsig_tilde_setup $(L) + +vsnapshot: + cl vsnapshot~.c $(F) /link /export:vsnapshot_tilde_setup $(L) + +vrgb: + cl vrgb~.c $(F) /link /export:vrgb_tilde_setup $(L) user32.lib + +vcolor: + cl vcolor~.c $(F) /link /export:vcolor_tilde_setup $(L) user32.lib + +vframeread: + cl vframeread~.c $(F) /link /export:vframeread_tilde_setup $(L) + +vdrawarray: + cl vdrawarray.c $(F) /link /export:vdrawarray_setup $(L) + +arraysize: + cl arraysize.c $(F) /link /export:arraysize_setup $(L) + +buildstr: + cl buildstr.c $(F) /link /export:buildstr_setup $(L) + +l2s: + cl l2s.c $(F) /link /export:l2s_setup $(L) diff --git a/Patches/noize.dll b/Patches/noize.dll new file mode 100644 index 0000000..cdd4326 Binary files /dev/null and b/Patches/noize.dll differ diff --git a/Patches/ooo.pd b/Patches/ooo.pd new file mode 100644 index 0000000..a10612b --- /dev/null +++ b/Patches/ooo.pd @@ -0,0 +1,19 @@ +#N canvas 483 310 458 308 12; +#X obj 167 136 random 10; +#X obj 199 66 inlet; +#X obj 134 68 inlet; +#X obj 167 176 sel 0; +#X obj 167 216 outlet; +#X text 14 8 ooo - one out of ...; +#X obj 290 58 float \$1; +#X obj 302 32 loadbang; +#X obj 216 103 - 1; +#X msg 148 103 bang; +#X connect 0 0 3 0; +#X connect 1 0 8 0; +#X connect 2 0 9 0; +#X connect 3 0 4 0; +#X connect 6 0 8 0; +#X connect 7 0 6 0; +#X connect 8 0 0 1; +#X connect 9 0 0 0; diff --git a/Patches/play.pd b/Patches/play.pd new file mode 100644 index 0000000..053c019 --- /dev/null +++ b/Patches/play.pd @@ -0,0 +1,8 @@ +#N canvas 290 207 206 201 12; +#X obj 35 60 fps \$1; +#X msg 35 90 next; +#X obj 35 119 outlet; +#X obj 35 30 inlet; +#X connect 0 0 1 0; +#X connect 1 0 2 0; +#X connect 3 0 0 0; diff --git a/Patches/ramp.pd b/Patches/ramp.pd new file mode 100644 index 0000000..5f84056 --- /dev/null +++ b/Patches/ramp.pd @@ -0,0 +1,35 @@ +#N canvas 60 34 505 412 10; +#X obj 60 40 inlet; +#X text 106 40 from \, to \, steps; +#X obj 54 372 outlet; +#X text 108 373 float; +#X obj 68 77 unpack f f f; +#X obj 277 177 f; +#X obj 277 201 bangx; +#X obj 144 131 f; +#X obj 144 177 -; +#X text 175 178 to - from; +#X obj 144 204 /; +#X text 174 205 div steps; +#X obj 128 254 +; +#X obj 68 124 t b b f f; +#X obj 101 254 f; +#X obj 101 277 t f f; +#X connect 0 0 4 0; +#X connect 4 0 13 0; +#X connect 4 1 7 1; +#X connect 4 2 5 1; +#X connect 4 2 10 1; +#X connect 5 0 6 0; +#X connect 6 0 14 0; +#X connect 7 0 8 0; +#X connect 8 0 10 0; +#X connect 10 0 12 1; +#X connect 12 0 14 1; +#X connect 13 0 5 0; +#X connect 13 1 7 0; +#X connect 13 2 8 1; +#X connect 13 3 14 1; +#X connect 14 0 15 0; +#X connect 15 0 2 0; +#X connect 15 1 12 0; diff --git a/Patches/randombox.pd b/Patches/randombox.pd new file mode 100644 index 0000000..b7de22b --- /dev/null +++ b/Patches/randombox.pd @@ -0,0 +1,19 @@ +#N canvas 261 155 452 302 12; +#X obj 128 198 pack f f f f; +#X obj 128 102 random \$1; +#X obj 158 125 random \$2; +#X obj 188 148 random \$1; +#X obj 219 171 random \$2; +#X obj 128 31 inlet; +#X obj 128 67 t b b b b; +#X obj 128 235 outlet; +#X connect 0 0 7 0; +#X connect 1 0 0 0; +#X connect 2 0 0 1; +#X connect 3 0 0 2; +#X connect 4 0 0 3; +#X connect 5 0 6 0; +#X connect 6 0 1 0; +#X connect 6 1 2 0; +#X connect 6 2 3 0; +#X connect 6 3 4 0; diff --git a/Patches/reset.pd b/Patches/reset.pd new file mode 100644 index 0000000..0a33ffc --- /dev/null +++ b/Patches/reset.pd @@ -0,0 +1,8 @@ +#N canvas 365 282 350 242 12; +#X obj 44 34 loadbang; +#X obj 130 34 r fs_reset; +#X obj 60 100 outlet; +#X msg 130 60 bang; +#X connect 0 0 2 0; +#X connect 1 0 3 0; +#X connect 3 0 2 0; diff --git a/Patches/sameonce.pd b/Patches/sameonce.pd new file mode 100644 index 0000000..0d8d1f6 --- /dev/null +++ b/Patches/sameonce.pd @@ -0,0 +1,15 @@ +#N canvas 115 170 321 367 12; +#X obj 71 73 inlet; +#X obj 147 322 outlet; +#X obj 147 142 float; +#X msg 204 178 bang; +#X obj 71 200 moses 1; +#X obj 71 142 != -1; +#X text 8 6 pass float if different from previous; +#X connect 0 0 2 1; +#X connect 0 0 5 0; +#X connect 2 0 5 1; +#X connect 2 0 1 0; +#X connect 3 0 2 0; +#X connect 4 1 3 0; +#X connect 5 0 4 0; diff --git a/Patches/snapOut~.pd b/Patches/snapOut~.pd new file mode 100644 index 0000000..2712c45 --- /dev/null +++ b/Patches/snapOut~.pd @@ -0,0 +1,45 @@ +#N canvas 620 1 504 354 10; +#X obj 39 16 inlet~; +#X msg 128 134 1; +#X msg 159 134 0; +#X obj 128 162 metro 100; +#X obj 119 16 inlet; +#X text 160 15 snapout size in seconds; +#X floatatom 260 48 4 0 0; +#X obj 211 82 * 1000; +#X floatatom 209 134 4 0 0; +#X msg 54 134 bang; +#X obj 39 188 tabwrite~ \$1; +#X obj 303 132 symbol \$1; +#X obj 303 109 loadbang; +#X msg 260 186 \; \$2 resize \$1; +#X obj 260 156 pack f s; +#X obj 260 219 print; +#X obj 367 15 loadbang; +#X obj 367 37 samplerate~; +#X obj 260 82 *; +#X obj 341 69 / 100; +#X obj 260 109 -; +#X obj 119 55 switch~; +#X connect 0 0 10 0; +#X connect 1 0 3 0; +#X connect 2 0 3 0; +#X connect 3 0 10 0; +#X connect 4 0 6 0; +#X connect 4 0 21 0; +#X connect 6 0 7 0; +#X connect 6 0 18 0; +#X connect 7 0 8 0; +#X connect 8 0 3 1; +#X connect 8 0 3 0; +#X connect 9 0 10 0; +#X connect 11 0 14 1; +#X connect 12 0 11 0; +#X connect 13 0 15 0; +#X connect 14 0 13 0; +#X connect 16 0 17 0; +#X connect 17 0 18 1; +#X connect 17 0 19 0; +#X connect 18 0 20 0; +#X connect 19 0 20 1; +#X connect 20 0 14 0; diff --git a/Patches/vcolor~.c b/Patches/vcolor~.c new file mode 100644 index 0000000..0de7fe6 --- /dev/null +++ b/Patches/vcolor~.c @@ -0,0 +1,96 @@ +#include "m_pd.h" +#include "math.h" +#include "sharemem.h" +#include "vframe.h" +#include "plugin.h" +#include "displaydepth.h" + +/* -------------------------- vcolor~ ------------------------------ */ +static t_class *vcolor_class; + +typedef struct _vcolor +{ + t_object x_obj; + float x_r; + float x_g; + float x_b; + int depth; +} t_vcolor; + +static t_int *vcolor_perform(t_int *w) +{ + t_float *in_r = (t_float *)(w[1]); + t_float *in_g = (t_float *)(w[2]); + t_float *in_b = (t_float *)(w[3]); + t_float *out = (t_float *)(w[4]); + int n = (int)(w[5]); + t_vcolor *x = (t_vcolor *)(w[6]); + + switch(x->depth) + { + case 16: + while (n--) + { + *out++ = colortosample16(rgbtocolor16( + (byte)(*in_r++*255.0), + (byte)(*in_g++*255.0), + (byte)(*in_b++*255.0) + )); + } + break; + case 32: + while (n--) + { + *out++ = colortosample32(rgbtocolor32( + (byte)(*in_r++*255.0), + (byte)(*in_g++*255.0), + (byte)(*in_b++*255.0))); + } + break; + } + return (w+7); +} + +static void vcolor_dsp(t_vcolor *x, t_signal **sp) +{ + dsp_add(vcolor_perform, 6, + sp[0]->s_vec, + sp[1]->s_vec, + sp[2]->s_vec, + sp[3]->s_vec, + sp[0]->s_n, + x); +} + +static void vcolor_float(t_vcolor *x, t_float f) +{ +} + +static void *vcolor_new(t_floatarg f) +{ + t_vcolor *x = (t_vcolor *)pd_new(vcolor_class); + x->depth = getdisplaydepth(); + if(!x->depth) + { + post("vcolor~: getdisplaydepth() failed, defaulting to 16."); + x->depth = 16; + } + inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("signal"), gensym("signal")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("signal"), gensym("signal")); + outlet_new(&x->x_obj, gensym("signal")); + return (x); +} + +static void vcolor_destroy(t_vcolor *x) +{ +} + +void vcolor_tilde_setup(void) +{ + vcolor_class = class_new(gensym("vcolor~"), + (t_newmethod)vcolor_new, (t_method)vcolor_destroy, + sizeof(t_vcolor), 0, A_DEFFLOAT, 0); + CLASS_MAINSIGNALIN(vcolor_class, t_vcolor, x_r); + class_addfloat(vcolor_class, (t_method)vcolor_float); + class_addmethod(vcolor_class, (t_method)vcolor_dsp, gensym("dsp"), 0); +} diff --git a/Patches/vcolor~.dll b/Patches/vcolor~.dll new file mode 100644 index 0000000..ba9ff30 Binary files /dev/null and b/Patches/vcolor~.dll differ diff --git a/Patches/vcolor~.exp b/Patches/vcolor~.exp new file mode 100644 index 0000000..f07ba8c Binary files /dev/null and b/Patches/vcolor~.exp differ diff --git a/Patches/vcolor~.lib b/Patches/vcolor~.lib new file mode 100644 index 0000000..6092fa3 Binary files /dev/null and b/Patches/vcolor~.lib differ diff --git a/Patches/vcolor~.obj b/Patches/vcolor~.obj new file mode 100644 index 0000000..80e68ad Binary files /dev/null and b/Patches/vcolor~.obj differ diff --git a/Patches/vcopy.pd b/Patches/vcopy.pd new file mode 100644 index 0000000..00e109d --- /dev/null +++ b/Patches/vcopy.pd @@ -0,0 +1,16 @@ +#N canvas 471 263 464 314 12; +#X obj 46 27 inlet; +#X obj 97 211 outlet; +#X obj 235 27 inlet; +#X obj 235 57 l2s; +#X obj 196 91 vplugin; +#X obj 97 125 pack f s; +#X obj 324 32 reset; +#X msg 324 58 black; +#X connect 0 0 5 0; +#X connect 2 0 3 0; +#X connect 3 0 4 0; +#X connect 4 0 5 1; +#X connect 5 0 1 0; +#X connect 6 0 7 0; +#X connect 7 0 4 0; diff --git a/Patches/vdrawarray.c b/Patches/vdrawarray.c new file mode 100644 index 0000000..fa8fab7 --- /dev/null +++ b/Patches/vdrawarray.c @@ -0,0 +1,131 @@ +#include "m_pd.h" +#include "math.h" +#include "sharemem.h" +#include "vframe.h" + +/* -------------------------- vdrawarray ------------------------------ */ +static t_class *vdrawarray_class; + +typedef struct _vdrawarray +{ + t_object x_obj; + t_symbol *array_name; + t_float startpos, endpos; + int id; + HANDLE hvf, hbits; + LPVOID memvf, membits; + struct vframeimage *vfp; +} t_vdrawarray; + +void vdrawarray_set(t_vdrawarray *x, t_symbol *s) +{ + x->array_name = s; +} + +static void vdrawarray_bang(t_vdrawarray *x) +{ + int i, o, h, y, bytesize, gsize, pos, len; + t_float *gdata, tmpf; + byte *p; + t_garray *g; + + if(!x->id) + { + post("vdrawarray: connect vframe first"); + return; + } + + if(!(g = (t_garray *)pd_findbyclass(x->array_name, garray_class))) + { + pd_error(x, "vdrawarray: %s: no such table", x->array_name->s_name); + return; + } + + garray_getfloatarray(g, &gsize, &gdata); + + h = x->vfp->f.height; + p = (byte*)x->membits; + bytesize = x->vfp->f.pixelformat/8; + + if(x->startpos==0 && x->endpos==0) + x->endpos=gsize; + + if(x->startpos<0) x->startpos=0; + if(x->startpos>gsize) x->startpos=gsize; + if(x->endpos<0) x->endpos=0; + if(x->endpos>gsize) x->endpos=gsize; + + if(x->endposstartpos) + { + tmpf = x->endpos; + x->endpos = x->startpos; + x->startpos = tmpf; + } + + for(i=0; ivfp->f.width; i++) + { + pos = (int)((i / (float)x->vfp->f.width) * (x->endpos-x->startpos) + x->startpos ); + len = (int)((fabs(gdata[pos]) * (float)x->vfp->f.height)); + + o = (x->vfp->f.height - len) / 2; + for(y=o; yvfp->f.height; y++) + memset(&p[y*x->vfp->f.lpitch+i*bytesize], 253, bytesize); + } +} + +static void vdrawarray_float(t_vdrawarray *x, t_float f) +{ + if(x->id==f && x->membits!=NULL) + { + outlet_float(x->x_obj.ob_outlet, x->id); + vdrawarray_bang(x); + return; + } + + x->id = f; + + openframedatabyid(x->id, + &x->hvf, &x->hbits, &x->memvf, &x->membits, &x->vfp); + if(!x->membits) + { + post("vdrawarray: no memory at %d", x->id); + return; + } else + { + outlet_float(x->x_obj.ob_outlet, x->id); + vdrawarray_bang(x); + } +} + +static void *vdrawarray_new(t_symbol *s) +{ + t_vdrawarray *x = (t_vdrawarray *)pd_new(vdrawarray_class); + + x->array_name = s; + x->id=0; + x->hvf=NULL; + x->memvf=NULL; + x->hbits=NULL; + x->membits=NULL; + x->startpos=x->endpos=0; + outlet_new(&x->x_obj, gensym("float")); + floatinlet_new(&x->x_obj, &x->startpos); + floatinlet_new(&x->x_obj, &x->endpos); + return (x); +} + +static void vdrawarray_destroy(t_vdrawarray *x) +{ + if(x->membits!=NULL) smfree(&x->hbits, x->membits); + if(x->memvf!=NULL) smfree(&x->hvf, x->memvf); +} + +void vdrawarray_setup(void) +{ + vdrawarray_class = class_new(gensym("vdrawarray"), + (t_newmethod)vdrawarray_new, (t_method)vdrawarray_destroy, + sizeof(t_vdrawarray), 0, A_DEFSYM, 0); + class_addfloat(vdrawarray_class, (t_method)vdrawarray_float); + class_addbang(vdrawarray_class, (t_method)vdrawarray_bang); + class_addmethod(vdrawarray_class, (t_method)vdrawarray_set, gensym("set"), A_DEFSYM, 0); +} diff --git a/Patches/vdrawarray.dll b/Patches/vdrawarray.dll new file mode 100644 index 0000000..f14883b Binary files /dev/null and b/Patches/vdrawarray.dll differ diff --git a/Patches/vdrawarray.exp b/Patches/vdrawarray.exp new file mode 100644 index 0000000..00b8adf Binary files /dev/null and b/Patches/vdrawarray.exp differ diff --git a/Patches/vdrawarray.lib b/Patches/vdrawarray.lib new file mode 100644 index 0000000..53139da Binary files /dev/null and b/Patches/vdrawarray.lib differ diff --git a/Patches/vdrawarray.obj b/Patches/vdrawarray.obj new file mode 100644 index 0000000..bf12d3c Binary files /dev/null and b/Patches/vdrawarray.obj differ diff --git a/Patches/vframe.c b/Patches/vframe.c new file mode 100644 index 0000000..ee1bf37 --- /dev/null +++ b/Patches/vframe.c @@ -0,0 +1,262 @@ +#include +#include +#include "m_pd.h" +#include "sharemem.h" +#include "vframe.h" +#include "dllcall.h" +#include "displaydepth.h" + +/* vframe */ + +static t_class *vframe_class; + +typedef struct _vframe +{ + t_object x_obj; + + int id; + HANDLE hlvframe, hlbits; + LPVOID memvframe, membits; + + HMODULE effectlib, copylib; + cdecl FARPROC effectproc, copyproc; + char effectplugin[80], effectloaded[80], + copyplugin[80], copyloaded[80]; + char effectparams[256]; +} t_vframe; + +static void vframe_effect(t_vframe *x) +{ + struct vframeimage *vfp; + byte *bp; + int i1, i2, i3, i4; + char *s1=0, s2[256]; + + if(!x->membits) + { + post("vframe: init has failed."); + return; + } + if(!x->effectplugin) return; + if(strcmp(x->effectloaded, x->effectplugin)) + { + loadeffect(&x->effectlib, &x->effectproc, x->effectplugin); + if(!x->effectlib || !x->effectproc) + { + post("vframe: failed to load effect from %s", x->effectplugin); + strcpy(x->effectloaded, "-"); + return; + } + strcpy(x->effectloaded, x->effectplugin); + } + vfp = x->memvframe; + bp = x->membits; + i1 = vfp->f.lpitch; + i2 = vfp->f.width; + i3 = vfp->f.height; + i4 = vfp->f.pixelformat; + + (*x->effectproc)(bp, i1, i2, i3, i4, &x->effectparams, &s2); + outlet_float(x->x_obj.ob_outlet, x->id); +} + +static void vframe_copy(t_vframe *x, float source, char *cmd) +{ + char *t, *args=0; + HANDLE h1, h2; + LPVOID p1=NULL, p2=NULL; + struct vframeimage *vfp1=NULL, *vfp2=NULL; + byte *b1, *b2; + int i1, i2, i3, i4, i5, i6, i7, i8; + char returnbuf[256]; + + if(!x->membits) + { + post("vframe: init has failed."); + return; + } + strcpy(x->copyplugin, cmd); + t = strstr(x->copyplugin, " "); + if(t) + { + t[0]=0; + args=t+1; + } + + if(!x->copyplugin) return; + if(strcmp(x->copyloaded, x->copyplugin)) + { + loadcopy(&x->copylib, &x->copyproc, x->copyplugin); + if(!x->copylib || !x->copyproc) + { + post("vframe: failed to load copy from %s", x->copyplugin); + strcpy(x->copyloaded, "-"); + return; + } + strcpy(x->copyloaded, x->copyplugin); + } + + p2 = openframedatabyid((int)source, &h1, &h2, &p1, &p2, &vfp1); + if(!p2) + { + if(source) post("vframe: no memory at %f", source); + return; + } + + vfp2 = (struct vframeimage *)x->memvframe; + + b1 = p2; + i1 = vfp1->f.lpitch; + i2 = vfp1->f.width; + i3 = vfp1->f.height; + i4 = vfp1->f.pixelformat; + + b2 = x->membits; + i5 = vfp2->f.lpitch; + i6 = vfp2->f.width; + i7 = vfp2->f.height; + i8 = vfp2->f.pixelformat; + + (*x->copyproc)( + b1, i1, i2, i3, i4, + b2, i5, i6, i7, i8, + args, &returnbuf + ); + + outlet_float(x->x_obj.ob_outlet, x->id); +} + +static void vframe_float(t_vframe *x, t_float f) +{ + post("float %f", f); +} + +static void vframe_symbol(t_vframe *x, t_symbol *s) +{ + char *t; + + strcpy(x->effectplugin, s->s_name); + x->effectparams[0]=0; + + t = strstr(x->effectplugin, " "); + if(t) + { + strcpy(x->effectparams, t+1); + t[0]=0; + } + vframe_effect(x); +} + +static void vframe_list(t_vframe *x, t_symbol *s, int ac, t_atom *av) +{ + float f; + char *s2; + if (!ac || ac!=2) return; + + f = atom_getfloatarg(0, ac, av); + s2 = atom_getsymbolarg(1, ac, av)->s_name; + vframe_copy(x, f, s2); +} + +static void vframe_anything(t_vframe *x, t_symbol *s, int argc, t_atom *argv) +{ + char *t; + + strcpy(x->effectplugin, s->s_name); + x->effectparams[0]=0; + + t = strstr(x->effectplugin, " "); + if(t) + { + strcpy(x->effectparams, t+1); + t[0]=0; + } + vframe_effect(x); +} + +static void vframe_bang(t_vframe *x, t_floatarg fa) +{ + if(x->membits!=NULL) + outlet_float(x->x_obj.ob_outlet, x->id); +} + +static void *vframe_new(t_symbol *sym, int argc, t_atom *argv) +{ + t_vframe *x = (t_vframe *)pd_new(vframe_class); + + struct vframeimage vf; + int width=176, height=144, pixelformat=16; + char s[20]; + + if(argc>=2) + { + width = atom_getfloat(argv); + height = atom_getfloat(argv+1); + } + pixelformat = getdisplaydepth(); + if(pixelformat!=16 && pixelformat!=24 && pixelformat!=32) + { + post("vframe: bad display depth, should be 16, 24 or 32. defaulting to 16."); + pixelformat = 16; + } + + // allocate shared memory for bits and struct frameimage + x->id = rand(); + itoa(x->id, s, 10); + + x->membits = smalloc(&x->hlbits, s, width*height*(pixelformat/8)); + if(x->membits==NULL) + { + post("vframe: membits smalloc() failed."); + } else + { + strcpy(vf.bitsname, s); + vf.f.width = width; + vf.f.height = height; + vf.f.pixelformat = pixelformat; + vf.f.lpitch = vf.f.width*(pixelformat/8); /* + some more for directx-crap??? */ + vf.f.bits=NULL; + + x->id = rand(); + itoa(x->id, s, 10); + + x->memvframe = smalloc(&x->hlvframe, s, + sizeof(struct vframeimage)); + + if(x->memvframe==NULL) + { + post("vframeimage smalloc() failed."); + } else + { + memcpy(x->memvframe, &vf, sizeof(struct vframeimage)); + } + } + + x->effectlib=NULL; + strcpy(x->effectloaded, "n o t h i n g"); + x->copylib=NULL; + strcpy(x->copyloaded, "n o t h i n g"); + + outlet_new(&x->x_obj, gensym("float")); + return((void *)x); +} + +static void vframe_destroy(t_vframe *x) +{ + if(x->membits!=NULL) smfree(&x->hlbits, x->membits); + if(x->memvframe!=NULL) smfree(&x->hlvframe, x->memvframe); + if(x->effectlib) FreeLibrary(x->effectlib); + if(x->copylib) FreeLibrary(x->copylib); +} + +void vframe_setup(void) +{ + vframe_class = class_new(gensym("vframe"), + (t_newmethod)vframe_new, (t_method)vframe_destroy, + sizeof(t_vframe), CLASS_DEFAULT, A_GIMME, 0); + class_addfloat(vframe_class, vframe_float); + class_addbang(vframe_class, vframe_bang); + class_addsymbol(vframe_class, vframe_symbol); + class_addanything(vframe_class, vframe_anything); + class_addlist(vframe_class, vframe_list); +} diff --git a/Patches/vframe.dll b/Patches/vframe.dll new file mode 100644 index 0000000..677c448 Binary files /dev/null and b/Patches/vframe.dll differ diff --git a/Patches/vframe.exp b/Patches/vframe.exp new file mode 100644 index 0000000..de5412f Binary files /dev/null and b/Patches/vframe.exp differ diff --git a/Patches/vframe.h b/Patches/vframe.h new file mode 100644 index 0000000..232b166 --- /dev/null +++ b/Patches/vframe.h @@ -0,0 +1,66 @@ +#ifndef __VFRAME_H +#define __VFRAME_H + +#include "plugin.h" + +struct vframeimage +{ + char bitsname[40]; // name of shared memory to image data + // use this, not f.bits! + _frame f; // image header, see Plugins\plugin.h +}; + +LPVOID openframedatabyid( int id, + HANDLE *hvf, HANDLE *hbits, + LPVOID *memvf, LPVOID *membits, + struct vframeimage **vfp ) +{ + char s[80]; + + if(*membits!=NULL) smfree(hbits, *membits); + if(*memvf!=NULL) smfree(hvf, *memvf); + + *membits=NULL; + + itoa(id, s, 10); + + *memvf = smopen(hvf, s); + if(*memvf!=NULL) + { + *vfp = *memvf; + + *membits = smopen(hbits, ((struct vframeimage *)*vfp)->bitsname); + if(*membits==NULL) + { + printf("membits open error.\n"); + smfree(hvf, *memvf); + } else { + } + } + return(*membits); +} + +float max16 = 2<<14; +float max32 = 2<<23; + +__inline float colortosample16(short c) +{ + return(c / max16); +} + +__inline float colortosample32(long c) +{ + return(c / max32); +} + +__inline short sampletocolor16(float s) +{ + return(s * max16); +} + +__inline long sampletocolor32(float s) +{ + return(s * max32); +} + +#endif diff --git a/Patches/vframe.lib b/Patches/vframe.lib new file mode 100644 index 0000000..f03cc5a Binary files /dev/null and b/Patches/vframe.lib differ diff --git a/Patches/vframe.obj b/Patches/vframe.obj new file mode 100644 index 0000000..9f6f8cc Binary files /dev/null and b/Patches/vframe.obj differ diff --git a/Patches/vframeread~.c b/Patches/vframeread~.c new file mode 100644 index 0000000..fe61836 --- /dev/null +++ b/Patches/vframeread~.c @@ -0,0 +1,123 @@ +#include "m_pd.h" +#include "math.h" +#include "sharemem.h" +#include "vframe.h" + +/* -------------------------- vframeread~ ------------------------------ */ +static t_class *vframeread_class; + +typedef struct _vframeread +{ + t_object x_obj; + float x_f; + float x_sigf; + int id; + HANDLE hvf, hbits; + LPVOID memvf, membits; + unsigned long pos, size; +} t_vframeread; + +static t_int *vframeread_perform(t_int *w) +{ + t_vframeread *x = (t_vframeread *)(w[1]); + t_float *in_sync = (t_float *)(w[2]); + t_float *out = (t_float *)(w[3]); + int n = (int)(w[4]); + short *p16; + long *p32; + struct vframeimage *vfp=x->memvf; + unsigned long bytespp; + + if(!vfp || !x->membits) return(w+5); + + bytespp = vfp->f.pixelformat / 8; + + switch(vfp->f.pixelformat) + { + case 16: + p16 = (short *)x->membits; + while (n--) + { + if(*in_sync>=0 && *in_sync<=1) + x->pos = *in_sync * (float)(x->size / bytespp); + in_sync++; + *out++ = colortosample16(p16[x->pos++]); + if(x->pos*bytespp >= x->size) + x->pos=0; + } + break; + case 32: + p32 = (long *)x->membits; + while (n--) + { + if(*in_sync>=0 && *in_sync<1) + x->pos = *in_sync * (float)(x->size / bytespp); + in_sync++; + *out++ = colortosample32(p32[x->pos++]); + if(x->pos*bytespp >= x->size) + x->pos=0; + } + break; + } + return (w+5); +} + +static void vframeread_dsp(t_vframeread *x, t_signal **sp) +{ + dsp_add(vframeread_perform, 4, + x, + sp[0]->s_vec, + sp[1]->s_vec, + sp[0]->s_n); +} + +static void vframeread_float(t_vframeread *x, t_float f) +{ + struct vframeimage *vfp; + + if(x->id==f && x->membits) return; + + x->id = x->x_f = f; + + openframedatabyid(x->id, + &x->hvf, &x->hbits, &x->memvf, &x->membits, &vfp); + if(!x->membits) + { + post("vframeread~: no memory at %d", x->id); + return; + } else + { + x->size = vfp->f.height*vfp->f.lpitch; + x->pos = 0; + } +} + +static void *vframeread_new(t_floatarg f) +{ + t_vframeread *x = (t_vframeread *)pd_new(vframeread_class); + x->id = -1; + x->x_f = f; + x->x_sigf = 0; + x->hvf=NULL; + x->memvf=NULL; + x->hbits=NULL; + x->membits=NULL; + outlet_new(&x->x_obj, gensym("signal")); + return (x); +} + +static void vframeread_destroy(t_vframeread *x) +{ + if(x->membits!=NULL) smfree(&x->hbits, x->membits); + if(x->memvf!=NULL) smfree(&x->hvf, x->memvf); +} + +void vframeread_tilde_setup(void) +{ + vframeread_class = class_new(gensym("vframeread~"), + (t_newmethod)vframeread_new, (t_method)vframeread_destroy, + sizeof(t_vframeread), 0, A_DEFFLOAT, 0); + CLASS_MAINSIGNALIN(vframeread_class, t_vframeread, x_sigf); + class_addfloat(vframeread_class, (t_method)vframeread_float); + class_addmethod(vframeread_class, (t_method)vframeread_dsp, gensym("dsp"), 0); +} diff --git a/Patches/vframeread~.dll b/Patches/vframeread~.dll new file mode 100644 index 0000000..c433e65 Binary files /dev/null and b/Patches/vframeread~.dll differ diff --git a/Patches/vframeread~.exp b/Patches/vframeread~.exp new file mode 100644 index 0000000..ca173e8 Binary files /dev/null and b/Patches/vframeread~.exp differ diff --git a/Patches/vframeread~.lib b/Patches/vframeread~.lib new file mode 100644 index 0000000..c5e2974 Binary files /dev/null and b/Patches/vframeread~.lib differ diff --git a/Patches/vframeread~.obj b/Patches/vframeread~.obj new file mode 100644 index 0000000..72813aa Binary files /dev/null and b/Patches/vframeread~.obj differ diff --git a/Patches/videoscrub.pd b/Patches/videoscrub.pd new file mode 100644 index 0000000..00c304b --- /dev/null +++ b/Patches/videoscrub.pd @@ -0,0 +1,29 @@ +#N canvas 306 359 496 310 12; +#X obj 43 24 inlet; +#X text 97 25 fs.frame; +#X obj 55 67 fs.info; +#X obj 36 231 outlet; +#X text 100 231 fs.frame (same as inlet!); +#X msg 204 193 mousetrack_1; +#X obj 213 26 inlet; +#X text 268 26 second outlet of fs.frame; +#X obj 213 66 unpack f f; +#X obj 36 118 /; +#X obj 36 151 *; +#X msg 36 181 seek \$1; +#X obj 188 159 init; +#X floatatom 102 121 5 0 0; +#X floatatom 151 121 5 0 0; +#X connect 0 0 2 0; +#X connect 2 0 9 1; +#X connect 2 0 13 0; +#X connect 2 2 10 1; +#X connect 2 2 14 0; +#X connect 5 0 3 0; +#X connect 6 0 8 0; +#X connect 8 0 9 0; +#X connect 9 0 10 0; +#X connect 10 0 11 0; +#X connect 11 0 3 0; +#X connect 12 0 3 0; +#X connect 12 0 5 0; diff --git a/Patches/vimport.pd b/Patches/vimport.pd new file mode 100644 index 0000000..08433db --- /dev/null +++ b/Patches/vimport.pd @@ -0,0 +1,11 @@ +#N canvas 257 346 509 298 12; +#X obj 46 39 inlet; +#X obj 313 41 inlet; +#X text 21 12 fs.frame to import from; +#X text 292 14 vframe to import to; +#X obj 179 122 pack s f; +#X text 329 192 import plugin; +#X msg 179 182 \; \$1inlet fs2vf \$2; +#X connect 0 0 4 0; +#X connect 1 0 4 1; +#X connect 4 0 6 0; diff --git a/Patches/vplugin.pd b/Patches/vplugin.pd new file mode 100644 index 0000000..1639dfa --- /dev/null +++ b/Patches/vplugin.pd @@ -0,0 +1,9 @@ +#N canvas 0 0 464 314 12; +#X obj 70 26 inlet; +#X obj 70 172 makefilename c:/lab/framestein/plugins/%s; +#X obj 70 272 outlet; +#X text 125 200 correct this path to your installation; +#X obj 70 142 l2s; +#X connect 0 0 4 0; +#X connect 1 0 2 0; +#X connect 4 0 1 0; diff --git a/Patches/vref.pd b/Patches/vref.pd new file mode 100644 index 0000000..452d36a --- /dev/null +++ b/Patches/vref.pd @@ -0,0 +1,10 @@ +#N canvas 529 226 471 302 12; +#X obj 61 95 inlet; +#X obj 133 95 inlet; +#X obj 101 151 f; +#X obj 101 203 outlet; +#X text 10 5 vref: reference to vframe. use this to make your patches +more clear.; +#X connect 0 0 2 0; +#X connect 1 0 2 1; +#X connect 2 0 3 0; diff --git a/Patches/vrgb~.c b/Patches/vrgb~.c new file mode 100644 index 0000000..d4e2cec --- /dev/null +++ b/Patches/vrgb~.c @@ -0,0 +1,117 @@ +#include "m_pd.h" +#include "math.h" +#include "sharemem.h" +#include "vframe.h" +#include "plugin.h" +#include "displaydepth.h" + +/* -------------------------- vrgb~ ------------------------------ */ +static t_class *vrgb_class; + +typedef struct _vrgb +{ + t_object x_obj; + float x_f; + float mode; /* 0=rgb 1=r ... */ + int depth; +} t_vrgb; + +static t_int *vrgb_perform(t_int *w) +{ + t_float *in = (t_float *)(w[1]); + t_float *r = (t_float *)(w[2]); + t_float *g = (t_float *)(w[3]); + t_float *b = (t_float *)(w[4]); + int n = (int)(w[5]); + t_vrgb *x = (t_vrgb *)(w[6]); + byte cr, cg, cb; + short c16; + long c32; + + // support "x->mode" later.... + + switch(x->depth) + { + case 16: + while (n--) + { + c16 = sampletocolor16(*in++); + cr = r16(c16); + cg = g16(c16); + cb = b16(c16); + *r++ = cr / 255.0; + *g++ = cg / 255.0; + *b++ = cb / 255.0; + +/* *r++ = colortosample16(rgbtocolor16(cr, 0, 0)); + *g++ = colortosample16(rgbtocolor16(0, cg, 0)); + *b++ = colortosample16(rgbtocolor16(0, 0, cb)); +*/ } + break; + case 32: + while (n--) + { + c32 = sampletocolor32(*in++); + cr = r32(c32); + cg = g32(c32); + cb = b32(c32); + *r++ = cr / 255.0; + *g++ = cg / 255.0; + *b++ = cb / 255.0; + +/* *b++ = colortosample32(rgbtocolor32(cr, 0, 0)); + *g++ = colortosample32(rgbtocolor32(0, cg, 0)); + *r++ = colortosample32(rgbtocolor32(0, 0, cb)); +*/ } + break; + } + return (w+7); +} + +static void vrgb_dsp(t_vrgb *x, t_signal **sp) +{ + dsp_add(vrgb_perform, 6, + sp[0]->s_vec, + sp[1]->s_vec, + sp[2]->s_vec, + sp[3]->s_vec, + sp[0]->s_n, + x); +} + +static void vrgb_float(t_vrgb *x, t_float f) +{ + x->mode = f; +post("mode %f", f); +} + +static void *vrgb_new(t_floatarg f) +{ + t_vrgb *x = (t_vrgb *)pd_new(vrgb_class); + x->x_f = f; + x->mode=0; + x->depth = getdisplaydepth(); + if(!x->depth) + { + post("vrgb~: getdisplaydepth() failed, defaulting to 16."); + x->depth = 16; + } + outlet_new(&x->x_obj, gensym("signal")); + outlet_new(&x->x_obj, gensym("signal")); + outlet_new(&x->x_obj, gensym("signal")); + return (x); +} + +static void vrgb_destroy(t_vrgb *x) +{ +} + +void vrgb_tilde_setup(void) +{ + vrgb_class = class_new(gensym("vrgb~"), + (t_newmethod)vrgb_new, (t_method)vrgb_destroy, + sizeof(t_vrgb), 0, A_DEFFLOAT, 0); + CLASS_MAINSIGNALIN(vrgb_class, t_vrgb, x_f); + class_addfloat(vrgb_class, (t_method)vrgb_float); + class_addmethod(vrgb_class, (t_method)vrgb_dsp, gensym("dsp"), 0); +} diff --git a/Patches/vrgb~.dll b/Patches/vrgb~.dll new file mode 100644 index 0000000..dba660b Binary files /dev/null and b/Patches/vrgb~.dll differ diff --git a/Patches/vrgb~.exp b/Patches/vrgb~.exp new file mode 100644 index 0000000..431dc6d Binary files /dev/null and b/Patches/vrgb~.exp differ diff --git a/Patches/vrgb~.lib b/Patches/vrgb~.lib new file mode 100644 index 0000000..49d8fdb Binary files /dev/null and b/Patches/vrgb~.lib differ diff --git a/Patches/vrgb~.obj b/Patches/vrgb~.obj new file mode 100644 index 0000000..a49f96d Binary files /dev/null and b/Patches/vrgb~.obj differ diff --git a/Patches/vsig~.c b/Patches/vsig~.c new file mode 100644 index 0000000..f177723 --- /dev/null +++ b/Patches/vsig~.c @@ -0,0 +1,123 @@ +#include "m_pd.h" +#include "math.h" +#include "sharemem.h" +#include "vframe.h" + +/* -------------------------- vsig~ ------------------------------ */ +static t_class *vsig_class; + +typedef struct _vsig +{ + t_object x_obj; + float x_f; + t_outlet *x_bang; + int id; + HANDLE hvf, hbits; + LPVOID memvf, membits; + unsigned long pos, size; +} t_vsig; + +static t_int *vsig_perform(t_int *w) +{ + t_vsig *x = (t_vsig *)(w[1]); + t_float *out = (t_float *)(w[2]); + t_float *sync = (t_float *)(w[3]); + int n = (int)(w[4]); + short *p16; + long *p32; + struct vframeimage *vfp=x->memvf; + int bitspp; + + if(!vfp || !x->membits) return(w+5); + + bitspp = vfp->f.pixelformat / 8; + + switch(vfp->f.pixelformat) + { + case 16: + p16 = (short *)x->membits; + while (n--) + { + *out++ = colortosample16(p16[x->pos++]); + if(x->pos*bitspp >= x->size) + { + x->pos=0; + *sync = 1; // moveto topleft + outlet_bang(x->x_bang); + } else *sync = -1; // continue from whereever you are + sync++; + } + break; + case 32: + p32 = (long *)x->membits; + while (n--) + { + *out++ = colortosample32(p32[x->pos++]); + if(x->pos*bitspp >= x->size) + { + x->pos=0; + *sync = 1; + outlet_bang(x->x_bang); + } else *sync = -1; + sync++; + } + break; + } + return (w+5); +} + +static void vsig_dsp(t_vsig *x, t_signal **sp) +{ + dsp_add(vsig_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n); +} + +static void vsig_float(t_vsig *x, t_float f) +{ + struct vframeimage *vfp; + + if(x->id==f && x->membits!=NULL) return; + + x->id = x->x_f = f; + + openframedatabyid(x->id, + &x->hvf, &x->hbits, &x->memvf, &x->membits, &vfp); + if(!x->membits) + { + post("vsig~: no memory at %d", x->id); + return; + } else + { + x->size = vfp->f.height*vfp->f.lpitch; + x->pos = 0; + } +} + +static void *vsig_new(t_floatarg f) +{ + t_vsig *x = (t_vsig *)pd_new(vsig_class); + x->id = -1; + x->x_f = f; + x->hvf=NULL; + x->memvf=NULL; + x->hbits=NULL; + x->membits=NULL; + outlet_new(&x->x_obj, gensym("signal")); + outlet_new(&x->x_obj, gensym("signal")); + x->x_bang = outlet_new(&x->x_obj, gensym("bang")); + return (x); +} + +static void vsig_destroy(t_vsig *x) +{ + if(x->membits!=NULL) smfree(&x->hbits, x->membits); + if(x->memvf!=NULL) smfree(&x->hvf, x->memvf); +} + +void vsig_tilde_setup(void) +{ + vsig_class = class_new(gensym("vsig~"), + (t_newmethod)vsig_new, (t_method)vsig_destroy, + sizeof(t_vsig), 0, A_DEFFLOAT, 0); + class_addfloat(vsig_class, (t_method)vsig_float); + class_addmethod(vsig_class, (t_method)vsig_dsp, gensym("dsp"), 0); +} diff --git a/Patches/vsig~.dll b/Patches/vsig~.dll new file mode 100644 index 0000000..554cdfe Binary files /dev/null and b/Patches/vsig~.dll differ diff --git a/Patches/vsig~.exp b/Patches/vsig~.exp new file mode 100644 index 0000000..26db989 Binary files /dev/null and b/Patches/vsig~.exp differ diff --git a/Patches/vsig~.lib b/Patches/vsig~.lib new file mode 100644 index 0000000..fa4c919 Binary files /dev/null and b/Patches/vsig~.lib differ diff --git a/Patches/vsig~.obj b/Patches/vsig~.obj new file mode 100644 index 0000000..ba38233 Binary files /dev/null and b/Patches/vsig~.obj differ diff --git a/Patches/vsnapshot~.c b/Patches/vsnapshot~.c new file mode 100644 index 0000000..ba5e980 --- /dev/null +++ b/Patches/vsnapshot~.c @@ -0,0 +1,139 @@ +#include "m_pd.h" +#include "math.h" +#include "sharemem.h" +#include "vframe.h" + +/* -------------------------- vsnapshot~ ------------------------------ */ +static t_class *vsnapshot_class; + +typedef struct _vsnapshot +{ + t_object x_obj; + float x_f; + int id; + HANDLE hvf, hbits; + LPVOID memvf, membits; + unsigned long pos, size; +} t_vsnapshot; + +static t_int *vsnapshot_perform(t_int *w) +{ + t_vsnapshot *x = (t_vsnapshot *)(w[1]); + t_float *in = (t_sample *)(w[2]); + t_float *sync = (t_sample *)(w[3]); + int n = (int)(w[4]); + short *p16; + long *p32; + struct vframeimage *vfp=x->memvf; + unsigned long bytespp; + + if(!vfp || !x->membits) return(w+5); + + bytespp = vfp->f.pixelformat / 8; + + switch(vfp->f.pixelformat) + { + case 16: + p16 = x->membits; + while (n--) + { + if(*sync>0 && *sync<1) + x->pos=*sync * (float)(x->size / bytespp); + else + if(*sync==1) x->pos=(x->size / bytespp)-1; + + p16[x->pos++] = sampletocolor16(*in); + in++; + sync++; + if(x->pos*bytespp >= x->size) + { + x->pos=0; + outlet_float(x->x_obj.ob_outlet, x->id); + } + } + break; + case 32: + p32 = x->membits; + while (n--) + { + if(*sync>0 && *sync<1) + x->pos=*sync * (float)(x->size / bytespp); + else + if(*sync==1) x->pos=(x->size / bytespp)-1; + + p32[x->pos++] = sampletocolor32(*in); + in++; + sync++; + if(x->pos*bytespp >= x->size) + { + x->pos=0; + outlet_float(x->x_obj.ob_outlet, x->id); + } + } + break; + } + return(w+5); +} + +static void vsnapshot_dsp(t_vsnapshot *x, t_signal **sp) +{ + dsp_add(vsnapshot_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n); +} + +static void vsnapshot_float(t_vsnapshot *x, t_float f) +{ + struct vframeimage *vfp; + + if(x->id==f && x->membits!=NULL) + { + outlet_float(x->x_obj.ob_outlet, x->id); + return; + } + + x->id = x->x_f = f; + + openframedatabyid(x->id, + &x->hvf, &x->hbits, &x->memvf, &x->membits, &vfp); + if(!x->membits) + { + post("vsnapshot~: no memory at %d", x->id); + return; + } else + { + x->size = vfp->f.height*vfp->f.lpitch; + x->pos = 0; + outlet_float(x->x_obj.ob_outlet, x->id); + } +} + +static void *vsnapshot_new(t_floatarg f) +{ + t_vsnapshot *x = (t_vsnapshot *)pd_new(vsnapshot_class); + x->x_f = f; + x->pos=0; + x->hvf=NULL; + x->memvf=NULL; + x->hbits=NULL; + x->membits=NULL; + inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("signal"), gensym("signal")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft1")); + outlet_new(&x->x_obj, gensym("float")); + return (x); +} + +static void vsnapshot_destroy(t_vsnapshot *x) +{ + if(x->membits!=NULL) smfree(&x->hbits, x->membits); + if(x->memvf!=NULL) smfree(&x->hvf, x->memvf); +} + +void vsnapshot_tilde_setup(void) +{ + vsnapshot_class = class_new(gensym("vsnapshot~"), + (t_newmethod)vsnapshot_new, (t_method)vsnapshot_destroy, + sizeof(t_vsnapshot), 0, A_DEFFLOAT, 0); + CLASS_MAINSIGNALIN(vsnapshot_class, t_vsnapshot, x_f); + class_addmethod(vsnapshot_class, (t_method)vsnapshot_float, + gensym("ft1"), A_FLOAT, 0); + class_addmethod(vsnapshot_class, (t_method)vsnapshot_dsp, gensym("dsp"), 0); +} diff --git a/Patches/vsnapshot~.dll b/Patches/vsnapshot~.dll new file mode 100644 index 0000000..bc3187a Binary files /dev/null and b/Patches/vsnapshot~.dll differ diff --git a/Patches/vsnapshot~.exp b/Patches/vsnapshot~.exp new file mode 100644 index 0000000..2d397e5 Binary files /dev/null and b/Patches/vsnapshot~.exp differ diff --git a/Patches/vsnapshot~.lib b/Patches/vsnapshot~.lib new file mode 100644 index 0000000..b6ac3d4 Binary files /dev/null and b/Patches/vsnapshot~.lib differ diff --git a/Patches/vsnapshot~.obj b/Patches/vsnapshot~.obj new file mode 100644 index 0000000..a199364 Binary files /dev/null and b/Patches/vsnapshot~.obj differ diff --git a/Patches/vsnap~.pd b/Patches/vsnap~.pd new file mode 100644 index 0000000..241e8ba --- /dev/null +++ b/Patches/vsnap~.pd @@ -0,0 +1,18 @@ +#N canvas 86 302 458 308 12; +#X obj 164 170 vsnapshot~; +#X obj 239 80 reset; +#X obj 239 131 vframe \$1 \$2; +#X obj 164 211 outlet; +#X obj 120 80 inlet~; +#X obj 179 80 inlet~; +#X text 13 6 wrapper for vsnapshot~; +#X text 67 45 video signal | sync signal; +#X text 170 242 outlet to fs.frame; +#X obj 253 108 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X connect 0 0 3 0; +#X connect 1 0 2 0; +#X connect 2 0 0 2; +#X connect 4 0 0 0; +#X connect 5 0 0 1; +#X connect 9 0 2 0; diff --git a/PeRColate Framestein.pdf b/PeRColate Framestein.pdf new file mode 100644 index 0000000..e8d027e Binary files /dev/null and b/PeRColate Framestein.pdf differ diff --git a/Plugins/2colors.cpp b/Plugins/2colors.cpp new file mode 100644 index 0000000..b76be62 --- /dev/null +++ b/Plugins/2colors.cpp @@ -0,0 +1,21 @@ +#include +#include "plugin.h" +#include "pixels.h" + +// 2colors: make the image consist of black and white pixels only. +// I haven't tested this yet and it most likely WILL NOT WORK!!! + +void perform_effect(_frame f, _args a) +{ + pixels p(f); + int i=127, o; // intensity + + if(a.s) i=atoi(a.s); + + while(!p.eof()) + { + o = (p.red() + p.green() + p.blue()) / 3; + if(i +#include +#include "plugin.h" + +void perform_effect(_frame f, _args a) +{ + printf("NOTE: bend as effect does nothing. Use bend as copy operation.\n"); +} + +void perform_copy(_frame f1, _frame f2, _args a) +{ + int x, y, w, h, pos, pos2, src, ysrc, ypos1, ypos2, + widthminuspos, widthminuspos2, widthminusone, + heightminusypos1, heightminusypos2; + pixel8 *p1, *p2, tp=0, tpy=0; + char *t; + byte pixelsize = f1.pixelformat/8; + + if(!a.s) return; + pos = atoi(a.s); + if(t = strstr(a.s, " ")) + { + pos2 = atoi(t+1); + tp = 1; + if(t = strstr(t+1, " ")) + { + ypos1 = atoi(t+1); + if(t = strstr(t+1, " ")) + { + ypos2 = atoi(t+1); + if(ypos1>0||ypos2>0) tpy = 1; + } + } + } + + w = f1.width=w) pos=w-1; + if(pos2<0) pos2=0; + if(pos2>=w) pos2=w-1; + + if(ypos1<0) ypos1=0; + if(ypos1>=w) ypos1=w-1; + if(ypos2<0) ypos2=0; + if(ypos2>=w) ypos2=w-1; + + widthminuspos = f1.width-pos; + widthminuspos2 = f1.width-pos2; + widthminusone = w-1; + + heightminusypos1 = f1.height-ypos1; + heightminusypos2 = f1.height-ypos2; + + // here we'll avoid checking for pixelformat by taking the source and destination + // offsets as 8-bit, and multiplying that by pixelsize + + for(y=0; y +#include "plugin.h" + +void perform_effect(_frame f, _args a) +{ + memset(f.bits, 0, f.height*f.lpitch); +} + +void perform_copy(_frame f1, _frame f2, _args a) +{ + memset(f1.bits, 0, f1.height*f1.lpitch); + memset(f2.bits, 0, f2.height*f2.lpitch); +} diff --git a/Plugins/black.dll b/Plugins/black.dll new file mode 100644 index 0000000..cb8b57a Binary files /dev/null and b/Plugins/black.dll differ diff --git a/Plugins/black.exp b/Plugins/black.exp new file mode 100644 index 0000000..4399f54 Binary files /dev/null and b/Plugins/black.exp differ diff --git a/Plugins/black.lib b/Plugins/black.lib new file mode 100644 index 0000000..a21da90 Binary files /dev/null and b/Plugins/black.lib differ diff --git a/Plugins/black.obj b/Plugins/black.obj new file mode 100644 index 0000000..45e140d Binary files /dev/null and b/Plugins/black.obj differ diff --git a/Plugins/colortv.c b/Plugins/colortv.c new file mode 100644 index 0000000..1885d1f --- /dev/null +++ b/Plugins/colortv.c @@ -0,0 +1,69 @@ +#include "plugin.h" + +void perform_effect(struct frame f, struct args a) +{ + int x, y; + pixel16 *p16; + pixel32 *p32; + pixel16 c1, c2, c3; + + switch(f.pixelformat) + { + case 16: + for(y=0; y +#include +#include "plugin.h" + +void perform_copy(_frame f1, _frame f2, _args a) +{ + byte pixelsize = f1.pixelformat/8; + short x, y, xoff, w, h, size=1; + char *t; + + if(!a.s) return; + xoff = atoi(a.s); + + if(t = strstr(a.s, " ")) size=atoi(t+1); + + w = f1.width=w) + { + size = w - xoff; + if(!size) return; + } + + if(xoff<0 || xoff>=w) return; + + for(y=0; y +#include "plugin.h" +#include "sharemem.h" +#include "vframe.h" + +void perform_effect(_frame f, _args a) +{ + HANDLE hlvframe=NULL, hl=NULL; + LPVOID p=NULL; + struct vframeimage *vfp=NULL; + unsigned long c; + + if(!a.s) return; + + vfp = (struct vframeimage *)smopen(&hlvframe, a.s); + if(vfp==NULL) return; + +// printf("name %s width %d height %d pf %d bits %s\n", +// a.s, vfp->f.width, vfp->f.height, vfp->f.pixelformat, vfp->bitsname); + + if(f.pixelformat != vfp->f.pixelformat) + { + printf("fs2vf: pixelformats are different. no resampling available.\n"); + return; + } + + p = smopen(&hl, vfp->bitsname); + if(p==NULL) + { + CloseHandle(hlvframe); + return; + } + + c = (f.height*f.lpitch < vfp->f.height*vfp->f.lpitch) ? + f.height*f.lpitch : vfp->f.height*vfp->f.lpitch; + + memcpy(p, f.bits, c); + + smfree(&hl, p); + smfree(&hlvframe, vfp); +} diff --git a/Plugins/fs2vf.dll b/Plugins/fs2vf.dll new file mode 100644 index 0000000..974de86 Binary files /dev/null and b/Plugins/fs2vf.dll differ diff --git a/Plugins/fs2vf.exp b/Plugins/fs2vf.exp new file mode 100644 index 0000000..f3d5fba Binary files /dev/null and b/Plugins/fs2vf.exp differ diff --git a/Plugins/fs2vf.lib b/Plugins/fs2vf.lib new file mode 100644 index 0000000..038bb12 Binary files /dev/null and b/Plugins/fs2vf.lib differ diff --git a/Plugins/fs2vf.obj b/Plugins/fs2vf.obj new file mode 100644 index 0000000..4996274 Binary files /dev/null and b/Plugins/fs2vf.obj differ diff --git a/Plugins/gol.c b/Plugins/gol.c new file mode 100644 index 0000000..89ff284 --- /dev/null +++ b/Plugins/gol.c @@ -0,0 +1,89 @@ + +// +// Game of Life .. what a waste of time +// + +#include +#include +#include "plugin.h" + +#define BORN 1 +#define DYING 2 + +int dead = 0; + +int aroundme(_frame f, int x, int y) +{ + int i=0; + if(r16(scanline16(f, y-1)[x-1])>dead) i++; + if(r16(scanline16(f, y-1)[x])>dead) i++; + if(r16(scanline16(f, y-1)[x+1])>dead) i++; + if(r16(scanline16(f, y)[x-1])>dead) i++; + if(r16(scanline16(f, y)[x+1])>dead) i++; + if(r16(scanline16(f, y+1)[x-1])>dead) i++; + if(r16(scanline16(f, y+1)[x])>dead) i++; + if(r16(scanline16(f, y+1)[x+1])>dead) i++; + return i; +} + +void setstate(_frame f, byte *t, int x, int y) +{ + int i = aroundme(f, x, y); + + if(i<=1 || i>=4) t[y*f.width+x]=DYING; + else + if(i==3) t[y*f.width+x]=BORN; +} + +void perform_effect(struct frame f, struct args a) +{ + int x,y,i,r; + pixel16 *p, c; + byte *t; + + if(f.pixelformat!=16) return; + + t = malloc(f.width*f.height); + memset(t, 0, f.width*f.height); + + for(y=2; y0) + { + setstate(f, t, x-1, y-1); + setstate(f, t, x, y-1); + setstate(f, t, x+1, y-1); + setstate(f, t, x-1, y); + setstate(f, t, x, y); + setstate(f, t, x+1, y); + setstate(f, t, x-1, y+1); + setstate(f, t, x, y+1); + setstate(f, t, x+1, y+1); + } + } + } + + for(y=2; y0 ? r : 255, g16(c), b16(c)); + break; + case DYING: + c = p[+x]; + p[x] = rgbtocolor16(0, g16(c), b16(c)); + break; + } + } + } + free(t); +} diff --git a/Plugins/gol.dll b/Plugins/gol.dll new file mode 100644 index 0000000..dfd2fd6 Binary files /dev/null and b/Plugins/gol.dll differ diff --git a/Plugins/gol.exp b/Plugins/gol.exp new file mode 100644 index 0000000..2dcf523 Binary files /dev/null and b/Plugins/gol.exp differ diff --git a/Plugins/gol.lib b/Plugins/gol.lib new file mode 100644 index 0000000..c38fb4e Binary files /dev/null and b/Plugins/gol.lib differ diff --git a/Plugins/gol.obj b/Plugins/gol.obj new file mode 100644 index 0000000..e571ee0 Binary files /dev/null and b/Plugins/gol.obj differ diff --git a/Plugins/green.cpp b/Plugins/green.cpp new file mode 100644 index 0000000..c66e3e6 --- /dev/null +++ b/Plugins/green.cpp @@ -0,0 +1,14 @@ +// this is just an example of using the pixels-class.. + +#include "plugin.h" +#include "pixels.h" + +void perform_effect(_frame f, _args a) +{ + pixels p(f); + while(!p.eof()) + { + p.putrgb(0, p.green(), 0); + p.next(); + } +} diff --git a/Plugins/green.dll b/Plugins/green.dll new file mode 100644 index 0000000..3dc1016 Binary files /dev/null and b/Plugins/green.dll differ diff --git a/Plugins/green.exp b/Plugins/green.exp new file mode 100644 index 0000000..bba3425 Binary files /dev/null and b/Plugins/green.exp differ diff --git a/Plugins/green.lib b/Plugins/green.lib new file mode 100644 index 0000000..f79b6b6 Binary files /dev/null and b/Plugins/green.lib differ diff --git a/Plugins/green.obj b/Plugins/green.obj new file mode 100644 index 0000000..d32d5ab Binary files /dev/null and b/Plugins/green.obj differ diff --git a/Plugins/hist.cpp b/Plugins/hist.cpp new file mode 100644 index 0000000..f525db1 --- /dev/null +++ b/Plugins/hist.cpp @@ -0,0 +1,54 @@ +// +// build an array where x=color intensity and y=number of colors with that intensity. +// use with fs.hist.pd. +// +// array is passed in a file, a better solution would be to use vframe... +// + +#include +#include +#include +#include +#include +#include "plugin.h" +#include "pixels.h" + +void perform_effect(_frame f, _args a) +{ + if(!a.s) return; + + // parameters: + // get gol + byte col = atoi(a.s); + + // get filename + char *t; + if(!(t = strstr(a.s, " "))) return; + char *filename = t+1; + + // get receivename + if(!(t = strstr(t+1, " "))) return; + char *retname = t+1; + t[0]=0; // tell filename and receivename apart + + pixels p(f); + signed short hist[256]; // 16bits, for read16 on pd + +// count colors from zero up + memset(hist, 0, sizeof(hist)); +// or count from -2^15 (bottom of graph)? +// short i, v=1<<15; +// for(i=0; i<256; hist[i++]=v) ; + + while(!p.eof()) + { + ++hist[col==0 ? p.red() : col==1 ? p.green() : col==2 ? p.blue() : 0]; + p.next(); + } + + ofstream of(filename, ios::out|ios::binary); + of.write((char *)&hist, sizeof(hist)); + of.close(); + + sprintf(a.ret, "%s=1", retname); // bang to indicate we're done +} diff --git a/Plugins/hist.dll b/Plugins/hist.dll new file mode 100644 index 0000000..7c0bc44 Binary files /dev/null and b/Plugins/hist.dll differ diff --git a/Plugins/hist.exp b/Plugins/hist.exp new file mode 100644 index 0000000..238ffc2 Binary files /dev/null and b/Plugins/hist.exp differ diff --git a/Plugins/hist.lib b/Plugins/hist.lib new file mode 100644 index 0000000..d8d0ddc Binary files /dev/null and b/Plugins/hist.lib differ diff --git a/Plugins/hist.obj b/Plugins/hist.obj new file mode 100644 index 0000000..760936d Binary files /dev/null and b/Plugins/hist.obj differ diff --git a/Plugins/makefile b/Plugins/makefile new file mode 100644 index 0000000..e899fe2 --- /dev/null +++ b/Plugins/makefile @@ -0,0 +1,82 @@ +all: noize colortv subtract xbend bend gol shuffle green tile rgbcopy copyvert black rgb hist setbits xshred sonogram vf2fs fs2vf swap 2colors plot makesliders + dir *.dll + +# FLAGS: +# +# + +FLAGS = /LD /Gd /GD /Ox + +EFFECT = /export:perform_effect +COPY = /export:perform_copy +BOTH = /export:perform_effect /export:perform_copy + +noize: + cl noize.c $(FLAGS) /link $(BOTH) + +colortv: + cl colortv.c $(FLAGS) /link $(BOTH) + +subtract: + cl subtract.cpp $(FLAGS) /link $(EFFECT) + +xbend: + cl xbend.c $(FLAGS) /link $(BOTH) + +bend: + cl bend.c $(FLAGS) /link $(BOTH) + +gol: + cl gol.c $(FLAGS) /link $(EFFECT) + +shuffle: + cl shuffle.c $(FLAGS) /link $(EFFECT) + +green: + cl green.cpp $(FLAGS) /link $(EFFECT) + +tile: + cl tile.cpp $(FLAGS) /link $(COPY) + +rgbcopy: + cl rgbcopy.cpp $(FLAGS) /link $(COPY) + +copyvert: + cl copy_vert.c $(FLAGS) /link $(COPY) + +black: + cl black.c $(FLAGS) /link $(BOTH) + +rgb: + cl rgb.c $(FLAGS) /link $(EFFECT) + +hist: + cl hist.cpp $(FLAGS) /link $(EFFECT) + +setbits: + cl setbits.c $(FLAGS) /link $(EFFECT) + +sonogram: + cl sonogram.cpp $(FLAGS) /link $(EFFECT) + +xshred: + cl xshred.c $(FLAGS) /link $(COPY) + +vf2fs: + cl vf2fs.c $(FLAGS) /I..\Externals /link $(EFFECT) + +fs2vf: + cl fs2vf.c $(FLAGS) /I..\Externals /link $(EFFECT) + +swap: + cl swap.cpp $(FLAGS) /link $(COPY) + +2colors: + cl 2colors.cpp $(FLAGS) /link $(EFFECT) + +plot: + cl plot.cpp $(FLAGS) /link $(EFFECT) + +makesliders: + cl makesliders.c $(FLAGS) /link $(EFFECT) + copy makesliders.dll ms.dll diff --git a/Plugins/makesliders.c b/Plugins/makesliders.c new file mode 100644 index 0000000..5c0b209 --- /dev/null +++ b/Plugins/makesliders.c @@ -0,0 +1,40 @@ +// +// makesliders: display slider values +// +// usage: makesliders 14 56 76 140 +// displays four sliders with given values +// + +#include +#include "plugin.h" + +#define MAXVALS 128 + +void perform_effect(_frame f, _args a) +{ + pixel8 *p8; + char *t=a.s; + int val[MAXVALS], valcount=0, i, y, bitsperpixel=f.pixelformat / 8, col; + + if(!t) return; + + while(t && valcount=0 && y +#include "plugin.h" + +void perform_effect(struct frame f, struct args a) +{ + int i,o,x,y; + byte bits = f.pixelformat/8; + + o=(f.width*f.height)/10; + for(i=0; i +#include +#include +#include "plugin.h" +#include "pixels.h" + +// plot exists to provide plotting to vframe - much faster than +// plot with fs.draw which goes thru network. + +void perform_effect(_frame f, _args a) +{ + if(!a.s) return; + + char *t=strstr(a.s, " "); + if(!t) return; + + t[0]=0; + + int x=atoi(a.s); + int y=atoi(t+1); + + pixels p(f); + p.moveto(x, y); + p.putrgb(255, 255, 255); +} diff --git a/Plugins/plot.dll b/Plugins/plot.dll new file mode 100644 index 0000000..93cff6a Binary files /dev/null and b/Plugins/plot.dll differ diff --git a/Plugins/plot.exp b/Plugins/plot.exp new file mode 100644 index 0000000..1d5ce2f Binary files /dev/null and b/Plugins/plot.exp differ diff --git a/Plugins/plot.lib b/Plugins/plot.lib new file mode 100644 index 0000000..afdc085 Binary files /dev/null and b/Plugins/plot.lib differ diff --git a/Plugins/plot.obj b/Plugins/plot.obj new file mode 100644 index 0000000..c48c30f Binary files /dev/null and b/Plugins/plot.obj differ diff --git a/Plugins/plugin.h b/Plugins/plugin.h new file mode 100644 index 0000000..00d3514 --- /dev/null +++ b/Plugins/plugin.h @@ -0,0 +1,119 @@ +// +// send the name of the plugin to fs.frame, and fs will call +// perform_effect(struct frame f, struct args a) in your dll. +// +// send it to the right inlet of fs.copy, and +// perform_copy(struct frame f1, struct frame f2, struct args a) +// will be used as a copy operation. +// + +#ifndef _PLUGINH +#define _PLUGINH + +typedef unsigned char byte; +#define pixel8 byte +#define pixel16 unsigned short +#define pixel24 struct pixel24data +#define pixel32 unsigned long +#define _frame struct frame +#define _args struct args + +struct pixel24data { byte b; byte g; byte r; }; + +struct frame +{ + byte *bits; // pixel data + int lpitch; // used to get row position in bits, see scanline below + // this is not always width*(pixelformat/8), you tell me why + int width; + int height; + int pixelformat; // pixelformat is bitcount of your screen, 8, 16, 24 or 32. +}; + +struct args +{ + char *s; // effect/copy arguments in a string + char *ret; // return values. data given in the form + // "pd_receive_name=value;..." will be sent back to Pd. + // memory allocated: 256 characters. +}; + +// 8-bit pointer to row y +__inline byte *scanline(struct frame f, int y) { return &f.bits[y*f.lpitch]; } + +// pointer to 16 bit pixels +__inline pixel16 *scanline16(struct frame f, int y) { return (pixel16 *)scanline(f, y); } + +// pointer to 24 bit pixels +__inline pixel24 *scanline24(struct frame f, int y) { return (pixel24 *)scanline(f, y); } + +// pointer to 32 bit pixels +__inline pixel32 *scanline32(struct frame f, int y) { return (pixel32 *)scanline(f, y); } + +__inline byte r16(pixel16 color) +{ + return (color >> 11) << 3; +} + +__inline byte g16(pixel16 color) +{ + return ((color & 2016) >> 5) << 2; +} + +__inline byte b16(pixel16 color) +{ + return (color & 31) << 3; +} + +__inline byte r24(pixel24 color) +{ + return color.r; +} + +__inline byte g24(pixel24 color) +{ + return color.g; +} + +__inline byte b24(pixel24 color) +{ + return color.b; +} + +__inline byte r32(pixel32 color) +{ + return (byte)color; +} + +__inline byte g32(pixel32 color) +{ + return (byte)(((pixel16)color) >> 8); +} + +__inline byte b32(pixel32 color) +{ + return (byte)(color >> 16); +} + +__inline pixel16 rgbtocolor16(byte r, byte g, byte b) +{ + return ((r >> 3) << 11) | // r value shifted + ((g >> 2) << 5) | // g value shifted + (b >> 3); // add blue +} + +__inline pixel24 rgbtocolor24(byte r, byte g, byte b) +{ + pixel24 p; + p.r = r; + p.g = g; + p.b = b; + return p; +} + +__inline pixel32 rgbtocolor32(byte r, byte g, byte b) +{ + return (b << 16) | (g << 8) | r; +} + +#endif // #ifndef _PLUGINH diff --git a/Plugins/rgb.c b/Plugins/rgb.c new file mode 100644 index 0000000..d58f784 --- /dev/null +++ b/Plugins/rgb.c @@ -0,0 +1,62 @@ +#include +#include "plugin.h" + +void perform_effect(_frame f, _args a) +{ + char *t; + short x, y; + pixel16 c16; + pixel24 c24; + pixel32 c32; + byte r, g, b; + char *ret_r, *ret_g, *ret_b; + + if(!a.s) return; + + // get x and y params + x = atoi(a.s); + if(!(t = strstr(a.s, " "))) return; + y = atoi(t+1); + + // get returnvaluereceivenames + if(!(t = strstr(t+1, " "))) return; + ret_r = t+1; + if(!(t = strstr(t+1, " "))) return; + ret_g = t+1; + t[0]=0; + if(!(t = strstr(t+1, " "))) return; + ret_b = t+1; + t[0]=0; + + if(x<0||x>=f.width) return; + if(y<0||y>=f.height) return; + + switch(f.pixelformat) + { + case 16: + c16 = scanline16(f, y)[x]; + r = r16(c16); + g = g16(c16); + b = b16(c16); + break; + case 24: + c24 = scanline24(f, y)[x]; + r = r24(c24); + g = g24(c24); + b = b24(c24); + break; + case 32: + c32 = scanline32(f, y)[x]; + r = r32(c32); + g = g32(c32); + b = b32(c32); + break; + } + + // return-values: + // + // framestein will send data given in the form "pd_receiver_name=value" + // back to pd. + + sprintf(a.ret, "%s=%d;%s=%d;%s=%d", ret_b, b, ret_g, g, ret_r, r); +} diff --git a/Plugins/rgb.dll b/Plugins/rgb.dll new file mode 100644 index 0000000..ba7dfd2 Binary files /dev/null and b/Plugins/rgb.dll differ diff --git a/Plugins/rgb.exp b/Plugins/rgb.exp new file mode 100644 index 0000000..cc7feab Binary files /dev/null and b/Plugins/rgb.exp differ diff --git a/Plugins/rgb.lib b/Plugins/rgb.lib new file mode 100644 index 0000000..8e364a1 Binary files /dev/null and b/Plugins/rgb.lib differ diff --git a/Plugins/rgb.obj b/Plugins/rgb.obj new file mode 100644 index 0000000..69b7892 Binary files /dev/null and b/Plugins/rgb.obj differ diff --git a/Plugins/rgbcopy.cpp b/Plugins/rgbcopy.cpp new file mode 100644 index 0000000..b226e23 --- /dev/null +++ b/Plugins/rgbcopy.cpp @@ -0,0 +1,28 @@ +#include +#include +#include "plugin.h" +#include "pixels.h" + +void perform_copy(_frame f1, _frame f2, _args a) +{ + pixels p1(f1), p2(f2); + char *t; + short r=0, g=0, b=0; + + if(!a.s) return; + + if(strstr(a.s, "r") || strstr(a.s, "R")) r=1; + if(strstr(a.s, "g") || strstr(a.s, "G")) g=1; + if(strstr(a.s, "b") || strstr(a.s, "B")) b=1; + + while(!p1.eof()&&!p2.eof()) + { + p2.putrgb( + r ? p1.red() : p2.red(), + g ? p1.green() : p2.green(), + b ? p1.blue() : p2.blue() + ); + p1.next(); + p2.next(); + } +} diff --git a/Plugins/rgbcopy.dll b/Plugins/rgbcopy.dll new file mode 100644 index 0000000..1a995d3 Binary files /dev/null and b/Plugins/rgbcopy.dll differ diff --git a/Plugins/rgbcopy.exp b/Plugins/rgbcopy.exp new file mode 100644 index 0000000..b85e71e Binary files /dev/null and b/Plugins/rgbcopy.exp differ diff --git a/Plugins/rgbcopy.lib b/Plugins/rgbcopy.lib new file mode 100644 index 0000000..09edbd5 Binary files /dev/null and b/Plugins/rgbcopy.lib differ diff --git a/Plugins/rgbcopy.obj b/Plugins/rgbcopy.obj new file mode 100644 index 0000000..5d7194c Binary files /dev/null and b/Plugins/rgbcopy.obj differ diff --git a/Plugins/setbits.c b/Plugins/setbits.c new file mode 100644 index 0000000..dddc5eb --- /dev/null +++ b/Plugins/setbits.c @@ -0,0 +1,11 @@ +#include +#include "plugin.h" + +void perform_effect(_frame f, _args a) +{ + unsigned char c; + + if(!a.s) return; + c = atoi(a.s); + memset(f.bits, c, f.height*f.lpitch); +} diff --git a/Plugins/setbits.dll b/Plugins/setbits.dll new file mode 100644 index 0000000..9a772ab Binary files /dev/null and b/Plugins/setbits.dll differ diff --git a/Plugins/setbits.exp b/Plugins/setbits.exp new file mode 100644 index 0000000..484fe3b Binary files /dev/null and b/Plugins/setbits.exp differ diff --git a/Plugins/setbits.lib b/Plugins/setbits.lib new file mode 100644 index 0000000..1e1db08 Binary files /dev/null and b/Plugins/setbits.lib differ diff --git a/Plugins/setbits.obj b/Plugins/setbits.obj new file mode 100644 index 0000000..09a9196 Binary files /dev/null and b/Plugins/setbits.obj differ diff --git a/Plugins/sharemem.h b/Plugins/sharemem.h new file mode 100644 index 0000000..a26d198 --- /dev/null +++ b/Plugins/sharemem.h @@ -0,0 +1,61 @@ +#ifndef __SHAREMEM_H +#define __SHAREMEM_H + +#include +#include + +// +// allocate named shared memory +// +LPVOID smalloc(HANDLE *h, char *name, DWORD size) +{ + LPVOID p; + + *h = CreateFileMapping( + INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, + size, name + ); + + if(*h==NULL) return(NULL); + + p = MapViewOfFile( *h, FILE_MAP_WRITE, 0, 0, 0); + + if(p==NULL) + { + CloseHandle(*h); + return(NULL); + } + return(p); +} + +// +// open access to named shared memory +// +LPVOID smopen(HANDLE *h, char *name) +{ + LPVOID p; + + *h = OpenFileMapping(FILE_MAP_ALL_ACCESS, TRUE, name); + + if(*h==NULL) return(NULL); + + p = MapViewOfFile(*h, FILE_MAP_WRITE, 0, 0, 0); + + if(p==NULL) + { + CloseHandle(*h); + return(NULL); + } + return(p); +} + +// +// cleanup +// +void smfree(HANDLE *h, LPVOID p) +{ + UnmapViewOfFile(p); + CloseHandle(*h); +} + +#endif diff --git a/Plugins/shuffle.c b/Plugins/shuffle.c new file mode 100644 index 0000000..0604595 --- /dev/null +++ b/Plugins/shuffle.c @@ -0,0 +1,42 @@ +#include +#include "plugin.h" + +void perform_effect(_frame f, _args a) +{ + int i, o=1000, x1, y1, x2, y2, range=10; + char *t; + pixel8 *p1, *p2; + pixel32 dot; + byte pixelsize=f.pixelformat/8; + + if(f.pixelformat>32) return; + + if(a.s) + { + o = atoi(a.s); + if(o==0) o=1000; + + if(t = strstr(a.s, " ")) + if((range = atoi(t+1))==0) return; + } + + for(i=0; i=f.width) x2=f.width-1; + if(y2<0) y2=0; + if(y2>=f.height) y2=f.height-1; + + p1 = scanline(f, y1); + p2 = scanline(f, y2); + + memcpy(&dot, &p2[x2*pixelsize], pixelsize); + memcpy(&p2[x2*pixelsize], &p1[x1*pixelsize], pixelsize); + memcpy(&p1[x1*pixelsize], &dot, pixelsize); + } +} diff --git a/Plugins/shuffle.dll b/Plugins/shuffle.dll new file mode 100644 index 0000000..bd5d552 Binary files /dev/null and b/Plugins/shuffle.dll differ diff --git a/Plugins/shuffle.exp b/Plugins/shuffle.exp new file mode 100644 index 0000000..2802b94 Binary files /dev/null and b/Plugins/shuffle.exp differ diff --git a/Plugins/shuffle.lib b/Plugins/shuffle.lib new file mode 100644 index 0000000..d1bc16f Binary files /dev/null and b/Plugins/shuffle.lib differ diff --git a/Plugins/shuffle.obj b/Plugins/shuffle.obj new file mode 100644 index 0000000..5c70ab2 Binary files /dev/null and b/Plugins/shuffle.obj differ diff --git a/Plugins/sonogram.cpp b/Plugins/sonogram.cpp new file mode 100644 index 0000000..821b94a --- /dev/null +++ b/Plugins/sonogram.cpp @@ -0,0 +1,82 @@ +// +// sonogram.cpp +// +// use with fs.sonogram +// +// see example-sonogram.pd +// + +#include +#include +#include +#include +#include +#include "plugin.h" +#include "pixels.h" + +#define SONOSIZE 128 +#define SONOMAXVAL 500 +#define sonotype float + +int callcount=-1; + +void perform_effect(_frame f, _args a) +{ + if(!a.s) return; + + if(++callcount>=f.width) callcount=0; + + FILE *inf; + if((inf = fopen(a.s, "rb"))==NULL) + { + printf("sonogram: error opening %s\n", a.s); + return; + } + + char buf[80]; + sonotype sono[SONOSIZE]; + int i=0; + + while(!feof(inf)) + { + if(!fgets(buf, 80, inf)) + { + printf("sonogram: read error.\n"); + return; + } + sono[i] = atof(buf); + if(++i>=SONOSIZE) break; + } + fclose(inf); + + int y; + + for(i=0; iSONOMAXVAL) sono[i]=SONOMAXVAL; + sono[i] = (sonotype)((sono[i] / (float)SONOMAXVAL)*255); + // white = no sound + sono[i] = abs(sono[i]-255); + + y = (int)((i / (float)SONOSIZE) * (float)f.height); + // bottom = bass + y = abs((f.height-1) - y); + + switch(f.pixelformat) + { + case 16: + scanline16(f, y)[callcount] = + rgbtocolor16(sono[i], sono[i], sono[i]); + break; + case 24: + scanline24(f, y)[callcount] = + rgbtocolor24(sono[i], sono[i], sono[i]); + break; + case 32: + scanline32(f, y)[callcount] = + rgbtocolor32(sono[i], sono[i], sono[i]); + break; + } + } +} diff --git a/Plugins/sonogram.dll b/Plugins/sonogram.dll new file mode 100644 index 0000000..db6e132 Binary files /dev/null and b/Plugins/sonogram.dll differ diff --git a/Plugins/sonogram.exp b/Plugins/sonogram.exp new file mode 100644 index 0000000..40a6fae Binary files /dev/null and b/Plugins/sonogram.exp differ diff --git a/Plugins/sonogram.lib b/Plugins/sonogram.lib new file mode 100644 index 0000000..484c38d Binary files /dev/null and b/Plugins/sonogram.lib differ diff --git a/Plugins/sonogram.obj b/Plugins/sonogram.obj new file mode 100644 index 0000000..7dd6ee5 Binary files /dev/null and b/Plugins/sonogram.obj differ diff --git a/Plugins/subtract.cpp b/Plugins/subtract.cpp new file mode 100644 index 0000000..89ba216 --- /dev/null +++ b/Plugins/subtract.cpp @@ -0,0 +1,38 @@ +// 0.20 +// - from c to c++ +// - pixelformat-aware + +#include +#include +#include "plugin.h" +#include "pixels.h" + +void perform_effect(_frame f, _args a) +{ + pixels p(f); + char *t; + byte tr, tg, tb, r=0, g=0, b=0; + + if(!a.s) return; + + r = atoi(a.s); + if(t = strstr(a.s, " ")) + { + g = atoi(t+1); + if (t = strstr(t+1, " ")) + b = atoi(t+1); + } + + while(!p.eof()) + { + tr = p.red(); + tg = p.green(); + tb = p.blue(); + p.putrgb( + tr>r ? tr-r : 0, + tg>g ? tg-g : 0, + tb>b ? tb-b : 0 + ); + p.next(); + } +} diff --git a/Plugins/subtract.dll b/Plugins/subtract.dll new file mode 100644 index 0000000..883c541 Binary files /dev/null and b/Plugins/subtract.dll differ diff --git a/Plugins/subtract.exp b/Plugins/subtract.exp new file mode 100644 index 0000000..9a066ba Binary files /dev/null and b/Plugins/subtract.exp differ diff --git a/Plugins/subtract.lib b/Plugins/subtract.lib new file mode 100644 index 0000000..5132561 Binary files /dev/null and b/Plugins/subtract.lib differ diff --git a/Plugins/subtract.obj b/Plugins/subtract.obj new file mode 100644 index 0000000..8405ccc Binary files /dev/null and b/Plugins/subtract.obj differ diff --git a/Plugins/swap.cpp b/Plugins/swap.cpp new file mode 100644 index 0000000..d1389f4 --- /dev/null +++ b/Plugins/swap.cpp @@ -0,0 +1,62 @@ +#include +#include +#include +#include "plugin.h" +#include "pixels.h" + +// swap selected area on two images +// args: swap sourcex1 sourcey1 sourcex2 sourcey2 destx desty +// (the selection is of equal size on both images) + +void swapint(int *a, int *b) +{ + int i = *b; + *b = *a; + *a = i; +} + +void perform_copy(_frame f1, _frame f2, _args a) +{ + if(!a.s) return; + + // get args + int sx1, sy1, sx2, sy2, dx1, dy1; + char *t; + + sx1 = atoi(a.s); + if(!(t = strstr(a.s, " "))) return; + sy1 = atoi(t); + if(!(t = strstr(t+1, " "))) return; + sx2 = atoi(t); + if(!(t = strstr(t+1, " "))) return; + sy2 = atoi(t); + if(!(t = strstr(t+1, " "))) return; + dx1 = atoi(t); + if(!(t = strstr(t+1, " "))) return; + dy1 = atoi(t); + + if(sx1>sx2) swapint(&sx1, &sx2); + if(sy1>sy2) swapint(&sy1, &sy2); + +printf("swap: %d %d %d %d - %d %d\n", sx1, sy1, sx2, sy2, dx1, dy1); + + int x, y, i, o; + pixel16 c16; + pixels p1(f1), p2(f2); + + for(y=sy1; y<=sy2; y++) + for(x=sx1; x<=sx2; x++) + { + if(x>=f1.width || y>=f1.height) continue; + i = dx1+(x-sx1); + o = dy1+(y-sy1); + if(i>=f2.width || o>=f2.height) continue; + + p1.moveto(x, y); + p2.moveto(i, o); + + c16 = p2.dot16(); + p2.dot16(p1.dot16()); + p1.dot16(c16); + } +} diff --git a/Plugins/swap.dll b/Plugins/swap.dll new file mode 100644 index 0000000..ee04f4c Binary files /dev/null and b/Plugins/swap.dll differ diff --git a/Plugins/swap.exp b/Plugins/swap.exp new file mode 100644 index 0000000..8015b40 Binary files /dev/null and b/Plugins/swap.exp differ diff --git a/Plugins/swap.lib b/Plugins/swap.lib new file mode 100644 index 0000000..bda1a31 Binary files /dev/null and b/Plugins/swap.lib differ diff --git a/Plugins/swap.obj b/Plugins/swap.obj new file mode 100644 index 0000000..cca03a8 Binary files /dev/null and b/Plugins/swap.obj differ diff --git a/Plugins/tile.cpp b/Plugins/tile.cpp new file mode 100644 index 0000000..47fa5ca --- /dev/null +++ b/Plugins/tile.cpp @@ -0,0 +1,59 @@ +#include +#include +#include "plugin.h" +#include "pixels.h" + +void perform_copy(_frame f1, _frame f2, _args a) +{ + pixels px(f2); + pixel16 *p16; + pixel24 *p24; + pixel32 *p32; + int tile, tiley=-1, prevy=-1; + char *t; + + tile = atoi(a.s); + if(tile<=0) tile=2; + if(t = strstr(a.s, " ")) + { + tiley = atoi(t+1); + if(tiley<=0) tiley=2; + } + + // i could have the switch() inside the while-loop.. + // but is it more efficient this way? + + switch(f1.pixelformat) + { + case 16: + while(!px.eof()) { + if(px.y != prevy) { + p16 = scanline16(f1, (px.y * (tiley>0 ? tiley : tile))%f1.height); + prevy = px.y; + } + px.dot16(p16[ (px.x * tile)%f1.width ]); + px.next(); + } + break; + case 24: + while(!px.eof()) { + if(px.y != prevy) { + p24 = scanline24(f1, (px.y * (tiley>0 ? tiley : tile))%f1.height); + prevy = px.y; + } + px.dot24(p24[ (px.x * tile)%f1.width ]); + px.next(); + } + break; + case 32: + while(!px.eof()) { + if(px.y != prevy) { + p32 = scanline32(f1, (px.y * (tiley>0 ? tiley : tile))%f1.height); + prevy = px.y; + } + px.dot32(p32[ (px.x * tile)%f1.width ]); + px.next(); + } + break; + } +} diff --git a/Plugins/tile.dll b/Plugins/tile.dll new file mode 100644 index 0000000..58a8886 Binary files /dev/null and b/Plugins/tile.dll differ diff --git a/Plugins/tile.exp b/Plugins/tile.exp new file mode 100644 index 0000000..69d5907 Binary files /dev/null and b/Plugins/tile.exp differ diff --git a/Plugins/tile.lib b/Plugins/tile.lib new file mode 100644 index 0000000..1f0732e Binary files /dev/null and b/Plugins/tile.lib differ diff --git a/Plugins/tile.obj b/Plugins/tile.obj new file mode 100644 index 0000000..8409075 Binary files /dev/null and b/Plugins/tile.obj differ diff --git a/Plugins/vf2fs.c b/Plugins/vf2fs.c new file mode 100644 index 0000000..47e856e --- /dev/null +++ b/Plugins/vf2fs.c @@ -0,0 +1,49 @@ +// +// readvf.c +// used to display vframe objects +// +// 1st argument is name of shared memory +// to struct vframeimage (see Externals\vframe.h) +// + +#include +#include "plugin.h" +#include "sharemem.h" +#include "vframe.h" + +void perform_effect(_frame f, _args a) +{ + HANDLE hlvframe=NULL, hl=NULL; + LPVOID p=NULL; + struct vframeimage *vfp=NULL; + unsigned long c; + + if(!a.s) return; + + vfp = (struct vframeimage *)smopen(&hlvframe, a.s); + if(vfp==NULL) return; + +// printf("name %s width %d height %d pf %d bits %s\n", +// a.s, vfp->f.width, vfp->f.height, vfp->f.pixelformat, vfp->bitsname); + + if(f.pixelformat != vfp->f.pixelformat) + { + printf("vf2fs: pixelformats are different. no resampling available.\n"); + return; + } + + p = smopen(&hl, vfp->bitsname); + if(p==NULL) + { + CloseHandle(hlvframe); + return; + } + + c = (f.height*f.lpitch < vfp->f.height*vfp->f.lpitch) ? + f.height*f.lpitch : vfp->f.height*vfp->f.lpitch; + + memcpy(f.bits, p, c); + + smfree(&hl, p); + smfree(&hlvframe, vfp); +} diff --git a/Plugins/vf2fs.dll b/Plugins/vf2fs.dll new file mode 100644 index 0000000..d51abad Binary files /dev/null and b/Plugins/vf2fs.dll differ diff --git a/Plugins/vf2fs.exp b/Plugins/vf2fs.exp new file mode 100644 index 0000000..c9ce25b Binary files /dev/null and b/Plugins/vf2fs.exp differ diff --git a/Plugins/vf2fs.lib b/Plugins/vf2fs.lib new file mode 100644 index 0000000..0c52583 Binary files /dev/null and b/Plugins/vf2fs.lib differ diff --git a/Plugins/vf2fs.obj b/Plugins/vf2fs.obj new file mode 100644 index 0000000..4c0a7bd Binary files /dev/null and b/Plugins/vf2fs.obj differ diff --git a/Plugins/xbend.c b/Plugins/xbend.c new file mode 100644 index 0000000..1ba9959 --- /dev/null +++ b/Plugins/xbend.c @@ -0,0 +1,99 @@ +#include +#include +#include "plugin.h" + +void perform_effect(_frame f, _args a) +{ + byte pixelsize = f.pixelformat/8; + int x, y, pos, pos2, widthminuspos, widthminuspos2; + pixel8 *p, *tp=0; + char *t; + + if(!a.s) return; + + pos = atoi(a.s); + if(t = strstr(a.s, " ")) + { + pos2 = atoi(t+1); + tp = (pixel8 *)malloc(f.width*pixelsize); + } + + if(pos<0) pos=0; + if(pos>=f.width) pos=f.width-1; + if(pos2<0) pos2=0; + if(pos2>=f.width) pos2=f.width-1; + + widthminuspos = f.width-pos; + widthminuspos2 = f.width-pos2; + + for(y=0; y=w) pos=w-1; + if(pos2<0) pos2=0; + if(pos2>=w) pos2=w-1; + + widthminuspos = f1.width-pos; + widthminuspos2 = f1.width-pos2; + widthminusone = w-1; + + for(y=0; y +#include "plugin.h" + +void perform_copy(_frame f1, _frame f2, _args a) +{ + int step, w, h, y, pixelsize=f1.pixelformat/8; + + if(!a.s) return; + + step = atoi(a.s); + if(step<=0) step=1; + + w = f1.width +FastLib by G-Soft, http://gfody.com +TDcAviPlay by Dream Company, http://www.dream-com.com +Intel Image Processing Library version 1.5 (ijl15.dll) +C2PhotoShopHost by Antti Lukats, http://www.case2000.com +AviWriter by Elliott Shevin (with large pieces of code stolen from Anders Melander) +l2s from ZEXY by Johannes Zmoelnig, see ftp://iem.kug.ac.at/pd/Externals/ZEXY/. + +And, Pure Data by Miller Puckette and others, http://www.crca.ucsd.edu/~msp/software.html + + +OFFICIAL LINKS + +download site: +framestein.org + +List for receiving update information: +http://groups.yahoo.com/group/framestein + +Send your feedback, ideas, plugins, ... +jusu@iki.fi +. diff --git a/Reija/01.jpg b/Reija/01.jpg new file mode 100644 index 0000000..ac17dd9 Binary files /dev/null and b/Reija/01.jpg differ diff --git a/Reija/02.jpg b/Reija/02.jpg new file mode 100644 index 0000000..681558a Binary files /dev/null and b/Reija/02.jpg differ diff --git a/Reija/03.jpg b/Reija/03.jpg new file mode 100644 index 0000000..55dc52b Binary files /dev/null and b/Reija/03.jpg differ diff --git a/Reija/04.jpg b/Reija/04.jpg new file mode 100644 index 0000000..d6f834a Binary files /dev/null and b/Reija/04.jpg differ diff --git a/Reija/05.jpg b/Reija/05.jpg new file mode 100644 index 0000000..2716db4 Binary files /dev/null and b/Reija/05.jpg differ diff --git a/Reija/06.jpg b/Reija/06.jpg new file mode 100644 index 0000000..c2c8480 Binary files /dev/null and b/Reija/06.jpg differ diff --git a/Reija/07.jpg b/Reija/07.jpg new file mode 100644 index 0000000..14e045c Binary files /dev/null and b/Reija/07.jpg differ diff --git a/Reija/08.jpg b/Reija/08.jpg new file mode 100644 index 0000000..77bde9c Binary files /dev/null and b/Reija/08.jpg differ diff --git a/Source/Filez.pas b/Source/Filez.pas new file mode 100644 index 0000000..1560a77 --- /dev/null +++ b/Source/Filez.pas @@ -0,0 +1,87 @@ +unit Filez; +{$I-} + +interface + +uses + Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs; + +type + THandleFileEvent = procedure( const SearchRec:TSearchRec; + const FullPath: String ) of object; + // fullpath contains filepath+filename + + TScanDir = class(TComponent) + private + { Private declarations } + FOnHandleFile : THandleFileEvent; + protected + { Protected declarations } + public + { Public declarations } + procedure Scan( const Path : String ); + constructor Create( AOwner:TComponent ); override; + published + { Published declarations } + property OnHandleFile : THandleFileEvent read FOnHandleFile write FOnHandleFile; + end; + + function FileSizeByName( const FileName:String ):Longint; + +procedure Register; + +implementation + +uses + Strz; + +function FileSizeByName( const FileName:String ):Longint; +var + F:file of Byte; +begin + Result := 0; + AssignFile(F, FileName); + Reset(F); + if IoResult<>0 then Exit; + Result := FileSize(F); + Close(F); +end; + +constructor TScanDir.Create( AOwner:TComponent ); +begin + inherited Create( AOwner ); + + FOnHandleFile := nil; +end; + +procedure TScanDir.Scan( const Path : String ); +var + SearchRec : TSearchRec; + Result : Integer; + S : String; +begin + if not Assigned(FOnHandleFile) then + Exit; + + S := VerifyBackSlash(Path); + Result := FindFirst( S+'*.*', faAnyFile, SearchRec); + if Result=0 then + repeat + if (SearchRec.Name='.') or (SearchRec.Name='..') then + Continue; + + FOnHandleFile( SearchRec, + S+SearchRec.Name ); + + if SearchRec.Attr and faDirectory>0 then + Scan( S+SearchRec.Name ); + until FindNext(SearchRec)<>0; +end; + +procedure Register; +begin + RegisterComponents('Labrz', [TScanDir]); +end; + +end. + diff --git a/Source/Framestein.cfg b/Source/Framestein.cfg new file mode 100644 index 0000000..cdbef8d --- /dev/null +++ b/Source/Framestein.cfg @@ -0,0 +1,39 @@ +-$A+ +-$B- +-$C+ +-$D+ +-$E- +-$F- +-$G+ +-$H+ +-$I+ +-$J+ +-$K- +-$L+ +-$M- +-$N+ +-$O+ +-$P+ +-$Q- +-$R- +-$S- +-$T- +-$U- +-$V+ +-$W- +-$X+ +-$YD +-$Z1 +-cg +-AWinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; +-H+ +-W+ +-M +-$M16384,1048576 +-K$00400000 +-LE"c:\program files\borland\delphi5\Projects\Bpl" +-LN"c:\program files\borland\delphi5\Projects\Bpl" +-U"\lab\common;C:\lab\common\DelphiX2000_0717-2\Source;\lab\common\fastlib;\lab\common\pshost;C:\lab\common\G32" +-O"\lab\common;C:\lab\common\DelphiX2000_0717-2\Source;\lab\common\fastlib;\lab\common\pshost;C:\lab\common\G32" +-I"\lab\common;C:\lab\common\DelphiX2000_0717-2\Source;\lab\common\fastlib;\lab\common\pshost;C:\lab\common\G32" +-R"\lab\common;C:\lab\common\DelphiX2000_0717-2\Source;\lab\common\fastlib;\lab\common\pshost;C:\lab\common\G32" diff --git a/Source/Framestein.dof b/Source/Framestein.dof new file mode 100644 index 0000000..d217e75 --- /dev/null +++ b/Source/Framestein.dof @@ -0,0 +1,91 @@ +[Compiler] +A=1 +B=0 +C=1 +D=1 +E=0 +F=0 +G=1 +H=1 +I=1 +J=1 +K=0 +L=1 +M=0 +N=1 +O=1 +P=1 +Q=0 +R=0 +S=0 +T=0 +U=0 +V=1 +W=0 +X=1 +Y=1 +Z=1 +ShowHints=1 +ShowWarnings=1 +UnitAliases=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; +[Linker] +MapFile=0 +OutputObjs=0 +ConsoleApp=1 +DebugInfo=0 +RemoteSymbols=0 +MinStackSize=16384 +MaxStackSize=1048576 +ImageBase=4194304 +ExeDescription= +[Directories] +OutputDir= +UnitOutputDir= +PackageDLLOutputDir= +PackageDCPOutputDir= +SearchPath=\lab\common;C:\lab\common\DelphiX2000_0717-2\Source;\lab\common\fastlib;\lab\common\pshost;C:\lab\common\G32 +Packages=Vcl50;Vclx50;VclSmp50;Qrpt50;Vcldb50;Vclbde50;ibevnt50;vcldbx50;TeeUI50;TeeDB50;Tee50;TeeQR50;VCLIB50;vclie50;Inetdb50;Inet50;NMFast50;dclocx50;dclaxserver50;temppak;janDrawPack;pdpak +Conditionals= +DebugSourceDirs= +UsePackages=0 +[Parameters] +RunParams= +HostApplication= +[Language] +ActiveLang= +ProjectLang=$0000040B +RootDir= +[Version Info] +IncludeVerInfo=1 +AutoIncBuild=1 +MajorVer=0 +MinorVer=1 +Release=1 +Build=77 +Debug=0 +PreRelease=1 +Special=0 +Private=0 +DLL=0 +Locale=1033 +CodePage=1252 +[Version Info Keys] +CompanyName= +FileDescription= +FileVersion=0.1.1.77 +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName=Framestein +ProductVersion=1.0.0.0 +Comments= +[HistoryLists\hlUnitAliases] +Count=1 +Item0=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; +[HistoryLists\hlSearchPath] +Count=4 +Item0=\lab\common;C:\lab\common\DelphiX2000_0717-2\Source;\lab\common\fastlib;\lab\common\pshost;C:\lab\common\G32 +Item1=\lab\common;C:\lab\common\DelphiX2000_0717-2\Source;\lab\common\fastlib;\lab\common\pshost +Item2=\lab\common;C:\lab\common\DelphiX2000_0717-2\Source;\lab\common\fastlib +Item3=\lab\common;C:\lab\common\DelphiX2000_0717-2\Source diff --git a/Source/Framestein.dpr b/Source/Framestein.dpr new file mode 100644 index 0000000..4dd00b2 --- /dev/null +++ b/Source/Framestein.dpr @@ -0,0 +1,46 @@ +{ Copyright (C) 2001-2002 Juha Vehviläinen + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details.} + +program Framestein; + +{%ToDo 'Framestein.todo'} + +uses + Forms, + mainunit in 'mainunit.pas' {main}, + fsframeunit in 'fsframeunit.pas' {fsframe}, + fscopyunit in 'fscopyunit.pas' {fscopy}, + fstextunit in 'fstextunit.pas' {fstext}, + fsformunit in 'fsformunit.pas', + fsdrawunit in 'fsdrawunit.pas' {fsdraw}, + effectsunit in 'effectsunit.pas', + pluginunit in 'pluginunit.pas', + logunit in 'logunit.pas' {log}, + fsbrowserunit in 'fsbrowserunit.pas' {fsbrowser}, + fsinfounit in 'fsinfounit.pas' {fsinfo}, + configureunit in 'configureunit.pas' {configure}, + pshostunit in 'pshostunit.pas', + fsaviunit in 'fsaviunit.pas' {FsAvi}, + progressunit in 'progressunit.pas' {Progress}; + +{$R *.RES} + +begin + Application.Initialize; + Application.Title := 'Framestein'; + Application.CreateForm(Tmain, main); + Application.CreateForm(Tlog, log); + Application.CreateForm(Tconfigure, configure); + Application.CreateForm(TFsAvi, FsAvi); + Application.CreateForm(TProgress, Progress); + Application.Run; +end. + diff --git a/Source/Framestein.dsk b/Source/Framestein.dsk new file mode 100644 index 0000000..69b37b9 --- /dev/null +++ b/Source/Framestein.dsk @@ -0,0 +1,222 @@ +[Closed Files] +File_0=SourceModule,'c:\lab\Framestein\mainunit.pas',0,1,417,14,429,1,0 +File_1=SourceModule,'c:\lab\Framestein\fsframeunit.pas',0,1,746,1,758,1,0 +File_2=SourceModule,'c:\lab\Framestein\fsaviunit.pas',0,1,45,12,56,0,0 +File_3=SourceModule,'c:\lab\Framestein\FsAviWriter.pas',0,1,312,15,323,0,0 +File_4=SourceModule,'C:\lab\Framestein\progressunit.pas',0,1,1,13,10,0,0 +File_5=SourceModule,'c:\lab\Framestein\logunit.pas',0,1,38,1,53,1,0 +File_6=SourceModule,'c:\lab\framestein\fsspeedbutton.pas',0,1,30,1,40,0,0 +File_7=SourceModule,'c:\lab\Framestein\fsbrowserunit.pas',0,1,93,1,105,0,0 +File_8=SourceModule,'c:\lab\Framestein\pluginunit.pas',0,1,134,1,147,0,0 +File_9=SourceModule,'c:\lab\common\Strz.pas',0,1,1,1,1,0,0 + +[Modules] +Count=0 +EditWindowCount=0 + +[C:\Program Files\Borland\Delphi5\Projects\ProjectGroup1.bpg] +FormState=0 +FormOnTop=0 + +[c:\lab\Framestein\framestein.dpr] +FormState=0 +FormOnTop=0 + +[c:\lab\Framestein\Framestein.todo] +FormState=0 +FormOnTop=0 + +[Watches] +Count=1 +Watch0='longint(pointer(_pshost.fdata+100+((i-1)*4)^)',256,0,18,1,0 + +[Breakpoints] +Count=0 + +[AddressBreakpoints] +Count=0 + +[Main Window] +Create=1 +Visible=1 +State=2 +Left=0 +Top=0 +Width=1024 +Height=105 +MaxLeft=-4 +MaxTop=-4 +MaxWidth=1032 +MaxHeight=105 +ClientWidth=1024 +ClientHeight=78 + +[ProjectManager] +Create=1 +Visible=0 +State=0 +Left=245 +Top=124 +Width=148 +Height=449 +MaxLeft=-1 +MaxTop=-1 +ClientWidth=140 +ClientHeight=425 +TBDockHeight=494 +LRDockWidth=140 +Dockable=1 + +[CPUWindow] +Create=1 +Visible=0 +State=0 +Left=463 +Top=216 +Width=533 +Height=353 +MaxLeft=-1 +MaxTop=-1 +ClientWidth=525 +ClientHeight=326 +DumpPane=79 +DisassemblyPane=187 +RegisterPane=231 +FlagPane=64 + +[AlignmentPalette] +Create=1 +Visible=1 +State=0 +Left=36 +Top=641 +Width=156 +Height=82 +MaxLeft=-1 +MaxTop=-1 +ClientWidth=150 +ClientHeight=60 + +[PropertyInspector] +Create=1 +Visible=1 +State=0 +Left=0 +Top=97 +Width=241 +Height=639 +MaxLeft=-1 +MaxTop=-1 +ClientWidth=231 +ClientHeight=613 +TBDockHeight=494 +LRDockWidth=190 +Dockable=0 +SplitPos=140 +ArrangeBy=Name +SelectedItem= +ExpandedItems=Anchors,Display,Font,Font.Style,Options,Pen,VertScrollBar +HiddenCategories= +ShowStatusBar=1 + +[WatchWindow] +Create=1 +Visible=0 +State=0 +Left=246 +Top=567 +Width=813 +Height=187 +MaxLeft=-1 +MaxTop=-1 +ClientWidth=805 +ClientHeight=163 +TBDockHeight=65 +LRDockWidth=421 +Dockable=1 + +[BreakpointWindow] +Create=1 +Visible=0 +State=0 +Left=298 +Top=323 +Width=556 +Height=236 +MaxLeft=-1 +MaxTop=-1 +ClientWidth=548 +ClientHeight=212 +TBDockHeight=197 +LRDockWidth=737 +Dockable=1 +Column0Width=100 +Column1Width=60 +Column2Width=240 +Column3Width=40 +Column4Width=75 +Column5Width=75 + +[CallStackWindow] +Create=1 +Visible=1 +State=0 +Left=365 +Top=303 +Width=290 +Height=161 +MaxLeft=-1 +MaxTop=-1 +ClientWidth=282 +ClientHeight=137 +TBDockHeight=161 +LRDockWidth=294 +Dockable=1 + +[ThreadStatusWindow] +Create=1 +Visible=0 +State=0 +Left=193 +Top=107 +Width=624 +Height=152 +MaxLeft=-1 +MaxTop=-1 +ClientWidth=616 +ClientHeight=128 +TBDockHeight=152 +LRDockWidth=624 +Dockable=1 +Column0Width=145 +Column1Width=100 +Column2Width=115 +Column3Width=250 + +[ToDo List] +Create=1 +Visible=1 +State=0 +Left=244 +Top=427 +Width=753 +Height=296 +MaxLeft=-1 +MaxTop=-1 +ClientWidth=745 +ClientHeight=272 +TBDockHeight=170 +LRDockWidth=896 +Dockable=0 +Column0Width=564 +Column1Width=30 +Column2Width=100 +Column3Width=70 +Column4Width=70 +SortOrder=0 +ShowHints=1 +ShowChecked=1 + +[DockHosts] +DockHostCount=0 + diff --git a/Source/Framestein.res b/Source/Framestein.res new file mode 100644 index 0000000..ee5ac49 Binary files /dev/null and b/Source/Framestein.res differ diff --git a/Source/FsAviWriter.pas b/Source/FsAviWriter.pas new file mode 100644 index 0000000..6373846 --- /dev/null +++ b/Source/FsAviWriter.pas @@ -0,0 +1,888 @@ +unit FsAviWriter; + +// +// FSAviWriter - Framestein modified version of AviWriter. +// + +///////////////////////////////////////////////////////////////////////////// +// // +// AviWriter -- a component to create rudimentary AVI files // +// by Elliott Shevin, with large pieces of code // +// stolen from Anders Melander // +// version 1.0. Please send comments, suggestions, and advice // +// to shevine@aol.com. // +///////////////////////////////////////////////////////////////////////////// +// // +// AviWriter will build an AVI file containing one stream of any // +// number of TBitmaps, plus a single WAV file. // +// // +// Properties: // +// Bitmaps : A TList of pointers to TBitmap objects which become // +// frames of the AVI video stream. The component // +// allocates and frees the TList, but the caller // +// is responsible for managing the TBitmaps themselves. // +// Manipulate the list as you would any other TList. // +// At least one bitmap is required. // +// Height, Width: // +// The dimensions of the AVI video, in pixels. // +// FrameTime: // +// The duration of each video frame, in milliseconds. // +// Stretch: If TRUE, each TBitmap on the Bitmaps list is // +// stretches to the dimensions specified in Height // +// and Width. If FALSE, each TBitmap is copied from // +// its upper left corner without stretching. // +// FileName: The name of the AVI file to be written. // +// WAVFileName: // +// The name of a WAV file which will become the audio // +// stream for the AVI. Optional. // +// // +// Method: // +// Write: Creates the AVI file named by FileName. // +///////////////////////////////////////////////////////////////////////////// +// Wish List: // +// I'd like to be able to enhance this component in two ways, but // +// don't know how. Please send ideas to shevine@aol.com. // +// 1. So far, it's necessary to transform the video stream into // +// and AVI file on disk. I'd prefer to do this in memory. // +// 2. MIDI files for audio. // +///////////////////////////////////////////////////////////////////////////// + +interface + +uses + Windows,Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, + StdCtrls, DIB, +{$ifdef VER90} + ole2; +{$else} + ActiveX; +{$endif} + +//////////////////////////////////////////////////////////////////////////////// +// // +// Video for Windows // +// // +//////////////////////////////////////////////////////////////////////////////// +// // +// Adapted from Thomas Schimming's VFW.PAS // +// (c) 1996 Thomas Schimming, schimmin@iee1.et.tu-dresden.de // +// (c) 1998,99 Anders Melander // +// // +//////////////////////////////////////////////////////////////////////////////// +// // +// Ripped all COM/ActiveX stuff and added some AVI stream functions. // +// // +//////////////////////////////////////////////////////////////////////////////// + +type + + { TAVIFileInfoW record } + + LONG = Longint; + PVOID = Pointer; + +// TAVIFileInfo dwFlag values +const + AVIF_HASINDEX = $00000010; + AVIF_MUSTUSEINDEX = $00000020; + AVIF_ISINTERLEAVED = $00000100; + AVIF_WASCAPTUREFILE = $00010000; + AVIF_COPYRIGHTED = $00020000; + AVIF_KNOWN_FLAGS = $00030130; + + AVIERR_UNSUPPORTED = $80044065; // MAKE_AVIERR(101) + AVIERR_BADFORMAT = $80044066; // MAKE_AVIERR(102) + AVIERR_MEMORY = $80044067; // MAKE_AVIERR(103) + AVIERR_INTERNAL = $80044068; // MAKE_AVIERR(104) + AVIERR_BADFLAGS = $80044069; // MAKE_AVIERR(105) + AVIERR_BADPARAM = $8004406A; // MAKE_AVIERR(106) + AVIERR_BADSIZE = $8004406B; // MAKE_AVIERR(107) + AVIERR_BADHANDLE = $8004406C; // MAKE_AVIERR(108) + AVIERR_FILEREAD = $8004406D; // MAKE_AVIERR(109) + AVIERR_FILEWRITE = $8004406E; // MAKE_AVIERR(110) + AVIERR_FILEOPEN = $8004406F; // MAKE_AVIERR(111) + AVIERR_COMPRESSOR = $80044070; // MAKE_AVIERR(112) + AVIERR_NOCOMPRESSOR = $80044071; // MAKE_AVIERR(113) + AVIERR_READONLY = $80044072; // MAKE_AVIERR(114) + AVIERR_NODATA = $80044073; // MAKE_AVIERR(115) + AVIERR_BUFFERTOOSMALL = $80044074; // MAKE_AVIERR(116) + AVIERR_CANTCOMPRESS = $80044075; // MAKE_AVIERR(117) + AVIERR_USERABORT = $800440C6; // MAKE_AVIERR(198) + AVIERR_ERROR = $800440C7; // MAKE_AVIERR(199) + +type + TAVIFileInfoW = record + dwMaxBytesPerSec, // max. transfer rate + dwFlags, // the ever-present flags + dwCaps, + dwStreams, + dwSuggestedBufferSize, + + dwWidth, + dwHeight, + + dwScale, + dwRate, // dwRate / dwScale == samples/second + dwLength, + + dwEditCount: DWORD; + + szFileType: array[0..63] of WideChar; // descriptive string for file type? + end; + PAVIFileInfoW = ^TAVIFileInfoW; + +// TAVIStreamInfo dwFlag values +const + AVISF_DISABLED = $00000001; + AVISF_VIDEO_PALCHANGES= $00010000; + AVISF_KNOWN_FLAGS = $00010001; + +type + TAVIStreamInfoA = record + fccType, + fccHandler, + dwFlags, // Contains AVITF_* flags + dwCaps: DWORD; + wPriority, + wLanguage: WORD; + dwScale, + dwRate, // dwRate / dwScale == samples/second + dwStart, + dwLength, // In units above... + dwInitialFrames, + dwSuggestedBufferSize, + dwQuality, + dwSampleSize: DWORD; + rcFrame: TRect; + dwEditCount, + dwFormatChangeCount: DWORD; + szName: array[0..63] of AnsiChar; + end; + TAVIStreamInfo = TAVIStreamInfoA; + PAVIStreamInfo = ^TAVIStreamInfo; + + { TAVIStreamInfoW record } + + TAVIStreamInfoW = record + fccType, + fccHandler, + dwFlags, // Contains AVITF_* flags + dwCaps: DWORD; + wPriority, + wLanguage: WORD; + dwScale, + dwRate, // dwRate / dwScale == samples/second + dwStart, + dwLength, // In units above... + dwInitialFrames, + dwSuggestedBufferSize, + dwQuality, + dwSampleSize: DWORD; + rcFrame: TRect; + dwEditCount, + dwFormatChangeCount: DWORD; + szName: array[0..63] of WideChar; + end; + + PAVIStream = pointer; + PAVIFile = pointer; + TAVIStreamList = array[0..0] of PAVIStream; + PAVIStreamList = ^TAVIStreamList; + TAVISaveCallback = function (nPercent: integer): LONG; stdcall; + + TAVICompressOptions = packed record + fccType : DWORD; + fccHandler : DWORD; + dwKeyFrameEvery : DWORD; + dwQuality : DWORD; + dwBytesPerSecond : DWORD; + dwFlags : DWORD; + lpFormat : pointer; + cbFormat : DWORD; + lpParms : pointer; + cbParms : DWORD; + dwInterleaveEvery : DWORD; + end; + PAVICompressOptions = ^TAVICompressOptions; + +const + ICMF_CHOOSE_KEYFRAME = $0001; // show KeyFrame Every box + ICMF_CHOOSE_DATARATE = $0002; // show DataRate box + ICMF_CHOOSE_PREVIEW = $0004; // allow expanded preview dialog + +// Palette change data record +const + RIFF_PaletteChange: DWORD = 1668293411; +type + TAVIPalChange = packed record + bFirstEntry : byte; + bNumEntries : byte; + wFlags : WORD; + peNew : array[byte] of TPaletteEntry; + end; + PAVIPalChange = ^TAVIPalChange; + + APAVISTREAM = array[0..1] of PAVISTREAM; + APAVICompressOptions = array[0..1] of PAVICompressOptions; + PAPAVICompressOptions = ^APAVICompressOptions; + +procedure AVIFileInit; stdcall; +procedure AVIFileExit; stdcall; +function AVIFileOpen(var ppfile: PAVIFile; szFile: PChar; uMode: UINT; lpHandler: pointer): HResult; stdcall; +function AVIFileCreateStream(pfile: PAVIFile; var ppavi: PAVISTREAM; var psi: TAVIStreamInfo): HResult; stdcall; +function AVIStreamSetFormat(pavi: PAVIStream; lPos: LONG; lpFormat: pointer; cbFormat: LONG): HResult; stdcall; +function AVIStreamReadFormat(pavi: PAVIStream; lPos: LONG; lpFormat: pointer; var cbFormat: LONG): HResult; stdcall; +function AVIStreamWrite(pavi: PAVIStream; lStart, lSamples: LONG; lpBuffer: pointer; cbBuffer: LONG; dwFlags: DWORD; var plSampWritten: LONG; var plBytesWritten: LONG): HResult; stdcall; +function AVIStreamRelease(pavi: PAVISTREAM): ULONG; stdcall; +function AVIFileRelease(pfile: PAVIFile): ULONG; stdcall; +function AVIFileGetStream(pfile: PAVIFile; var ppavi: PAVISTREAM; fccType: DWORD; lParam: LONG): HResult; stdcall; +function CreateEditableStream(var ppsEditable: PAVISTREAM; psSource: PAVISTREAM): HResult; stdcall; +function AVISaveV(szFile: PChar; pclsidHandler: PCLSID; lpfnCallback: TAVISaveCallback; + nStreams: integer; pavi: APAVISTREAM; lpOptions: APAVICompressOptions): HResult; stdcall; +function AVISaveOptions(hwnd: HWND; uiFlags: UINT; nStreams: integer; + ppavi: APAVISTREAM; plpOptions: PAPAVICOMPRESSOPTIONS): Boolean; stdcall; external 'avifil32.dll'; +function AVIMakeCompressedStream(var ppaviCompressed: PAVISTREAM; + ppaviSource: PAVISTREAM; plpOptions: APAVICompressOptions; + pclsidHandler: PCLSID): HResult; stdcall; external 'avifil32.dll'; + +const + AVIERR_OK = 0; + + AVIIF_LIST = $01; + AVIIF_TWOCC = $02; + AVIIF_KEYFRAME = $10; + + streamtypeVIDEO = $73646976; // DWORD( 'v', 'i', 'd', 's' ) + streamtypeAUDIO = $73647561; // DWORD( 'a', 'u', 'd', 's' ) + + +type + TPixelFormat = (pfDevice, pf1bit, pf4bit, pf8bit, pf15bit, pf16bit, + pf24bit, pf32bit, pfCustom); + +type + TAviWriter = class(TComponent) + private + TempFileName : string; + pFile : PAVIFile; + fHeight : integer; + fWidth : integer; + fStretch : boolean; + fFrameTime : integer; + fFileName : string; + fWavFileName : string; + VideoStream : PAVISTREAM; + AudioStream : PAVISTREAM; + + Pstream : PAVISTREAM; + StreamInfo : TAVIStreamInfo; + + CompOptions : APAVICompressOptions; + cmp1, cmp2 : TAviCompressOptions; + + procedure AddVideo; + procedure AddAudio; + procedure InternalGetDIBSizes(Bitmap: HBITMAP; var InfoHeaderSize: Integer; + var ImageSize: longInt; PixelFormat: TPixelFormat); + function InternalGetDIB(Bitmap: HBITMAP; Palette: HPALETTE; + var BitmapInfo; var Bits; PixelFormat: TPixelFormat): Boolean; + procedure InitializeBitmapInfoHeader(Bitmap: HBITMAP; var Info: TBitmapInfoHeader; + PixelFormat: TPixelFormat); + procedure SetWavFileName(value : string); + { Private declarations } + protected + { Protected declarations } + public + Bitmaps : TList; + FramePos : Longint; + Prepared : Boolean; + fps : Integer; + constructor Create(AOwner : TComponent); override; + destructor Destroy; override; + procedure Write; + procedure Prepare; + procedure AddFrame(const DIB: TDIB); + procedure Finish; + { Public declarations } + published + property Height : integer read fHeight write fHeight; + property Width : integer read fWidth write fWidth; + property FrameTime: integer read fFrameTime write fFrameTime; + property Stretch : boolean read fStretch write fStretch; + property FileName : string read fFileName write fFileName; + property WavFileName : string read fWavFileName write SetWavFileName; + { Published declarations } + end; + +procedure Register; + +implementation + +uses + mainunit, + progressunit; + +function MAKEFOURCC(ch0, ch1, ch2, ch3: Char): Cardinal; +begin + Result := + (DWORD(BYTE(ch0))) or (DWORD(BYTE(ch1)) shl 8) or + (DWORD(BYTE(ch2)) shl 16) or (DWORD(BYTE(ch3)) shl 24 ); +end; + +constructor TAviWriter.Create(AOwner : TComponent); +var + tempdir : string; + l : integer; +begin + inherited Create(AOwner); + fHeight := screen.height div 10; + fWidth := screen.width div 10; + fFrameTime := 1000; + fStretch := true; + fFileName := ''; + Bitmaps := TList.create; + AVIFileInit; + + setlength(tempdir,MAX_PATH + 1); + l := GetTempPath(MAX_PATH,pchar(tempdir)); + setlength(tempdir,l); + if copy(tempdir,length(tempdir),1) <> '\' + then tempdir := tempdir + '\'; + TempFileName := tempdir + '~AWTemp.avi'; + Prepared := False; + + CompOptions[0] := @cmp1; + CompOptions[1] := @cmp2; + + FillChar(cmp1, Sizeof(cmp1), 0); + FillChar(cmp2, Sizeof(cmp1), 0); + + cmp1.fccType := streamtypeVIDEO; + cmp1.fccHandler := MakeFourCC('m','j','p','g'); +// cmp1.dwQuality := + + fps := 25; +end; + +destructor TAviWriter.Destroy; +begin + Bitmaps.free; + AviFileExit; + inherited; +end; + +procedure TAviWriter.Write; +var + Bitmap : TBitmap; + ExtBitmap : TBitmap; + nstreams : integer; + i : integer; + Streams : APAVISTREAM; + CompOptions : APAVICompressOptions; + AVIERR : integer; + refcount : integer; +begin + AudioStream := nil; + VideoStream := nil; + + // If no bitmaps are on the list, raise an error. + if Bitmaps.count < 1 then + raise Exception.Create('No bitmaps on the Bitmaps list'); + + // If anything on the Bitmaps TList is not a bitmap, raise + // an error. + for i := 0 to Bitmaps.count - 1 do begin + ExtBitmap := Bitmaps[i]; + if not(ExtBitmap is TBitmap) + then raise Exception.Create('Bitmaps[' + inttostr(i) + + '] is not a TBitmap'); + end; + + try + AddVideo; + + if WavFileName <> '' + then AddAudio; + + // Create the output file. + if WavFileName <> '' + then nstreams := 2 + else nstreams := 1; + + Streams[0] := VideoStream; + Streams[1] := AudioStream; + CompOptions[0] := nil; + CompOptions[1] := nil; + + AVIERR := AVISaveV(pchar(FileName), + nil, // File handler + nil, // Callback + nStreams, // Number of streams Streams, CompOptions); // Compress options for VideoStream if AVIERR <> AVIERR_OK then raise Exception.Create('Unable to write output file'); finally if assigned(VideoStream) then AviStreamRelease(VideoStream); if assigned(AudioStream) + then AviStreamRelease(AudioStream); try repeat + refcount := AviFileRelease(pFile); + until refcount <= 0; + except + end; + + DeleteFile(TempFileName); + end; +end; + +procedure TAviWriter.AddVideo; +var + Pstream : PAVISTREAM; + StreamInfo : TAVIStreamInfo; + BitmapInfo : PBitmapInfoHeader; + BitmapInfoSize : Integer; + BitmapSize : longInt; + BitmapBits : pointer; + Bitmap : TBitmap; + ExtBitmap : TBitmap; + Samples_Written : LONG; + Bytes_Written : LONG; + AVIERR : integer; + i : integer; + startpos : DWORD; + len : DWORD; +begin + + // Open AVI file for write + if (AVIFileOpen(pFile, pchar(TempFileName), + OF_WRITE or OF_CREATE OR OF_SHARE_EXCLUSIVE, nil) + <> AVIERR_OK) + then + raise Exception.Create('Failed to create AVI video work file'); + + // Allocate the bitmap to which the bitmaps on the Bitmaps Tlist + // will be copied. + Bitmap := TBitmap.create; + Bitmap.Height := self.Height; + Bitmap.Width := self.Width; + + // Write the stream header. + try + FillChar(StreamInfo, sizeof(StreamInfo), 0); + + // Set frame rate and scale + StreamInfo.dwRate := 1000; + StreamInfo.dwScale := fFrameTime; + StreamInfo.fccType := streamtypeVIDEO; + StreamInfo.fccHandler := 0; + StreamInfo.dwFlags := 0; + StreamInfo.dwSuggestedBufferSize := 0; + StreamInfo.rcFrame.Right := self.width; + StreamInfo.rcFrame.Bottom := self.height; + + // Open AVI data stream + if (AVIFileCreateStream(pFile, pStream, StreamInfo) <> AVIERR_OK) then + raise Exception.Create('Failed to create AVI video stream'); + + try + // Write the bitmaps to the stream. + for i := 0 to Bitmaps.count - 1 do begin + try + BitmapInfo := nil; + BitmapBits := nil; + + // Copy the bitmap from the list to the AVI bitmap, + // stretching if desired. If the caller elects not to + // stretch, use the first pixel in the bitmap as a + // background color in case either the height or + // width of the source is smaller than the output. + // If Draw fails, do a StretchDraw. + ExtBitmap := Bitmaps[i]; + if fStretch + then Bitmap.Canvas.StretchDraw + (Rect(0,0,self.width,self.height),ExtBitmap) + else try + with Bitmap.Canvas do begin + Brush.Color := ExtBitmap.Canvas.Pixels[0,0]; + Brush.Style := bsSolid; + FillRect(Rect(0,0,Bitmap.Width,Bitmap.Height)); + Draw(0,0,ExtBitmap); + end; + except + Bitmap.Canvas.StretchDraw + (Rect(0,0,self.width,self.height),ExtBitmap); + end; + + // Determine size of DIB + InternalGetDIBSizes(Bitmap.Handle, BitmapInfoSize, BitmapSize, pf8bit); + if (BitmapInfoSize = 0) then + raise Exception.Create('Failed to retrieve bitmap info'); + + // Get DIB header and pixel buffers + GetMem(BitmapInfo, BitmapInfoSize); + GetMem(BitmapBits, BitmapSize); + InternalGetDIB + (Bitmap.Handle, 0, BitmapInfo^, BitmapBits^, pf8bit); + + // On the first time through, set the stream format. + if i = 0 then + if (AVIStreamSetFormat(pStream, 0, BitmapInfo, BitmapInfoSize) <> AVIERR_OK) then + raise Exception.Create('Failed to set AVI stream format'); + + // Write frame to the video stream + AVIERR := + AVIStreamWrite(pStream, i, 1, BitmapBits, BitmapSize, AVIIF_KEYFRAME, + Samples_Written, Bytes_Written); + if AVIERR <> AVIERR_OK then + raise Exception.Create + ('Failed to add frame to AVI. Err=' + + inttohex(AVIERR,8)); + finally + if (BitmapInfo <> nil) then + FreeMem(BitmapInfo); + if (BitmapBits <> nil) then + FreeMem(BitmapBits); + end; + end; + + // Create the editable VideoStream from pStream. + if CreateEditableStream(VideoStream,pStream) <> AVIERR_OK then + raise Exception.Create + ('Could not create Video Stream'); + finally + AviStreamRelease(pStream); + end; + + finally + Bitmap.free; + end; +end; + +procedure TAviWriter.AddAudio; +var + InputFile : PAVIFILE; + hr : integer; + InputStream : PAVIStream; + avisClip : TAVISTREAMINFO; + l, selstart : DWORD; + pastecode : integer; +begin + // Open the audio file. + hr := AVIFileOpen(InputFile, pchar(WavFileName),OF_READ, nil); + case hr of + 0: ; + AVIERR_BADFORMAT : raise Exception.Create('The file could not be read, indicating a corrupt file or an unrecognized format.'); + AVIERR_MEMORY : raise Exception.Create('The file could not be opened because of insufficient memory.'); + AVIERR_FILEREAD : raise Exception.Create('A disk error occurred while reading the audio file.'); + AVIERR_FILEOPEN : raise Exception.Create('A disk error occurred while opening the audio file.'); + REGDB_E_CLASSNOTREG : raise Exception.Create('According to the registry, the type of audio file specified in AVIFileOpen does not have a handler to process it.'); + else raise Exception.Create('Unknown error opening audio file'); + end; + + // Open the audio stream. + try + if (AVIFileGetStream(InputFile, InputStream, 0, 0) <> AVIERR_OK) then + raise Exception.Create('Unable to get audio stream'); + + try + // Create AudioStream as a copy of InputStream + if (CreateEditableStream(AudioStream,InputStream) <> AVIERR_OK) then + raise Exception.Create('Failed to create editable AVI audio stream'); + finally + AviStreamRelease(InputStream); + end; + + finally + AviFileRelease(InputFile); + end; +end; + +// -------------- +// InternalGetDIB +// -------------- +// Converts a bitmap to a DIB of a specified PixelFormat. +// +// Parameters: +// Bitmap The handle of the source bitmap. +// Pal The handle of the source palette. +// BitmapInfo The buffer that will receive the DIB's TBitmapInfo structure. +// A buffer of sufficient size must have been allocated prior to +// calling this function. +// Bits The buffer that will receive the DIB's pixel data. +// A buffer of sufficient size must have been allocated prior to +// calling this function. +// PixelFormat The pixel format of the destination DIB. +// +// Returns: +// True on success, False on failure. +// +// Note: The InternalGetDIBSizes function can be used to calculate the +// nescessary sizes of the BitmapInfo and Bits buffers. +// +function TAviWriter.InternalGetDIB(Bitmap: HBITMAP; Palette: HPALETTE; + var BitmapInfo; var Bits; PixelFormat: TPixelFormat): Boolean; +// From graphics.pas, "optimized" for our use +var + OldPal : HPALETTE; + DC : HDC; +begin + InitializeBitmapInfoHeader(Bitmap, TBitmapInfoHeader(BitmapInfo), PixelFormat); + OldPal := 0; + DC := CreateCompatibleDC(0); + try + if (Palette <> 0) then + begin + OldPal := SelectPalette(DC, Palette, False); + RealizePalette(DC); + end; + Result := (GetDIBits(DC, Bitmap, 0, abs(TBitmapInfoHeader(BitmapInfo).biHeight), + @Bits, TBitmapInfo(BitmapInfo), DIB_RGB_COLORS) <> 0); + finally + if (OldPal <> 0) then + SelectPalette(DC, OldPal, False); + DeleteDC(DC); + end; +end; + + +// ------------------- +// InternalGetDIBSizes +// ------------------- +// Calculates the buffer sizes nescessary for convertion of a bitmap to a DIB +// of a specified PixelFormat. +// See the GetDIBSizes API function for more info. +// +// Parameters: +// Bitmap The handle of the source bitmap. +// InfoHeaderSize +// The returned size of a buffer that will receive the DIB's +// TBitmapInfo structure. +// ImageSize The returned size of a buffer that will receive the DIB's +// pixel data. +// PixelFormat The pixel format of the destination DIB. +// +procedure TAviWriter.InternalGetDIBSizes(Bitmap: HBITMAP; var InfoHeaderSize: Integer; + var ImageSize: longInt; PixelFormat: TPixelFormat); +// From graphics.pas, "optimized" for our use +var + Info : TBitmapInfoHeader; +begin + InitializeBitmapInfoHeader(Bitmap, Info, PixelFormat); + // Check for palette device format + if (Info.biBitCount > 8) then + begin + // Header but no palette + InfoHeaderSize := SizeOf(TBitmapInfoHeader); + if ((Info.biCompression and BI_BITFIELDS) <> 0) then + Inc(InfoHeaderSize, 12); + end else + // Header and palette + InfoHeaderSize := SizeOf(TBitmapInfoHeader) + SizeOf(TRGBQuad) * (1 shl Info.biBitCount); + ImageSize := Info.biSizeImage; +end; + +// -------------------------- +// InitializeBitmapInfoHeader +// -------------------------- +// Fills a TBitmapInfoHeader with the values of a bitmap when converted to a +// DIB of a specified PixelFormat. +// +// Parameters: +// Bitmap The handle of the source bitmap. +// Info The TBitmapInfoHeader buffer that will receive the values. +// PixelFormat The pixel format of the destination DIB. +// +{$IFDEF BAD_STACK_ALIGNMENT} + // Disable optimization to circumvent optimizer bug... + {$IFOPT O+} + {$DEFINE O_PLUS} + {$O-} + {$ENDIF} +{$ENDIF} + + +procedure TAviWriter.InitializeBitmapInfoHeader(Bitmap: HBITMAP; var Info: TBitmapInfoHeader; + PixelFormat: TPixelFormat); +// From graphics.pas, "optimized" for our use +var + DIB : TDIBSection; + Bytes : Integer; + function AlignBit(Bits, BitsPerPixel, Alignment: Cardinal): Cardinal; + begin + Dec(Alignment); + Result := ((Bits * BitsPerPixel) + Alignment) and not Alignment; + Result := Result SHR 3; + end; +begin + DIB.dsbmih.biSize := 0; + Bytes := GetObject(Bitmap, SizeOf(DIB), @DIB); + if (Bytes = 0) then + raise Exception.Create('Invalid bitmap'); +// Error(sInvalidBitmap); + + if (Bytes >= (sizeof(DIB.dsbm) + sizeof(DIB.dsbmih))) and + (DIB.dsbmih.biSize >= sizeof(DIB.dsbmih)) then + Info := DIB.dsbmih + else + begin + FillChar(Info, sizeof(Info), 0); + with Info, DIB.dsbm do + begin + biSize := SizeOf(Info); + biWidth := bmWidth; + biHeight := bmHeight; + end; + end; + case PixelFormat of + pf1bit: Info.biBitCount := 1; + pf4bit: Info.biBitCount := 4; + pf8bit: Info.biBitCount := 8; + pf24bit: Info.biBitCount := 24; + else +// Error(sInvalidPixelFormat); + raise Exception.Create('Invalid pixel foramt'); + // Info.biBitCount := DIB.dsbm.bmBitsPixel * DIB.dsbm.bmPlanes; + end; + Info.biPlanes := 1; + Info.biCompression := BI_RGB; // Always return data in RGB format + Info.biSizeImage := AlignBit(Info.biWidth, Info.biBitCount, 32) * Cardinal(abs(Info.biHeight)); +end; +{$IFDEF O_PLUS} + {$O+} + {$UNDEF O_PLUS} +{$ENDIF} + +procedure TAviWriter.SetWavFileName(value : string); +begin + if lowercase(fWavFileName) <> lowercase(value) + then if lowercase(ExtractFileExt(value)) <> '.wav' + then raise Exception.Create('WavFileName must name a file ' + + 'with the .wav extension') + else fWavFileName := value; +end; + + +procedure Register; +begin + RegisterComponents('Labrz', [TAviWriter]); +end; + + procedure AVIFileInit; stdcall; external 'avifil32.dll' name 'AVIFileInit'; + procedure AVIFileExit; stdcall; external 'avifil32.dll' name 'AVIFileExit'; + function AVIFileOpen; external 'avifil32.dll' name 'AVIFileOpenA'; + function AVIFileCreateStream; external 'avifil32.dll' name 'AVIFileCreateStreamA'; + function AVIStreamSetFormat; external 'avifil32.dll' name 'AVIStreamSetFormat'; + function AVIStreamReadFormat; external 'avifil32.dll' name 'AVIStreamReadFormat'; + function AVIStreamWrite; external 'avifil32.dll' name 'AVIStreamWrite'; + function AVIStreamRelease; external 'avifil32.dll' name 'AVIStreamRelease'; + function AVIFileRelease; external 'avifil32.dll' name 'AVIFileRelease'; + function AVIFileGetStream; external 'avifil32.dll' name 'AVIFileGetStream'; + function CreateEditableStream; external 'avifil32.dll' name 'CreateEditableStream'; + function AVISaveV; external 'avifil32.dll' name 'AVISaveV'; + +procedure TAviWriter.Prepare; +begin + if Prepared then begin + main.Post('Finishing previous file..'); + Finish; + end; + + AudioStream := nil; + VideoStream := nil; + + if (AVIFileOpen(pFile, pchar(TempFileName), + OF_WRITE or OF_CREATE or OF_SHARE_EXCLUSIVE, nil) <> AVIERR_OK) then + raise Exception.Create('Failed to create AVI video work file'); + + FillChar(StreamInfo, sizeof(StreamInfo), 0); + + // Set frame rate and scale + StreamInfo.dwRate := fps*1000; + StreamInfo.dwScale := fFrameTime; + StreamInfo.fccType := streamtypeVIDEO; + StreamInfo.fccHandler := 0; + StreamInfo.dwFlags := 0; + StreamInfo.dwSuggestedBufferSize := 0; + StreamInfo.rcFrame.Right := self.width; + StreamInfo.rcFrame.Bottom := self.height; + + // Open AVI data stream + if (AVIFileCreateStream(pFile, pStream, StreamInfo) <> AVIERR_OK) then + raise Exception.Create('Failed to create AVI video stream'); + + FramePos := 0; + Prepared := True; +end; + +procedure TAviWriter.AddFrame(const DIB: TDIB); +var + Samples_Written : LONG; + Bytes_Written : LONG; + AVIERR : integer; +begin + if not Prepared then begin + main.Post('fs.avi: internal error, not prepared to add frame.'); + Exit; + end; + + // On the first time through, set the stream format. + if FramePos = 0 then begin + if (AVIStreamSetFormat(pStream, 0, DIB.BitmapInfo, DIB.BitmapInfoSize) <> AVIERR_OK) then + raise Exception.Create('Failed to set AVI stream format'); + end; + + // Write frame to the video stream + AVIERR := AVIStreamWrite(pStream, FramePos, 1, DIB.PBits, DIB.Size, AVIIF_KEYFRAME, + Samples_Written, Bytes_Written); + + Inc(FramePos); + + if AVIERR <> AVIERR_OK then + raise Exception.Create('Failed to add frame to AVI. Err='+ + inttohex(AVIERR,8)); +end; + +function avisavecallback(nPercent: UINT): ULONG; stdcall; +begin +// Write('fs.avi: '+IntToStr(nPercent)+'%'+#13); + Progress.pb1.Position := nPercent; + Result := AVIERR_OK; +end; + +procedure TAviWriter.Finish; +var + nstreams: Integer; + Streams : APAVISTREAM; + AVIERR : integer; + refcount : integer; +begin + if not Prepared then begin + main.Post('fs.avi: nothing to write.'); + Exit; + end; + + if CreateEditableStream(VideoStream,pStream) <> AVIERR_OK then + raise Exception.Create('Could not create Video Stream'); + + AviStreamRelease(pStream); + + nstreams := 1; + + Streams[0] := VideoStream; + Streams[1] := nil;//AudioStream; + + if AVISaveOptions(0, ICMF_CHOOSE_PREVIEW, nStreams, Streams, @CompOptions) then begin + + Progress.Show; + + AVIERR := AVISaveV(pchar(FileName), + nil, // File handler + @avisavecallback, // Callback + nStreams, // Number of streams Streams, CompOptions); // Compress options for VideoStream Progress.Hide; // I get some strange error but the file is always ok so... screw it { if AVIERR <> AVIERR_OK then raise Exception.Create('Error on write - check output file.'); } if assigned(VideoStream) then AviStreamRelease(VideoStream); if assigned(AudioStream) + then AviStreamRelease(AudioStream); try repeat + refcount := AviFileRelease(pFile); + until refcount <= 0; + except + end; + + DeleteFile(TempFileName); + + Prepared := False; + end; +end; + +end. + diff --git a/Source/GPL.txt b/Source/GPL.txt new file mode 100644 index 0000000..14db8fc --- /dev/null +++ b/Source/GPL.txt @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/Source/README.txt b/Source/README.txt new file mode 100644 index 0000000..4037c52 --- /dev/null +++ b/Source/README.txt @@ -0,0 +1,36 @@ +To compile: + + +- Install DelphiX by Hiroyuki Hori, http://www.yks.ne.jp/~hori/ + +The above link doesn't always work, try these: + +http://turbo.gamedev.net/DelphiX2000_0717a.zip +http://turbo.gamedev.net/delphix.asp + + +- Install FastLib by G-Soft, http://gfody.com + + +- Install TScanDir in Filez.pas (in this directory). + + +- Correct your Search path and compile! + + +- Framestein needs ijl15.dll (included in Framestein-directory) to load/save jpegs + and to send jpeg-compressed frames thru network. + + +--- note to versions >= 0.27 --- + + +The photoshop filter host functionality is based on commercial code from http://www.case2000.com. +Due to my modifications the original component won't compile with Framestein and +I don't have the permission to release my modified version. + +To compile Fs without the PSHost, ignore errors on C2PhotoShopHost, and comment out +the implementation in pshostunit.pas. + +I'm planning a .dll of my version of the component to rid of this problem. +Mail me for info. diff --git a/Source/Strz.pas b/Source/Strz.pas new file mode 100644 index 0000000..85ad4a7 --- /dev/null +++ b/Source/Strz.pas @@ -0,0 +1,182 @@ +unit Strz; + +interface + +uses + Windows; + +type + CharSet = set of Char; + +// General +function MyStrToInt(const S: String): Integer; // some special checking, no exceptions +function MyStrToFloat(const S: String): Extended; // some special checking, no exceptions +function StrToRect(const S: String): TRect; +function Long2Str(L : LongInt) : string; +function SearchAndReplace( S, Old, New:String ):String; +function WordCount(S : string; WordDelims : CharSet) : Integer; + {-Given a set of word delimiters, return number of words in S} +function ExtractWord(N : Integer; S : string; WordDelims : CharSet) : string; + {-Given a set of word delimiters, return the N'th word in S} + +// Filez +function VerifyBackSlash( const FileName:String ):String; + +implementation + +uses + Classes, SysUtils; + +function StrToRect(const S: String): TRect; +var + i: Integer; +begin + Result := Rect(0, 0, 0, 0); + if S='' then Exit; + i := WordCount(S, [' ']); + Result.Left := MyStrToInt(ExtractWord(1, S, [' '])); + if i>1 then + Result.Top := MyStrToInt(ExtractWord(2, S, [' '])); + if i>2 then + Result.Right := MyStrToInt(ExtractWord(3, S, [' '])); + if i>3 then + Result.Bottom := MyStrToInt(ExtractWord(4, S, [' '])); +end; + +function MyStrToInt(const S: String): Integer; +var + St: String; +begin + Result := 0; + if (S='') or (S='-') or (S='0') then Exit; + try + Result := StrToInt(S); + except + St := S; + while Pos('.', St)>0 do + St[Pos('.', St)] := ','; + try Result := Trunc(StrToFloat(St)); except end; + end; +end; + +function MyStrToFloat(const S: String): Extended; +var + St: String; + i: Integer; +begin + Result := 0; + if (S='') or (S='-') or (S='0') then Exit; + St := S; + i := Pos('.', St); + if i>0 then + St[i] := ','; + try + Result := StrToFloat(St); + except + end; +end; + +function VerifyBackSlash( const FileName:String ):String; +begin + if FileName[Length(FileName)]='\' then + Result := FileName + else + Result := FileName + '\'; +end; + +function Long2Str(L : LongInt) : string; + {-Convert a long/word/integer/byte/shortint to a string} +var + S : string; +begin + Str(L, S); + Long2Str := S; +end; + +{-----} + + function WordCount(S : string; WordDelims : CharSet) : Integer; + {-Given a set of word delimiters, return number of words in S} + var + {I,} Count : Integer; {!!.12} + I, SLen : Word; {!!.12} + begin + Count := 0; + I := 1; + SLen:=Length(S); + + while I <= SLen do begin + {skip over delimiters} + while (I <= SLen) and (S[I] in WordDelims) do + Inc(I); + + {if we're not beyond end of S, we're at the start of a word} + if I <= SLen then + Inc(Count); + + {find the end of the current word} + while (I <= SLen) and not(S[I] in WordDelims) do + Inc(I); + end; + + WordCount := Count; + end; + + function ExtractWord(N : Integer; S : string; WordDelims : CharSet) : string; + {-Given a set of word delimiters, return the N'th word in S} + var + I : Word; {!!.12} + Count, Len : Integer; + SLen : Longint; + Str : String; + begin + Count := 0; + I := 1; + Len := 0; + Str := ''; + SLen := Length(S); + +// ExtractWord[0] := #0; + + while (I <= SLen) and (Count <> N) do begin + {skip over delimiters} + while (I <= SLen) and (S[I] in WordDelims) do + Inc(I); + + {if we're not beyond end of S, we're at the start of a word} + if I <= SLen then + Inc(Count); + + {find the end of the current word} + while (I <= SLen) and not(S[I] in WordDelims) do begin + {if this is the N'th word, add the I'th character to Tmp} + if Count = N then begin + Inc(Len); + SetLength(Str, Len); +// ExtractWord[0] := Char(Len); + Str[Len] := S[I]; +// ExtractWord[Len] := S[I]; + end; + + Inc(I); + end; + end; + ExtractWord := Str; + end; + +function SearchAndReplace( S, Old, New:String ):String; +var + Ts : String; + i : Integer; +begin + Ts := S; + i := Pos(Old, Ts); + while i>0 do begin + Delete(Ts, i, Length(Old)); + Insert(New, Ts, i); + i := Pos(Old, Ts); + end; + SearchAndReplace := Ts; +end; + +end. diff --git a/Source/configureunit.dfm b/Source/configureunit.dfm new file mode 100644 index 0000000..5a9e46d --- /dev/null +++ b/Source/configureunit.dfm @@ -0,0 +1,157 @@ +object configure: Tconfigure + Left = 317 + Top = 185 + Width = 443 + Height = 351 + BorderWidth = 4 + Caption = 'Configuration' + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [] + OldCreateOrder = False + Position = poScreenCenter + OnCreate = FormCreate + PixelsPerInch = 96 + TextHeight = 13 + object PageControl1: TPageControl + Left = 0 + Top = 0 + Width = 427 + Height = 275 + ActivePage = TSConnections + Align = alClient + TabOrder = 0 + object TSConnections: TTabSheet + Caption = 'Connections' + object Label1: TLabel + Left = 16 + Top = 36 + Width = 114 + Height = 13 + Caption = 'Host running Pure Data:' + end + object Label2: TLabel + Left = 16 + Top = 60 + Width = 95 + Height = 13 + Caption = 'Listen to Pd on port:' + end + object Label3: TLabel + Left = 16 + Top = 84 + Width = 103 + Height = 13 + Caption = 'Pd is listening on port:' + end + object Label4: TLabel + Left = 16 + Top = 112 + Width = 385 + Height = 13 + Caption = + 'NOTE: if you change the default ports, you need to modify fs.mai' + + 'n.pd accordingly.' + end + object Label5: TLabel + Left = 16 + Top = 164 + Width = 194 + Height = 13 + Caption = 'Listen to Framestein connections on port:' + end + object EditPdHost: TEdit + Left = 152 + Top = 32 + Width = 225 + Height = 21 + Ctl3D = True + ParentCtl3D = False + TabOrder = 0 + Text = 'localhost' + end + object EditPdReceivePort: TEdit + Left = 152 + Top = 56 + Width = 225 + Height = 21 + Ctl3D = True + ParentCtl3D = False + TabOrder = 1 + Text = '6001' + end + object EditPdSendPort: TEdit + Left = 152 + Top = 80 + Width = 225 + Height = 21 + Ctl3D = True + ParentCtl3D = False + TabOrder = 2 + Text = '6002' + end + object EditFsPort: TEdit + Left = 224 + Top = 160 + Width = 153 + Height = 21 + Ctl3D = True + ParentCtl3D = False + TabOrder = 3 + Text = '6010' + end + object CBEnableFSConns: TCheckBox + Left = 224 + Top = 184 + Width = 97 + Height = 17 + Caption = 'Enable' + TabOrder = 4 + end + end + object TSGeneral: TTabSheet + Caption = 'General' + ImageIndex = 1 + object CBDockMain: TCheckBox + Left = 16 + Top = 36 + Width = 377 + Height = 17 + Caption = 'Dock main window to Pd on connect' + TabOrder = 0 + end + end + end + object Panel1: TPanel + Left = 0 + Top = 275 + Width = 427 + Height = 41 + Align = alBottom + BevelOuter = bvNone + TabOrder = 1 + object ButtonOk: TButton + Left = 8 + Top = 8 + Width = 75 + Height = 25 + Caption = 'Ok' + Default = True + TabOrder = 0 + OnClick = ButtonOkClick + end + object ButtonCancel: TButton + Left = 96 + Top = 8 + Width = 75 + Height = 25 + Cancel = True + Caption = 'Cancel' + TabOrder = 1 + OnClick = ButtonCancelClick + end + end +end diff --git a/Source/configureunit.pas b/Source/configureunit.pas new file mode 100644 index 0000000..88dff73 --- /dev/null +++ b/Source/configureunit.pas @@ -0,0 +1,120 @@ +unit configureunit; + +interface + +uses + Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, + StdCtrls, ExtCtrls, ComCtrls; + +type + Tconfigure = class(TForm) + PageControl1: TPageControl; + TSConnections: TTabSheet; + Panel1: TPanel; + ButtonOk: TButton; + ButtonCancel: TButton; + Label1: TLabel; + EditPdHost: TEdit; + Label2: TLabel; + EditPdReceivePort: TEdit; + Label3: TLabel; + EditPdSendPort: TEdit; + Label4: TLabel; + Label5: TLabel; + EditFsPort: TEdit; + CBEnableFSConns: TCheckBox; + TSGeneral: TTabSheet; + CBDockMain: TCheckBox; + procedure ButtonCancelClick(Sender: TObject); + procedure ButtonOkClick(Sender: TObject); + procedure FormCreate(Sender: TObject); + private + { Private declarations } + public + { Public declarations } + procedure Execute; + end; + +var + configure: Tconfigure; + +implementation + +uses + Registry, + mainunit; + +{$R *.DFM} + +procedure Tconfigure.ButtonOkClick(Sender: TObject); +var + Reg: TRegistry; +begin + Reg := TRegistry.Create; + Reg.RootKey := HKEY_CURRENT_USER; + + main.PdHost := EditPdHost.Text; + main.PdReceivePort := StrToInt(EditPdReceivePort.Text); + main.PdSendPort := StrToInt(EditPdSendPort.Text); + main.FSPort := StrToInt(EditFsPort.Text); + main.EnableFSConns := CBEnableFSConns.Checked; + main.DockMain := CBDockMain.Checked; + + try + if Reg.OpenKey('\Software\Framestein', True) then begin + Reg.WriteString('PdHost', main.PdHost); + Reg.WriteInteger('PDReceivePort', main.PDReceivePort); + Reg.WriteInteger('PDSendPort', main.PDSendPort); + Reg.WriteInteger('FSPort', main.FSPort); + Reg.WriteBool('EnableFSConns', main.EnableFSConns); + Reg.WriteBool('DockMain', main.DockMain); + end; + except + end; + + Reg.CloseKey; + Reg.Free; + + main.ss1.Active := False; + main.ss1.Port := main.PDReceivePort; + main.ss1.Active := True; + + main.csToPd.Active := False; + main.csToPd.Host := main.PdHost; + main.csToPd.Port := main.PdSendPort; + main.csToPd.Active := True; + + main.ssfs.Active := False; + main.ssfs.Port := main.FSPort; + main.ssfs.Active := main.EnableFSConns; + + ModalResult := mrOk; +end; + +procedure Tconfigure.ButtonCancelClick(Sender: TObject); +begin + ModalResult := mrCancel; +end; + +procedure Tconfigure.Execute; +begin + // load values from main + EditPdHost.Text := main.PdHost; + if EditPdHost.Text='' then EditPdHost.Text:='localhost'; + EditPdReceivePort.Text := IntToStr(main.PdReceivePort); + EditPdSendPort.Text := IntToStr(main.PdSendPort); + EditFsPort.Text := IntToStr(main.FSPort); + CBEnableFSConns.Checked := main.EnableFSConns; + CBDockMain.Checked := main.DockMain; + // show + ShowModal; +end; + +procedure Tconfigure.FormCreate(Sender: TObject); +begin + if main.RunConfig then + Execute; +end; + +end. + diff --git a/Source/dc.inc b/Source/dc.inc new file mode 100644 index 0000000..a90d6f3 --- /dev/null +++ b/Source/dc.inc @@ -0,0 +1,42 @@ +{$O+,A+,W-,R-,Q-,B-,X+,T-,P+,H+,J+,C-} + +//--------------- Dream Company section ---------------------------- + +{$IFDEF VER93} +{$DEFINE BCB} +{$DEFINE CPB1} +{$ENDIF} + +{$IFNDEF VER80} + {$IFNDEF VER90} + {$IFNDEF VER93} + {$IFDEF VER110} + {$DEFINE CPB3} { C++ Builder 3.0 or higher} + {$DEFINE BCB} + {$ENDIF} + {$DEFINE D3} { Delphi 3.0 or higher } + {$ENDIF} + {$ENDIF} +{$ENDIF} + +{$IFDEF VER120} + {$DEFINE D4} + {$DEFINE D3} + {$DEFINE CPB3} +{$ENDIF} + +{$IFDEF VER125} +{$DEFINE CPB4} +{$DEFINE D4} +{$DEFINE D3} +{$DEFINE CPB3} +{$DEFINE BCB} +{$ENDIF} + +{$IFDEF VER130} +{$DEFINE CPB4} +{$DEFINE D4} +{$DEFINE D3} +{$DEFINE CPB3} +{$DEFINE D5} +{$ENDIF} diff --git a/Source/effectsunit.pas b/Source/effectsunit.pas new file mode 100644 index 0000000..791eeae --- /dev/null +++ b/Source/effectsunit.pas @@ -0,0 +1,109 @@ +{ Copyright (C) 2001 Juha Vehviläinen + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details.} + +unit effectsunit; +{This unit demonstrates how to work on the pixel level.. + + If you're adding an effect, all it takes is a couple of lines in + fsframeunit.pas to call your routine. Look for 'scramble' there + to see how. + + If you're adding a new copymode, look for all occurences of + 'dsBlend' in fscopyunit.pas to see how to do that. + + Also see everything in Framestein\Plugins-directory, you can write + effects and copymodes as plugins and never recompile framestein.. + or touch the pascal code. This is likely the way I'll be doing them + from now on, to keep the program "core" as simple and small as possible.. +} + +interface + +uses + Windows, Messages, SysUtils, Classes, Graphics, DirectX, DXDraws; + +procedure scramble(const d: TDirectDrawSurface); +procedure blend(const d1, d2: TDirectDrawSurface; const amount: Extended); + +implementation + +function ScanLine16(const sd: TDDSurfaceDesc; const y: Integer): Pointer; +begin + Result := Pointer(Integer(sd.lpSurface) + y*sd.lPitch); +end; + +procedure scramble(const d: TDirectDrawSurface); +var + x,y: Integer; + p16: PWordArray; + sd: TDDSurfaceDesc; +begin + if (d.Width=0) or (d.Height=0) then Exit; + d.Lock(sd); + case d.BitCount of + 16: for y:=0 to d.Height-1 do begin + p16 := ScanLine16(sd, y); + for x:=0 to d.Width-1 do + p16[x]:=random(16777216); + end; + end; + d.UnLock; +end; + +function r16(color: cardinal): byte; register; +begin; + result := (color shr 11) shl 3; +end; + +function g16(color: cardinal): byte; register; +begin; + result := ((color and 2016) shr 5) shl 2; +end; + +function b16(color: cardinal): byte; register; +begin; + result := (color and 31) shl 3; +end; + +procedure blend(const d1, d2: TDirectDrawSurface; const amount: Extended); +var + x, y, w, h: Integer; + p1, p2: PWordArray; + sd1, sd2: TDDSurfaceDesc; + c1,c2: cardinal; +begin + if (d1.Width=0) or (d2.Width=0) or + (d1.BitCount<>16) or (d2.BitCount<>16) then Exit; + w := d1.Width; + h := d1.Height; + if d2.Width B then + Result := A + else + Result := B; +end; + +function RectWidth(const R: TRect): Integer; +begin + with R do + Result := Right - Left; +end; + +function RectHeight(const R: TRect): Integer; +begin + with R do + Result := Bottom - Top; +end; + +{$IFNDEF D3} +function TransparentStretchBlt(DstDC: HDC; DstX, DstY, DstW, DstH: Integer; + SrcDC: HDC; SrcX, SrcY, SrcW, SrcH: Integer; MaskDC: HDC; MaskX, + MaskY: Integer): Boolean; +const + ROP_DstCopy = $00AA0029; +var + MemDC : THandle; + MemBmp : THandle; + Save : THandle; + crText : TColorRef; + crBack : TColorRef; +begin + Result := True; + if (Win32Platform = VER_PLATFORM_WIN32_NT) and (SrcW = DstW) and (SrcH = DstH) then + begin + MemBmp := CreateCompatibleBitmap(SrcDC, 1, 1); + MemBmp := SelectObject(MaskDC, MemBmp); + MaskBlt(DstDC, DstX, DstY, DstW, DstH, SrcDC, SrcX, SrcY, MemBmp, MaskX, + MaskY, MakeRop4(ROP_DstCopy, SrcCopy)); + MemBmp := SelectObject(MaskDC, MemBmp); + DeleteObject(MemBmp); + exit; + end; + + MemDC := CreateCompatibleDC(0); + MemBmp := CreateCompatibleBitmap(SrcDC, SrcW, SrcH); + Save := SelectObject(MemDC, MemBmp); + StretchBlt(MemDC, 0, 0, SrcW, SrcH, MaskDC, MaskX, MaskY, SrcW, SrcH, SrcCopy); + StretchBlt(MemDC, 0, 0, SrcW, SrcH, SrcDC, SrcX, SrcY, SrcW, SrcH, SrcErase); + crText := SetTextColor(DstDC, $0); + crBack := SetBkColor(DstDC, $FFFFFF); + StretchBlt(DstDC, DstX, DstY, DstW, DstH, MaskDC, MaskX, MaskY, SrcW, SrcH, SrcAnd); + StretchBlt(DstDC, DstX, DstY, DstW, DstH, MemDC, 0, 0, SrcW, SrcH, SrcInvert); + SetTextColor(DstDC, crText); + SetTextColor(DstDC, crBack); + SelectObject(MemDC, Save); + DeleteObject(MemBmp); + DeleteDC(MemDC); +end; +{$ENDIF} + +Procedure TransparentBitBltEx(sourcedc, destdc: THandle; SrcRect,DstRect: TRect; + atranscolor: longint); +Var + monobitmap: THandle; + oldbkcolor: longint; + monodc: THandle; + width: integer; + height: integer; + oldbitmap: THandle; +Begin + With SrcRect do + Begin + width := RectWidth(SrcRect); + height := RectHeight(SrcRect); + monodc := CreateCompatibleDC(sourcedc); + monobitmap := CreateCompatibleBitmap(monodc, width, height); + oldbitmap := SelectObject(monodc, monobitmap); + Try + oldbkcolor := SetBkColor(sourcedc, atranscolor); + BitBlt(monodc, 0, 0, width, height, sourcedc, Left, Top, SRCCOPY); + SetBkColor(sourcedc, oldbkcolor); + TransparentStretchBlt(destdc, DstRect.Left, DstRect.Top, RectWidth(DstRect), + RectHeight(DstRect), SourceDC, left, top, width, height, monodc, 0, 0); + Finally + SelectObject(monodc, oldbitmap); + DeleteDC(monodc); + DeleteObject(monobitmap); + End; + End; +End; + +Procedure TransparentBitBlt(sourcedc, destdc: THandle; arect: TRect; + atranscolor: longint; aoriginX,aoriginY: Integer); +begin + TransparentBitBltEx(sourcedc, destdc,arect, + Rect(aoriginX,aoriginY,aoriginX+RectWidth(arect),aoriginY+RectHeight(arect)), + atranscolor); +end; + +Function GetTransparentColor(dc: THandle; const arect: TRect): longint; +Begin + Result := GetPixel(dc, arect.left, arect.bottom); +End; + +{-----------------------------------------------------------------------} + +function AVIStreamEnd (pavi : PAVIStream) : longint; +begin + result := AVIStreamStart(pavi) + AVIStreamLength(pavi); +end; + +{-----------------------------------------------------------------------} + +function AVIStreamFormatSize (pavi : PAVIStream; lPos : longint; plSize : pointer) : longint; +begin + result := AVIStreamReadFormat(pavi, lPos, nil, plSize); +end; + +{-----------------------------------------------------------------------} + +constructor TDCAVIPlayer.Create (AOwner : TComponent); +begin + inherited Create(AOwner); + width := 100; + height := 50; + + fAutoSize := true; + fCenter := true; + fStartFrame := 1; + fTransparent := true; + fSkipFrames := true; + fAutoSize := true; + fBackChanged := true; + fblockchanges := true; + fPlaySound := true; + + AVIFileInit; + faudioplay := TAudioPlay.Create; + HookWndProc; + hdrawdib := DrawDIBOpen; +end; + +{------------------------------------------------------------------} + +destructor TDCAVIPlayer.Destroy; +begin + Stop; + UnHookWndProc; + DrawDIBClose(hdrawdib); + KillTempDC; + CloseFile; + faudioplay.Free; + AVIFileExit; + inherited Destroy; +end; + +{------------------------------------------------------------------} + +procedure TDCAVIPlayer.CreateParams(var Params: TCreateParams); +begin + inherited CreateParams(Params); + Params.ExStyle := Params.ExStyle or WS_EX_TRANSPARENT; +end; + +{------------------------------------------------------------------} + +function TDCAVIPlayer.ZOrder : integer; +begin + if Parent <> nil then + with Parent do + for result := 0 to ControlCount - 1 do + if Controls[result] = self then + exit; + + result := -1 +end; + +{------------------------------------------------------------------} + +procedure Timer(uID, uMsg, dwUser, dw1, dw2 : longint); stdcall; +begin + PostMessage(TDCAVIPlayer(dwUser).Handle, WM_NEXTFRAME, 0, 0); +end; + +{------------------------------------------------------------------} + +procedure TDCAVIPlayer.PlayAudio(startframe, endframe : integer); +var + astart : integer; + aend : integer; +begin + if (faudiostream = nil) or not fPlaySound then + exit; + + astart := AVIStreamTimeToSample(faudiostream, AVIStreamSampleToTime(fvideostream, startFrame)); + aend := AVIStreamTimeToSample(faudiostream, AVIStreamSampleToTime(fvideostream, endFrame)); + faudioplay.play(handle, faudiostream, astart, aend); +end; + +{------------------------------------------------------------------} + +procedure TDCAVIPlayer.Play (FromFrame, ToFrame: Word; Count: Integer); +var + info : TAVIStreamInfo; + ainfo : TAVIStreamInfo; +begin + Stop; + if not Assigned(fvideostream) then + exit; + + fFrame := FromFrame; + fStartFrame := FromFrame; + fStopFrame := ToFrame; + frepeatCount := Count; + AVIStreamInfo(fvideostream, @info, sizeof(info)); + fdelay := MulDiv(info.dwScale, 1000, info.dwRate); + + DoStart; + fActive := true; + if Assigned(faudiostream) then + begin + AVIStreamInfo(fvideostream, @ainfo, sizeof(info)); + PlayAudio(fFrame, fStopFrame); + end; + + fTimer := timeSetEvent(fdelay, 0, @Timer, integer(self), TIME_PERIODIC); +end; + +{------------------------------------------------------------------} + +procedure TDCAVIPlayer.Stop; +begin + if ftimer <> 0 then + begin + timeKillEvent(fTimer); + fTimer := 0; + end; + + if not fActive then + exit; + + faudioplay.stop; + fActive := false; + DoStop; + ShowFrame; +end; + +{------------------------------------------------------------------} + +procedure TDCAVIPlayer.Seek (Frame : integer); +begin + if Frame = fFrame then + exit; + + Stop; + ValidateFrameNumber(Frame); + fFrame := Frame; + Invalidate; +end; + +{------------------------------------------------------------------} + +procedure TDCAVIPlayer.Loaded; +var + _startframe : integer; + _stopframe : integer; +begin + inherited Loaded; + + if ffilename <> '' then + begin + fBlockChanges := false; + _startframe := fstartframe; + _stopframe := fStopFrame; + OpenFile; + fstartframe := _startframe; + fStopFrame := _stopframe; + fBlockChanges := true; + end; + + + if fActive then + if fOpen then + Play(fStartFrame, fStopFrame, fRepetitions) + else + fActive := false; + +end; + +{------------------------------------------------------------------} + +procedure TDCAVIPlayer.SetActive(val : boolean); +begin + if val = fActive then + exit; + + if not (csReading in ComponentState) then + if val then + begin + Play(fStartFrame, fStopFrame, fRepetitions) + end + else + begin + Stop; + if csDesigning in ComponentState then + begin + fFrame := 0; + ShowFrame; + end; + end; + +end; + +{------------------------------------------------------------------} + +procedure TDCAVIPlayer.SetAutoSize(val : boolean); +begin + if val = fAutoSize then + exit; + + fAutoSize := val; + AdjustControlsize; +end; + +{------------------------------------------------------------------} + +procedure TDCAVIPlayer.SetCenter(val : boolean); +begin + if val = fCenter then + exit; + + fCenter := val; + if not fTransparent then + Invalidate; + + ShowFrame; +end; + +{------------------------------------------------------------------} + +procedure TDCAVIPlayer.SetFileName(val : string); +var + wasactive : boolean; +begin + if val = fFileName then + exit; + + ffilename := val; + if csReading in ComponentState then + exit; + + wasactive := fActive; + + Reset; + + Invalidate; + ShowFrame; + + if val = '' then + begin + fbackchanged := true; + Parent.Invalidate; + UpdateWindow(Parent.Handle); + end; + + if wasActive then + if not (csReading in ComponentState) then + Active := true + else + fActive := true; +end; + +{------------------------------------------------------------------} + +procedure TDCAVIPlayer.SetRepetitions(val : integer); +begin + if val = fRepetitions then + exit; + + fRepetitions := val; + if csDesigning in ComponentState then + begin + Stop; + fFrame := 0; + ShowFrame; + end; +end; + +{------------------------------------------------------------------} + +procedure TDCAVIPlayer.ValidateFrameNumber(var val : integer); +begin + if fOpen then + if val > fLength - 1 then + val := fLength - 1 + else + if val < 0 then + val := 0; +end; + +{------------------------------------------------------------------} + +procedure TDCAVIPlayer.SetStartFrame(val : integer); +begin + if (val = fStartFrame) then + exit; + + ValidateFrameNumber(val); + fStartFrame := val; +end; + +{------------------------------------------------------------------} + +procedure TDCAVIPlayer.SetStopFrame(val : integer); +begin + if val = fStopFrame then + exit; + + ValidateFrameNumber(val); + fStopFrame := val; +end; + +{------------------------------------------------------------------} + +procedure TDCAVIPlayer.SetTransparent(val : boolean); +begin + if val = fTransparent then + exit; + + fTransparent := val; + Invalidate; + ShowFrame; +end; + +{------------------------------------------------------------------} + +procedure TDCAVIPlayer.SetStretch (val : boolean); +begin + if val = fStretch then + exit; + + fStretch := val; + if not (csReading in ComponentState) then + begin + if not val then + invalidate; + + if not fActive then + ShowFrame; + end; +end; + +{------------------------------------------------------------------} + +procedure TDCAVIPlayer.SetPlaySound (val : boolean); +begin + if val = fPlaySound then + exit; + + fPlaySound := val; + if fActive then + if val then + PlayAudio(fFrame, fStopFrame) + else + faudioplay.Stop; +end; + +{------------------------------------------------------------------} + +procedure TDCAVIPlayer.AdjustControlsize; +var + info : TAVIStreamInfo; + r : TRect; + r2 : TRect; + i : integer; + crect : TRect; +begin + if fautosize and fOpen then + begin + AVIStreamInfo(fvideostream, @info, sizeof(info)); + if fblockchanges then + Parent.Perform(WM_SETREDRAW, 0, 0); + r := Rect(left, top, left + width, top + height); + with info.rcframe do + SetBounds(self.left, self.top, right - left, bottom - top); + if fblockchanges then + begin + Parent.Perform(WM_SETREDRAW, 1, 0); + r2 := Rect(left, top, left + width, top + height); + SubtractRect(r, r, r2); + InvalidateRect(Parent.Handle, @r, true); + with Parent do + for i := 0 to ControlCount - 1 do + begin + with Controls[i] do + crect := Rect(left, top, left + width, top + height); + + if (Controls[i] is TWinControl) and (Controls[i] <> self) and + InterSectRect(r2, r, crect) then + Controls[i].Invalidate; + end; + end; + end; +end; + +{------------------------------------------------------------------} + +procedure TDCAVIPlayer.OpenFile; +var + info : TAVIStreamInfo; +begin + if ffilename = '' then + exit; + + if (AVIFileOpen(@favifile, @(ffilename[1]), 0, nil) <> 0) then + exit; + + if (AVIFileGetStream(favifile, @fvideostream, streamtypeVIDEO, 0) <> 0) then + begin + AVIFileRelease(favifile); + exit; + end; + + fgetframe := AVIStreamGetFrameOpen(fvideostream, nil); + + if fgetframe = nil then + begin + AVIStreamRelease(fvideostream); + AVIFileRelease(favifile); + exit; + end; + + AVIFileGetStream(favifile, @faudiostream, streamtypeAUDIO, 0); + + AVIStreamInfo(fvideostream, @info, sizeof(info)); + with info do + begin + fLength := dwlength; + fFrameWidth := rcframe.right - rcframe.left; + fFrameHeight := rcframe.bottom - rcframe.top; + fStartFrame := dwStart; + fStopFrame := fLength - 1; + end; + fFrame := fStartFrame; + fOpen := true; + SetWindowLong(handle, GWL_EXSTYLE, GetWindowLong(handle, GWL_EXSTYLE) and (not WS_EX_TRANSPARENT)); + AdjustControlsize; + fbackchanged := true; + Invalidate; +{ ShowFrame; + Parent.Invalidate;} + DoOpen; +end; + +{------------------------------------------------------------------} + +procedure TDCAVIPlayer.CloseFile; +begin + if not fOpen then + exit; + + if fActive then + Stop; + + if Assigned(fgetframe) then + AVIStreamGetFrameClose(fgetframe); + + if Assigned(faudiostream) then + AVIStreamRelease(faudiostream); + + if Assigned(fvideostream) then + AVIStreamRelease(fvideostream); + + if Assigned(favifile) then + AVIFileRelease(favifile); + + faudiostream := nil; + fvideostream := nil; + favifile := nil; + fgetframe := nil; + fOpen := false; + fLength := 0; + DoClose; +end; + +{------------------------------------------------------------------} + +procedure TDCAVIPlayer.CalcFrameLayout; +begin + fxstart := 0; + fystart := 0; + if csDesigning in ComponentState then + fofs := 1 + else + fofs := 0; + + if fOpen then + begin + fiwidth := FrameWidth; + fiheight := FrameHeight; + end + else + begin + fiwidth := self.width; + fiheight := self.height; + end; + + if not Stretch and fCenter then + begin + fxstart := (self.width - fiwidth) div 2; + fystart := (self.height - fiheight) div 2; + end; + + if not Transparent then + begin + if fxstart > 0 then + fxofs := 0 + else + fxofs := fofs; + + if fystart > 0 then + fyofs := 0 + else + fyofs := fofs; + end; +end; + +{------------------------------------------------------------------} + +procedure TDCAVIPlayer.StartDrawing; +begin + fdrawing := true; + fdrawcontrol := ZOrder; +end; + +{------------------------------------------------------------------} + +procedure TDCAVIPlayer.DrawFrameToDC(dc : THandle); +var + memdc : THandle; + formdc : THandle; + image : pointer; + imagestart : integer; + bitmap : THandle; + fbitmap : THandle; + oldmemobject : THandle; + oldfobject : THandle; + width : integer; + height : integer; + +begin +{_FS - We're not using your window anyway...} +// if PaintDisabled then +// exit; + + if fTransparent and (fBackChanged or not fActive) then + begin + SaveBackGround; + fBackChanged := false; + end; + + StartDrawing; + memdc := CreateCompatibleDC(dc); + formdc := CreateCompatibleDC(dc); + try + image := AVIStreamGetFrame(fgetframe, fFrame); + CalcFrameLayout; + + if fStretch then + begin + width := self.width; + height := self.height; + end + else + begin + width := fiwidth; + height := fiheight; + end; + + imagestart := 0; + + if Assigned(image) then + begin + SetStretchBltMode(memdc, HALFTONE); + imagestart := TBitmapInfoHeader(image^).biSize + TBitmapInfoHeader(image^).biClrUsed * 4; + end; + + if fTransparent then + begin + bitmap := CreateCompatibleBitmap(dc, width, height); + oldmemobject := SelectObject(memdc, bitmap); + + StretchDIBits(memdc, 0, 0, width, height, 0, 0, fiwidth, fiheight, pchar(image) + imagestart, + TBitmapInfo(image^), 0, SRCCOPY); + + fbitmap := CreateCompatibleBitmap(dc, self.width, self.height); + oldfobject := SelectObject(formdc, fbitmap); + + BitBlt(formdc, 0, 0, self.width, self.height, ftempdc, 0, 0, SRCCOPY); + + if Assigned(image) then + TransparentBitBlt(memdc, formdc, Rect(0, 0, width, height), + GetTransparentColor(memdc, Rect(0, 0, width - 1, height - 1)), + fxstart, fystart); + + BitBlt(dc, fofs, fofs, self.width - fofs * 2, self.height - fofs * 2, formdc, fofs, fofs, SRCCOPY); + + SelectObject(formdc, oldfobject); + DeleteObject(fbitmap); + SelectObject(memdc, oldmemobject); + DeleteObject(bitmap); + end + else + DrawDibDraw(hdrawdib, dc, fxstart, fystart, width - fxofs * 2, height - fyofs * 2, + image, pchar(image) + imagestart, 0, 0, fiwidth, fiheight, DDF_HALFTONE); + + finally + DeleteDC(memdc); + DeleteDC(formdc); + fdrawing := false; + end; +end; + +{------------------------------------------------------------------} + +function TDCAVIPlayer.PaintDisabled : boolean; +begin + result := fDrawing or ([csReading, csLoading] * ComponentState <> []) or (Parent = nil) + or ([csReading, csLoading] * Parent.ComponentState <> []) + or not HandleAllocated or not ({_FS-visible or }(csDesigning in ComponentState)); +end; + +{------------------------------------------------------------------} + +procedure TDCAVIPlayer.ShowFrame; +var + dc : THandle; + brush : THandle; +begin + if PaintDisabled then + exit; + + if _dc = 0 then + dc := GetDC(handle) + else + dc := _dc; + + if not (fTransparent or fOpen) then + begin + brush := CreateSolidBrush(ColorToRGB(Color)); + FillRect(dc, ClientRect, brush); + DeleteObject(brush); + end + else + DrawFrameToDC(dc); + + if _dc = 0 then + ReleaseDC(handle, dc); + + ShowRect; +end; + +{------------------------------------------------------------------} + +procedure TDCAVIPlayer.UpdateFrameNumber; +begin + if (fFrame >= fStopFrame) then + begin + if frepeatcount > 0 then + begin + dec(fRepeatCount); + if fRepeatCount = 0 then + begin + Stop; + exit; + end; + end; + + fFrame := fStartFrame - 1; + PlayAudio(fStartFrame, fStopFrame); + end; +end; + +{------------------------------------------------------------------} + +procedure TDCAVIPlayer.UpdateOtherAVIPlayers; +var + r : TRect; + i : integer; +begin + with Parent do + for i := ControlCount - 1 downto 0 do + begin + if (Controls[i] = self) then + break; + + if (Controls[i].Visible) and (Controls[i] is TDCAVIPlayer) then + with TDCAVIPlayer(Controls[i]) do + if [csDestroying, csLoading] * ComponentState = [] then + begin + fbackchanged := true; + r := ClientRect; + InvalidateRect(Handle, @r, true); + end; + end; +end; + +{------------------------------------------------------------------} + +procedure TDCAVIPlayer.PlayNextFrame(var Msg : TMessage); +begin + UpdateFrameNumber; + inc(fFrame); + if fActive and not fDrawing then + begin + ShowFrame; + UpdateOtherAVIPlayers; + end; +end; + +{------------------------------------------------------------------} + +procedure TDCAVIPlayer.SaveBackground; +var + dc : THandle; + formdc : THandle; + oldfbitmap : THandle; + fbitmap : THandle; + fdc : THandle; +begin + if Parent = nil then + exit; + + StartDrawing; + dc := GetDC(handle); + fdc := GetDC(parent.handle); + formdc := CreateCompatibleDC(fdc); + fbitmap := CreateCompatibleBitmap(fdc, parent.width, parent.height); + oldfbitmap := SelectObject(formdc, fbitmap); + + if ftempdc = 0 then + begin + ftempdc := CreateCompatibleDC(dc); + ftempbitmap := CreateCompatibleBitmap(dc, width, height); + foldbitmap := SelectObject(ftempdc, ftempbitmap); + end; + IntersectClipRect(formdc, left, top, left + width + 1, top + height + 1); + + + with parent do + PaintTo(formdc, 0, 0); + + SetViewPortOrgEx(formDC, 0, 0, nil); + BitBlt(ftempdc, 0, 0, width, height, formdc, left + 1, top + 1, SRCCOPY); + SelectObject(formdc, oldfbitmap); + DeleteObject(fbitmap); + DeleteDC(formdc); + ReleaseDC(Parent.Handle, fdc); + ReleaseDC(handle, dc); + + fdrawing := false; +end; + +{------------------------------------------------------------------} + +procedure TDCAVIPlayer.WMPaint(var Msg : TWMPaint); +var + ps : TPaintStruct; +begin + _dc := Msg.DC; + if _dc = 0 then + _dc := BeginPaint(handle, ps); + + try + Msg.result := 0; + +{ if name = 'DCAVIPlay3' then + asm nop end;} + + ShowFrame; + + finally + if Msg.DC = 0 then + EndPaint(handle, ps); + _dc := 0; + end; +end; + +{------------------------------------------------------------------} + +procedure TDCAVIPlayer.WMEraseBkgnd(var Msg : TMessage); +var + brush : THandle; + r : TRect; + dc : THandle; + width : integer; + height : integer; +begin + if PaintDisabled then + exit; + + if not (fTransparent or fStretch) then + begin + CalcFrameLayout; + if fStretch then + begin + width := self.width; + height := self.height; + end + else + begin + width := fiwidth; + height := fiheight; + end; + + dc := GetDC(handle); + brush := CreateSolidBrush(ColorToRGB(Color)); + r := rect(fofs, fofs, self.width, fystart); + FillRect(dc, r, brush); + + r := rect(fofs, fystart, fxstart, self.height); + FillRect(dc, r, brush); + + r := rect(fxstart, fystart + height, self.width - fofs * 2, self.height - fofs * 2); + FillRect(dc, r, brush); + + r := rect(fxstart + width, fystart, self.width - fofs * 2, fystart + height); + FillRect(dc, r, brush); + + DeleteObject(brush); + ReleaseDC(handle, dc); + end; +end; + +{------------------------------------------------------------------} + +procedure TDCAVIPlayer.WMMove (var Msg : TMessage); +begin + inherited; + fbackchanged := true; + ShowFrame; + UpdateOtherAVIPlayers; +end; + +{------------------------------------------------------------------} + +procedure TDCAVIPlayer.KillTempDC; +begin + if ftempdc <> 0 then + begin + SelectObject(ftempdc, foldbitmap); + DeleteObject(ftempbitmap); + DeleteDC(ftempdc); + ftempdc := 0; + end; +end; + +{------------------------------------------------------------------} + +procedure TDCAVIPlayer.WMSize (var Msg : TMessage); +begin + StartDrawing; + KillTempDC; + inherited; + fBackChanged := true; + fdrawing := false; + AdjustControlsize; + if not Active then + ShowFrame; + UpdateOtherAVIPlayers; +end; + +{------------------------------------------------------------------} + +procedure TDCAVIPlayer.ShowRect; +var + DC : THandle; + Pen : THandle; + SavePen : THandle; + SaveBrush : THandle; +begin + if not (csDesigning in ComponentState) then + exit; + + dc := GetDC(Handle); + Pen := CreatePen(PS_DOT, 1, clBlack); + SavePen := SelectObject(dc, Pen); + SaveBrush := SelectObject(dc, GetStockobject(HOLLOW_BRUSH)); + Rectangle(dc, 0, 0, width, height); + SelectObject(DC, SavePen); + DeleteObject(Pen); + SelectObject(DC, SaveBrush); + ReleaseDC(Handle, DC); +end; + +{------------------------------------------------------------------} + +var + WHook : HHook; + hooks : TList; + +type TCWPStruct = packed record + lParam : LPARAM; + wParam : WPARAM; + message : integer; + wnd : HWND; +end; + +function CallWndProcHook(nCode : integer; wParam : Longint; var Msg : TCWPStruct) : longint; stdcall; +var + i : integer; + r : TRect; + r2 : TRect; + + function IsPaintMsg : boolean; + var + c : TWinControl; + begin + result := false; + c := FindControl(msg.wnd); + if (c <> nil) and not (c is TDCAVIPlayer) and + TDCAVIPlayer(hooks[i]).HandleAllocated and + (TDCAVIPlayer(hooks[i]).owner = c.owner) or + (TDCAVIPlayer(hooks[i]).owner = c) then + begin + GetWindowRect(msg.wnd , r); + GetWindowRect(TDCAVIPlayer(hooks[i]).handle, r2); + result := IntersectRect(r, r, r2); + end; + end; + +begin + Result := CallNextHookEx(WHook, nCode, wParam, Longint(@Msg)); + + if ((msg.message > CN_BASE) and (msg.message < CN_BASE + 500)) or + (msg.message = WM_PAINT) or (msg.message = WM_SIZE) +{ or (msg.message = WM_ERASEBKGND)} then + for i := 0 to hooks.Count - 1 do + with TDCAVIPlayer(hooks[i]) do + if HandleAllocated and Transparent and IsPaintMsg then + begin + fbackchanged := true; + r := ClientRect; + InvalidateRect(Handle, @r, true); + end; +end; + +{------------------------------------------------------------------} + +procedure AddHook(o : TDCAVIPlayer); +begin + if hooks.Count = 0 then + WHook := SetWindowsHookEx(WH_CALLWNDPROC, @CallWndProcHook, 0, GetCurrentThreadId); + hooks.Add(o); +end; + +{------------------------------------------------------------------} + +procedure RemoveHook(o : TDCAVIPlayer); +begin + hooks.Remove(o); + if hooks.Count = 0 then + UnHookWindowsHookEx(WHook); +end; + +{------------------------------------------------------------------} + +procedure TDCAVIPlayer.HookWndProc; +begin + AddHook(self); +end; + +{------------------------------------------------------------------} + +procedure TDCAVIPlayer.UnHookWndProc; +begin + RemoveHook(self); +end; + +{------------------------------------------------------------------} + +procedure TDCAVIPlayer.Reset; +begin + CloseFile; + OpenFile; +end; + +{------------------------------------------------------------------} + +procedure TDCAVIPlayer.DoOpen; +begin + if Assigned(fOnOpen) then + fOnOpen(self); +end; + +{------------------------------------------------------------------} + +procedure TDCAVIPlayer.DoClose; +begin + if Assigned(fOnClose) then + fOnClose(self); +end; + +{------------------------------------------------------------------} + +procedure TDCAVIPlayer.DoStart; +begin + if Assigned(fOnStart) then + fOnStart(self); +end; + +{------------------------------------------------------------------} + +procedure TDCAVIPlayer.MMWOM_DONE(var M:TMessage); +begin + faudioplay.AudioPlayMessage(PWAVEHDR(M.lParam)); +end; + +{------------------------------------------------------------------} + +procedure TDCAVIPlayer.DoStop; +begin + if Assigned(fOnStop) then + fOnStop(Self); +end; + +{------------------------------------------------------------------} + +procedure TDCAVIPlayer.DisplayChange(var Msg : TMessage); +begin + DrawDIBClose(hdrawdib); + hdrawdib := DrawDIBOpen; +end; + +{------------------------------------------------------} + +destructor TAudioPlay.Destroy; +begin + Stop; + inherited; +end; + +{--------------------------------------------------------------} + +procedure TAudioPlay.AudioPlayMessage(W : PWAVEHDR); +begin + waveOutUnprepareHeader(FWaveOut, W, sizeof(TWAVEHDR)); + FreeMem(W, FBufferSize + sizeof(TWAVEHDR)); + if FPlaying then + FillBuffer; +end; + +{--------------------------------------------------------------} + +function TAudioPlay.FillBuffer : Boolean; +var + AudioBuf : PWAVEHDR; + SamplesToPlay : integer; + lRead : integer; +begin + Result := false; + GetMem(AudioBuf, fBufferSize + sizeof(TWAVEHDR)); + with AudioBuf^ do + begin + dwuser := integer(Self); + dwFlags := WHDR_DONE; + lpData := pointer(integer(AudioBuf) + sizeof(TWAVEHDR)); + dwBufferLength := fBufferSize; + end; + if waveOutPrepareHeader(FWaveOut, AudioBuf, + sizeof(TWAVEHDR)) <> MMSYSERR_NOERROR then + begin + FreeMem(AudioBuf, fBufferSize + sizeof(TWAVEHDR)); + exit; + end; + + SamplesToPlay := Min(fEnd - fCurrent, fBufferSize div fSampleSize); + if SamplesToPlay > 0 then + begin + AVIStreamRead(fAvi, fCurrent, SamplesToPlay, AudioBuf.lpData, + fBufferSize, @AudioBuf.dwBufferLength, @lRead); + if LRead = SamplesToPlay then + begin + inc(fCurrent, lRead); + waveOutWrite(fWaveOut, AudioBuf, sizeof(TWAVEHDR)); + end; + end; + fPlaying := true; + result := true; +end; + +{--------------------------------------------------------------} + +function TAudioPlay.OpenDevice(W : HWND; pAvi : pointer) : boolean; +var + strhdr : TAVISTREAMINFO; + lpFormat : pointer; + cbFormat : longint; +begin + result := false; + fAVI := pAvi; + AVIStreamInfo(pAvi, @StrHdr, sizeof(StrHdr)); + fSampleSize := StrHdr.dwSampleSize; + if (fSampleSize <= 0) then + exit; + + fBufferSize := Max(fSampleSize, cBufSize); + AVIStreamFormatSize(pavi, 0, @cbFormat); + GetMem(lpFormat, cbFormat); + FillChar(lpFormat^, cbFormat, 0); + AVIStreamReadFormat(pAvi, 0, lpFormat, @cbFormat); + sndPlaySound(nil, 0); + if waveOutOpen(@FWaveOut, WAVE_MAPPER, lpFormat, + W, 0, CALLBACK_WINDOW) = 0 then + result := true; + + FreeMem(lpFormat, cbFormat); +end; + +{--------------------------------------------------------------} + +procedure TAudioPlay.Stop; +begin + if fWaveOut <> 0 then + begin + FPlaying := false; + waveOutReset(FWaveOut); + waveOutClose(FWaveOut); + fWaveOut := 0; + end; +end; + +{--------------------------------------------------------------} + +function TAudioPlay.Play(W : HWND; pAvi : Pointer; lStart, lEnd : longint) : boolean; +var + i : integer; +begin + if fPlaying then + Stop; + + Result := false; + if lStart < 0 then + lStart := AVIStreamStart(pavi); + + if lEnd < 0 then + lEnd := AVIStreamEnd(pavi); + + if lStart >= lEnd then + exit; + + if not OpenDevice(W, pAvi) then + exit; + + waveOutPause(fWaveOut); + fBegin := lStart; + FCurrent := lStart; + fEnd := lEnd; + fPlaying := true; + for i := 1 to CAheadBuffers do + FillBuffer; + + waveOutRestart(FWaveOut); + result := true; +end; + +{---------------------------------------------------------------------} +{_FS: add} +function TDCAVIPlayer.GetFrameRate: integer; +var + info: TAviStreamInfo; +begin + Result:=0; + if not Assigned(fvideostream) then Exit; + AVIStreamInfo(fvideostream, @info, sizeof(info)); + Result := info.dwRate div info.dwScale; +end; +{_FS: end add} + +initialization + hooks := TList.Create; +finalization + if hooks.Count > 0 then + UnHookWindowsHookEx(WHook); + hooks.Free; +end. diff --git a/Source/fsaviunit.dfm b/Source/fsaviunit.dfm new file mode 100644 index 0000000..761db79 --- /dev/null +++ b/Source/fsaviunit.dfm @@ -0,0 +1,23 @@ +object FsAvi: TFsAvi + Left = 243 + Top = 106 + Width = 226 + Height = 103 + Caption = 'FsAvi' + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [] + OldCreateOrder = False + OnCreate = FormCreate + OnDestroy = FormDestroy + PixelsPerInch = 96 + TextHeight = 13 + object sd1: TSaveDialog + Filter = 'AVI files|*.avi' + Left = 8 + Top = 8 + end +end diff --git a/Source/fsaviunit.pas b/Source/fsaviunit.pas new file mode 100644 index 0000000..6f81e0b --- /dev/null +++ b/Source/fsaviunit.pas @@ -0,0 +1,103 @@ +unit fsaviunit; + +interface + +uses + Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, + fsformunit, + fsaviwriter, ExtCtrls, StdCtrls, Buttons; + +type + TFsAvi = class(TFsForm) + sd1: TSaveDialog; + procedure FormCreate(Sender: TObject); + procedure FormDestroy(Sender: TObject); + procedure BitBtn1Click(Sender: TObject); + procedure Button1Click(Sender: TObject); + procedure Button2Click(Sender: TObject); + private + { Private declarations } + a: TAviWriter; + public + { Public declarations } + procedure Parse(const S: String); override; + end; + +var + FsAvi: TFsAvi; + +implementation + +uses + fsframeunit, strz, mainunit; + +{$R *.DFM} + +{ Tavi } + +procedure TFsAvi.Parse(const S: String); +var + s1: String; + f: TFsFrame; +begin + if S='' then Exit; + + s1 := UpperCase(ExtractWord(1, S, [' '])); + + if s1='WRITE' then begin + a.FileName := Copy(S, Length(s1)+2, 255); + if a.Filename='' then + if sd1.Execute then begin + a.Filename := sd1.Filename; + if UpperCase(ExtractFileExt(a.Filename))<>'.AVI' then + a.Filename := a.Filename+'.avi'; + end else + Exit; + a.Finish; + Exit; + end else + if s1='FPS' then begin + a.fps := MyStrToInt(Copy(S, Length(s1)+2, 255)); + Exit; + end; + + if not a.Prepared then + a.Prepare; + + f := FindFrame(S); + if f=nil then Exit; + + a.Width := f.d1.SurfaceWidth; + a.Height := f.d1.SurfaceHeight; + + f.dDib.DIB.Assign(f.d1.Surface); + a.AddFrame(f.dDib.DIB); + main.SendReturnValues(PdName+'pos='+IntToStr(a.FramePos)); +end; + +procedure TFsAvi.FormCreate(Sender: TObject); +begin + a := TAviWriter.Create(Self); +end; + +procedure TFsAvi.FormDestroy(Sender: TObject); +begin + a.Free; +end; + +procedure TFsAvi.BitBtn1Click(Sender: TObject); +begin + a.Write; +end; + +procedure TFsAvi.Button1Click(Sender: TObject); +begin + a.Prepare; +end; + +procedure TFsAvi.Button2Click(Sender: TObject); +begin + a.Finish; +end; + +end. diff --git a/Source/fsbrowserunit.dfm b/Source/fsbrowserunit.dfm new file mode 100644 index 0000000..97c5299 --- /dev/null +++ b/Source/fsbrowserunit.dfm @@ -0,0 +1,35 @@ +inherited fsbrowser: Tfsbrowser + Left = 266 + Top = 377 + Width = 237 + Height = 257 + Caption = 'fsbrowser' + FormStyle = fsNormal + OldCreateOrder = True + PixelsPerInch = 96 + TextHeight = 13 + inherited d1: TDXDraw [1] + Width = 229 + Height = 230 + TabOrder = 2 + end + inherited PanelMute: TPanel [2] + Width = 229 + Height = 230 + end + object br: TWebBrowser [3] + Left = 0 + Top = 0 + Width = 229 + Height = 230 + Align = alClient + TabOrder = 0 + OnBeforeNavigate2 = brBeforeNavigate2 + ControlData = { + 4C000000AB170000C51700000000000000000000000000000000000000000000 + 000000004C000000000000000000000001000000E0D057007335CF11AE690800 + 2B2E126208000000000000004C0000000114020000000000C000000000000046 + 8000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000100000000000000000000000000000000000000} + end +end diff --git a/Source/fsbrowserunit.pas b/Source/fsbrowserunit.pas new file mode 100644 index 0000000..b507902 --- /dev/null +++ b/Source/fsbrowserunit.pas @@ -0,0 +1,113 @@ +unit fsbrowserunit; + +interface + +uses + Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, + fsframeunit, Filez, DIB, Menus, DXDraws, ExtCtrls, OleCtrls, SHDocVw, + C2PhotoShopHost, ExtDlgs, StdCtrls; + +type + Tfsbrowser = class(Tfsframe) + br: TWebBrowser; + procedure FormCreate(Sender: TObject); + procedure brBeforeNavigate2(Sender: TObject; const pDisp: IDispatch; + var URL, Flags, TargetFrameName, PostData, Headers: OleVariant; + var Cancel: WordBool); + private + { Private declarations } + public + { Public declarations } + PdName: String; + procedure Parse(const S: String); override; + procedure CopyToSurface; + end; + +var + fsbrowser: Tfsbrowser; + +implementation + +uses + ActiveX, + Strz, mainunit; + +{$R *.DFM} + +{ Tfsbrowser } + +procedure Tfsbrowser.Parse(const S: String); +var + s1, s2: String; +begin + s1 := Trim(UpperCase(ExtractWord(1, S, [' ']))); + if s1='' then Exit; + if (s1[1] in ['0'..'9']) and + (Pos('X', s1)>0) then begin + Width := MyStrToInt(ExtractWord(1, s1, ['X'])); + Height := MyStrToInt(ExtractWord(2, s1, ['X'])); + end else + if s1='OPEN' then begin + s2 := Copy(S, Length(s1)+2, 255); + br.Navigate(s2); + end else + if s1='STOP' then begin + br.Stop; + end else + if s1='REFRESH' then begin + br.Refresh; + end else begin + if + (UpperCase(Copy(S, 1, 4))='HTTP') or + (UpperCase(Copy(S, 1, 4))='FILE') + then + br.Navigate(S) + else + inherited Parse(S); + end; +end; + +procedure Tfsbrowser.FormCreate(Sender: TObject); +begin + inherited; + ClientWidth := 480; + ClientHeight := 360; +end; + +procedure Tfsbrowser.CopyToSurface; +var + DrawRect: TRect; +begin + if (br.ClientWidth<>d1.Surface.Width) or + (br.ClientHeight<>d1.Surface.Height) then + d1.SetSize(br.ClientWidth, br.ClientHeight); + + DrawRect := Rect(0, 0, d1.Surface.Width, d1.Surface.Height); + (br.Document as IViewObject).Draw( + DVASPECT_CONTENT, 1, nil, nil, 0, + d1.Surface.Canvas.Handle, @DrawRect, nil, nil, 0); + + d1.Surface.Canvas.Release; +end; + +procedure Tfsbrowser.brBeforeNavigate2(Sender: TObject; + const pDisp: IDispatch; var URL, Flags, TargetFrameName, PostData, + Headers: OleVariant; var Cancel: WordBool); +var + St: String; +begin + if UpperCase(Copy(URL, 1, 3))='FS:' then begin + St := Copy(URL, 4, 255); + + St := SearchAndReplace(St, '%exepath', + ExtractFilePath(Application.ExeName)); + St := SearchAndReplace(St, '//', '/'); + St := SearchAndReplace(St, '\/', '/'); + + main.SendReturnValuesString(PdName+'link', St); + Cancel:=True; + end; +end; + +end. + diff --git a/Source/fscopyunit.dfm b/Source/fscopyunit.dfm new file mode 100644 index 0000000..922152d --- /dev/null +++ b/Source/fscopyunit.dfm @@ -0,0 +1,26 @@ +object fscopy: Tfscopy + Left = 231 + Top = 103 + Width = 257 + Height = 93 + Caption = 'fscopy' + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [] + OldCreateOrder = False + WindowState = wsMinimized + OnClose = FormClose + OnCreate = FormCreate + PixelsPerInch = 96 + TextHeight = 13 + object copypsh: TC2PhotoShopHost + SerialNumber = 0 + BackColor = clBlack + ForeColor = clBlack + Left = 8 + Top = 8 + end +end diff --git a/Source/fscopyunit.pas b/Source/fscopyunit.pas new file mode 100644 index 0000000..0206d8f --- /dev/null +++ b/Source/fscopyunit.pas @@ -0,0 +1,349 @@ +{ Copyright (C) 2001 Juha Vehviläinen + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details.} + +unit fscopyunit; + +interface + +uses + Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, + mainunit, fsformunit, fsframeunit, StdCtrls, C2PhotoShopHost; + +type + TDrawStyles = (dsCopy, dsROP, dsAlpha, dsAdd, dsSub, + dsBlend, dsPlugin, dsFilter); + TRectTypes = (rtAll, rtRandom, rtSpecific); + + Tfscopy = class(TFsForm) + copypsh: TC2PhotoShopHost; + procedure FormClose(Sender: TObject; var Action: TCloseAction); + procedure FormCreate(Sender: TObject); + private + { Private declarations } + f1, f2: TFsFrame; + DrawStyle: TDrawStyles; + dsROPMode: Integer; + SourceType: TRectTypes; + DestType: TRectTypes; + SourceRect, DestRect: TRect; + iAlpha, iAdd, iSub: Integer; + iBlend: Extended; + Transparent, MirrorLeftRight, MirrorUpdown: Boolean; + iPlugin, iPluginArgs: String; + iFilter, iFilterArgs: String; + + procedure GetFrames(const S: String); + public + { Public declarations } + procedure Parse(const S: String); override; + end; + +var + fscopy: Tfscopy; + +implementation + +{$R *.DFM} + +uses + DxDraws, DirectX, + effectsunit, fsbrowserunit, pshostunit, + Strz; + +procedure Tfscopy.FormClose(Sender: TObject; var Action: TCloseAction); +begin + Action := caFree; +end; + +procedure Tfscopy.GetFrames(const S: String); +const + f1name: String = '-1'; + f2name: String = '-1'; +var + s1, s2: String; +begin + if (Pos(' ', S)=0) then Exit; + + s1 := UpperCase(ExtractWord(1, S, [' '])); + s2 := UpperCase(ExtractWord(2, S, [' '])); + + if (s1<>f1name) or (f1=nil) then + f1 := FindFrame(s1); + + if (s2<>f2name) or (f2=nil) then + f2 := FindFrame(s2); + + f1name := s1; f2name := s2; +end; + +procedure Tfscopy.Parse(const S: String); + + procedure SwapInt(var i1, i2: Integer); + var + tmpi: Integer; + begin + tmpi := i1; + i1 := i2; + i2 := tmpi; + end; + +var + s1: String; + bltFlags: Cardinal; + df: TDDBltFX; + ddck: TDDColorKey; + sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2: Integer; +begin + if (S='') then Exit; + + s1 := UpperCase(ExtractWord(1, S, [' '])); + + if Pos('FS.FRAME', s1)=0 then + if s1='COPY' then begin DrawStyle := dsCopy; Exit; end else + if s1='BLEND' then begin + DrawStyle := dsBlend; + iBlend := MyStrToFloat(ExtractWord(2, S, [' '])); + Exit; + end else + if s1='ALPHA' then begin + DrawStyle := dsAlpha; + iAlpha := MyStrToInt(ExtractWord(2, S, [' '])); + Exit; + end else + if s1='ADD' then begin + DrawStyle := dsAdd; + iAdd := MyStrToInt(ExtractWord(2, S, [' '])); + Exit; + end else + if s1='SUB' then begin + DrawStyle := dsSub; + iSub := MyStrToInt(ExtractWord(2, S, [' '])); + Exit; + end else + if s1='SOURCE' then begin + if Pos(' ', S)>0 then begin // at least x1 specified + SourceRect := StrToRect(Copy(S, Length(s1)+2, 255)); + SourceType := rtSpecific; + Exit; + end; + end else + if s1='DEST' then begin + if Pos(' ', S)>0 then begin // at least x1 specified + DestRect := StrToRect(Copy(S, Length(s1)+2, 255)); + DestType := rtSpecific; + Exit; + end; + end else + if s1='SOURCE_ALL' then begin SourceType := rtAll; Exit; end else + if s1='SOURCE_RANDOM' then begin SourceType := rtRandom; Exit; end else + if s1='DEST_ALL' then begin DestType := rtAll; Exit; end else + if s1='DEST_RANDOM' then begin DestType := rtRandom; Exit; end else + + if s1='BLACKNESS' then begin DrawStyle := dsROP; dsROPMode := cmBlackness; Exit; end else + if s1='DSTINVERT' then begin DrawStyle := dsROP; dsROPMode := cmDstInvert; Exit; end else + if s1='MERGECOPY' then begin DrawStyle := dsROP; dsROPMode := cmMergeCopy; Exit; end else + if s1='MERGEPAINT' then begin DrawStyle := dsROP; dsROPMode := cmMergePaint; Exit; end else + if s1='NOTSRCCOPY' then begin DrawStyle := dsROP; dsROPMode := cmNotSrcCopy; Exit; end else + if s1='NOTSRCERASE' then begin DrawStyle := dsROP; dsROPMode := cmNotSrcErase; Exit; end else + if s1='PATCOPY' then begin DrawStyle := dsROP; dsROPMode := cmPatCopy; Exit; end else + if s1='PATINVERT' then begin DrawStyle := dsROP; dsROPMode := cmPatInvert; Exit; end else + if s1='PATPAINT' then begin DrawStyle := dsROP; dsROPMode := cmPatPaint; Exit; end else + if s1='SRCAND' then begin DrawStyle := dsROP; dsROPMode := cmSrcAnd; Exit; end else + if s1='SRCCOPY' then begin DrawStyle := dsROP; dsROPMode := cmSrcCopy; Exit; end else + if s1='SRCERASE' then begin DrawStyle := dsROP; dsROPMode := cmSrcErase; Exit; end else + if s1='SRCINVERT' then begin DrawStyle := dsROP; dsROPMode := cmSrcInvert; Exit; end else + if s1='SRCPAINT' then begin DrawStyle := dsROP; dsROPMode := cmSrcPaint; Exit; end else + if s1='WHITENESS' then begin DrawStyle := dsROP; dsROPMode := cmWhiteness; Exit; end else + + if s1='TRANSPARENT_0' then begin Transparent := False; Exit; end else + if s1='TRANSPARENT_1' then begin Transparent := True; Exit; end else + if s1='MIRRORLEFTRIGHT_0' then begin MirrorLeftRight := False; Exit; end else + if s1='MIRRORLEFTRIGHT_1' then begin MirrorLeftRight := True; Exit; end else + if s1='MIRRORUPDOWN_0' then begin MirrorUpDown := False; Exit; end else + if s1='MIRRORUPDOWN_1' then begin MirrorUpDown := True; Exit; end else + if main.Plugins.IsPlugin(s1) then begin + DrawStyle := dsPlugin; + iPlugin := s1; + iPluginArgs := Copy(S, Length(s1)+2, 255); + Exit; + end else + if pshostunit.IsFilter(s1) then begin + DrawStyle := dsFilter; + iFilter := s1; + iFilterArgs := Copy(S, Length(s1)+2, 255); + Exit; + end; + + + GetFrames(S); + if (f1=nil) or (f2=nil) then Exit; + if (f1.d1=nil) or (f2.d1=nil) then Exit; + + if (f1.ParentWindow>0) and not IsWindow(f1.ParentWindow) then Exit; + if (f2.ParentWindow>0) and not IsWindow(f2.ParentWindow) then Exit; + + if f1 is TFsBrowser then begin + (f1 as TFsBrowser).CopyToSurface; + end; + + case SourceType of + rtAll: begin + sx1 := 0; + sy1 := 0; + sx2 := f1.d1.Surface.Width; + sy2 := f1.d1.Surface.Height; + end; + rtRandom: begin + sx1 := Random(f1.d1.Surface.Width); + sx2 := Random(f1.d1.Surface.Width); + sy1 := Random(f1.d1.Surface.Height); + sy2 := Random(f1.d1.Surface.Height); + end; + rtSpecific: begin + sx1 := SourceRect.Left; + sy1 := SourceRect.Top; + sx2 := SourceRect.Right; + sy2 := SourceRect.Bottom; + end; + end; + + case DestType of + rtAll: begin + dx1 := 0; + dy1 := 0; + dx2 := f2.d1.Surface.Width; + dy2 := f2.d1.Surface.Height; + end; + rtRandom: begin + dx1 := Random(f2.d1.Surface.Width); + dx2 := Random(f2.d1.Surface.Width); + dy1 := Random(f2.d1.Surface.Height); + dy2 := Random(f2.d1.Surface.Height); + end; + rtSpecific: begin + dx1 := DestRect.Left; + dy1 := DestRect.Top; + dx2 := DestRect.Right; + dy2 := DestRect.Bottom; + end; + end; + + if sx2f1.d1.Surface.Width then sx2:=f1.d1.Surface.Width; + if sy2>f1.d1.Surface.Height then sy2:=f1.d1.Surface.Height; + if dx1<0 then dx1:=0; + if dy1<0 then dy1:=0; + if dx2>f2.d1.Surface.Width then dx2:=f1.d1.Surface.Width; + if dy2>f2.d1.Surface.Height then dy2:=f2.d1.Surface.Height; + + case DrawStyle of + dsCopy: begin + ddck.dwColorSpaceLowValue := 0; + ddck.dwColorSpaceHighValue := 0; + DF.dwsize := SizeOf(DF); + DF.dwROP := cmSrcCopy; + DF.dwDDFX := 0; + DF.ddckSrcColorkey := ddck; + DF.ddckDestColorkey := ddck; + bltFlags := DDBLT_DDFX; + if Transparent then bltFlags := bltFlags or DDBLT_KEYSRCOVERRIDE; + if MirrorLeftRight then + DF.dwDDFX := DF.dwDDFX or DDBLTFX_MIRRORLEFTRIGHT; + if MirrorUpDown then + DF.dwDDFX := DF.dwDDFX or DDBLTFX_MIRRORUPDOWN; + + if not f2.d1.Surface.Blt( + Rect(dx1, dy1, dx2, dy2), + Rect(sx1, sy1, sx2, sy2), + bltFlags or {DDBLT_ROP or} DDBLT_WAIT, + DF, f1.d1.Surface ) then + main.Post(Self.Name+': blt failed.') + else + f2.FlipRequest; + end; + dsROP: begin + StretchBlt(f2.d1.Surface.Canvas.Handle, + dx1, dy1, dx2-dx1, dy2-dy1, + f1.d1.Surface.Canvas.Handle, + sx1, sy1, sx2-sx1, sy2-sy1, dsROPMode); + + f1.d1.Surface.Canvas.Release; + f2.d1.Surface.Canvas.Release; + f2.FlipRequest; + end; + dsAlpha: begin + f2.d1.Surface.DrawAlpha( + Rect(dx1, dy1, dx2, dy2), + Rect(sx1, sy1, sx2, sy2), + f1.d1.Surface, False, iAlpha); + f2.FlipRequest; + end; + dsAdd: begin + f2.d1.Surface.DrawAdd( + Rect(dx1, dy1, dx2, dy2), + Rect(sx1, sy1, sx2, sy2), + f1.d1.Surface, False, iAdd); + f2.FlipRequest; + end; + dsSub: begin + f2.d1.Surface.DrawSub( + Rect(dx1, dy1, dx2, dy2), + Rect(sx1, sy1, sx2, sy2), + f1.d1.Surface, False, iSub); + f2.FlipRequest; + end; + dsBlend: begin + blend(f1.d1.Surface, f2.d1.Surface, iBlend); + f2.FlipRequest; + end; + dsPlugin: begin + if main.Plugins.CallCopy(f1.d1.Surface, f2.d1.Surface, + iPlugin, iPluginArgs) then begin + f1.FlipRequest; + f2.FlipRequest; + end; + end; + dsFilter: begin + if pshostunit.Filter_copy(Self.copypsh, + f1.d1.Surface, f2.d1.Surface, + iFilter, iFilterArgs) then begin + f1.FlipRequest; + f2.FlipRequest; + end; + end; + end; +end; + +procedure Tfscopy.FormCreate(Sender: TObject); +begin + f1 := nil; f2 := nil; + DrawStyle := dsCopy; + SourceType := rtAll; + DestType := rtAll; + iAlpha := 50; iAdd := 255; iSub := 255; + Transparent := False; + MirrorLeftRight := False; + MirrorUpDown := False; +end; + +end. + diff --git a/Source/fsdrawunit.dfm b/Source/fsdrawunit.dfm new file mode 100644 index 0000000..9a73308 --- /dev/null +++ b/Source/fsdrawunit.dfm @@ -0,0 +1,17 @@ +object fsdraw: Tfsdraw + Left = 245 + Top = 177 + Width = 247 + Height = 106 + Caption = 'fsdraw' + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [] + OldCreateOrder = False + OnCreate = FormCreate + PixelsPerInch = 96 + TextHeight = 13 +end diff --git a/Source/fsdrawunit.pas b/Source/fsdrawunit.pas new file mode 100644 index 0000000..c67b3d4 --- /dev/null +++ b/Source/fsdrawunit.pas @@ -0,0 +1,101 @@ +{ Copyright (C) 2001 Juha Vehviläinen + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details.} + +unit fsdrawunit; + +interface + +uses + Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, + fsformunit, fsframeunit, fstextunit; + +type + Tfsdraw = class(TFsForm) + procedure FormCreate(Sender: TObject); + private + dest: TFsFrame; + { Private declarations } + public + { Public declarations } + procedure Parse(const S: String); override; + end; + +var + fsdraw: Tfsdraw; + +implementation + +uses + mainunit, Strz; + +{$R *.DFM} + +{ Tfsdraw } + +procedure Tfsdraw.Parse(const S: String); +var + r: TRect; + x, y: Integer; + s1, sa: String; + b: Boolean; +begin + if (S='') then Exit; + s1 := ExtractWord(WordCount(S, [' ']), S, [' ']); + dest := FindFrame(s1); + if (dest=nil) or (dest.d1=nil) then Exit; + + sa := UpperCase(Copy(S, 1, Pos(s1, S)-2)); + + b := ParsePenProperties(dest.d1.Surface.Canvas, sa); + dest.d1.Surface.Canvas.Release; + + s1 := ExtractWord(1, sa, [' ']); + + if b then Exit else + if s1='MODE_SOLID' then begin + dest.d1.Surface.Canvas.Brush.Style := bsSolid; + dest.d1.Surface.Canvas.Release; + end else + if s1='MODE_CLEAR' then begin + dest.d1.Surface.Canvas.Brush.Style := bsClear; + dest.d1.Surface.Canvas.Release; + end else + if s1='RECT' then begin + dest.d1.Surface.Canvas.Rectangle(StrToRect(Copy(sa, Length(s1)+2, 255))); + dest.d1.Surface.Canvas.Release; + dest.FlipRequest; + end else + if s1='LINE' then begin + r := StrToRect(Copy(sa, Length(s1)+2, 255)); + with dest.d1.Surface.Canvas do begin + MoveTo(r.Left, r.Top); + LineTo(r.Right, r.Bottom); + end; + dest.d1.Surface.Canvas.Release; + dest.FlipRequest; + end else + if s1='PLOT' then begin + x := MyStrToInt(ExtractWord(2, sa, [' '])); + y := MyStrToInt(ExtractWord(3, sa, [' '])); + dest.d1.Surface.Canvas.Pixels[x, y] := + dest.d1.Surface.Canvas.Pen.Color; + dest.d1.Surface.Canvas.Release; + dest.FlipRequest; + end else +end; + +procedure Tfsdraw.FormCreate(Sender: TObject); +begin + dest := nil; +end; + +end. + diff --git a/Source/fsformunit.pas b/Source/fsformunit.pas new file mode 100644 index 0000000..3f71db8 --- /dev/null +++ b/Source/fsformunit.pas @@ -0,0 +1,18 @@ +unit fsformunit; + +interface + +uses + Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs; + +type + TFsForm = class(TForm) + public + PdName: String; + procedure Parse(const S: String); virtual; abstract; + end; + +implementation + +end. + \ No newline at end of file diff --git a/Source/fsframeunit.dfm b/Source/fsframeunit.dfm new file mode 100644 index 0000000..3e38f21 --- /dev/null +++ b/Source/fsframeunit.dfm @@ -0,0 +1,146 @@ +object fsframe: Tfsframe + Left = 583 + Top = 507 + Width = 277 + Height = 198 + Caption = 'fs.frame' + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [] + OldCreateOrder = False + PopupMenu = PopupMenu1 + Position = poDefaultSizeOnly + OnClose = FormClose + OnCreate = FormCreate + OnDestroy = FormDestroy + OnMouseWheel = FormMouseWheel + PixelsPerInch = 96 + TextHeight = 13 + object LabelFoo: TLabel + Left = 8 + Top = 136 + Width = 44 + Height = 13 + Caption = 'LabelFoo' + Visible = False + end + object PanelMute: TPanel + Left = 0 + Top = 0 + Width = 269 + Height = 171 + Align = alClient + BevelOuter = bvNone + Caption = 'mute' + Ctl3D = True + ParentCtl3D = False + TabOrder = 1 + end + object d1: TDXDraw + Left = 0 + Top = 0 + Width = 269 + Height = 171 + AutoInitialize = True + AutoSize = False + Color = clBtnFace + Display.FixedBitCount = False + Display.FixedRatio = False + Display.FixedSize = False + Options = [doStretch, doDirectX7Mode, doHardware, doSelectDriver] + SurfaceHeight = 171 + SurfaceWidth = 269 + Align = alClient + PopupMenu = PopupMenu1 + TabOrder = 0 + OnMouseDown = d1MouseDown + OnMouseMove = d1MouseMove + OnMouseUp = d1MouseUp + end + object PopupMenu1: TPopupMenu + OnPopup = PopupMenu1Popup + Left = 8 + Top = 8 + object MiBufferImages: TMenuItem + Caption = 'Buffer images' + OnClick = MiBufferImagesClick + end + object MiSaveFrame: TMenuItem + Caption = 'Save this image as ..' + OnClick = MiSaveFrameClick + end + object Mi11: TMenuItem + Caption = 'zoom 1:&1' + OnClick = Mi11Click + end + object Mi12: TMenuItem + Caption = 'zoom 1:&2' + OnClick = Mi12Click + end + object Mi176x144: TMenuItem + Caption = 'zoom 176x144' + OnClick = Mi176x144Click + end + object MiMute: TMenuItem + Caption = 'Mute' + OnClick = MiMuteClick + end + object MiBorders: TMenuItem + Caption = 'Borders' + Checked = True + OnClick = MiBordersClick + end + object MiStayOnTop: TMenuItem + Caption = 'StayOnTop' + OnClick = MiStayOnTopClick + end + object MiMouseTrack: TMenuItem + Caption = 'MouseTrack' + OnClick = MiMouseTrackClick + end + object MiHideCursor: TMenuItem + Caption = 'HideCursor' + OnClick = MiHideCursorClick + end + object MiUndock: TMenuItem + Caption = 'Undock' + OnClick = MiUndockClick + end + end + object dDib: TDXDIB + Left = 8 + Top = 40 + end + object dirBuffer: TScanDir + OnHandleFile = dirBufferHandleFile + Left = 8 + Top = 72 + end + object opd1: TOpenPictureDialog + Filter = 'All (*.jpg;*.bmp;*.avi)|*.jpg;*.bmp;*.avi' + Options = [ofHideReadOnly, ofAllowMultiSelect, ofFileMustExist, ofEnableSizing] + Left = 8 + Top = 104 + end + object framepsh: TC2PhotoShopHost + SerialNumber = 0 + BackColor = clBlack + ForeColor = clBlack + Left = 40 + Top = 8 + end + object svd1: TSaveDialog + Filter = '*.bmp|BMP files' + Options = [ofOverwritePrompt, ofHideReadOnly, ofPathMustExist, ofEnableSizing] + Left = 40 + Top = 104 + end + object dirUse: TScanDir + OnHandleFile = dirUseHandleFile + Left = 40 + Top = 72 + end +end diff --git a/Source/fsframeunit.pas b/Source/fsframeunit.pas new file mode 100644 index 0000000..e3316a7 --- /dev/null +++ b/Source/fsframeunit.pas @@ -0,0 +1,1098 @@ +{ Copyright (C) 2001 Juha Vehviläinen + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details.} + +unit fsframeunit; + +interface + +uses + Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, + Menus, Jpeg, DXDraws, + FastDIB, fsDcAvi, + fsformunit, ExtCtrls, DIB, Filez, ExtDlgs, C2PhotoShopHost, Buttons, + StdCtrls; + +type + TFastDIBList = TList; + + Tfsframe = class(TFsForm) + d1: TDXDraw; + PopupMenu1: TPopupMenu; + Mi11: TMenuItem; + Mi12: TMenuItem; + MiMute: TMenuItem; + dDib: TDXDIB; + MiBorders: TMenuItem; + MiStayOnTop: TMenuItem; + dirBuffer: TScanDir; + PanelMute: TPanel; + MiMouseTrack: TMenuItem; + MiBufferImages: TMenuItem; + opd1: TOpenPictureDialog; + MiSaveFrame: TMenuItem; + Mi176x144: TMenuItem; + MiHideCursor: TMenuItem; + framepsh: TC2PhotoShopHost; + MiUndock: TMenuItem; + svd1: TSaveDialog; + dirUse: TScanDir; + LabelFoo: TLabel; + procedure FormClose(Sender: TObject; var Action: TCloseAction); + procedure Mi11Click(Sender: TObject); + procedure Mi12Click(Sender: TObject); + procedure MiMuteClick(Sender: TObject); + procedure FormCreate(Sender: TObject); + procedure FormDestroy(Sender: TObject); + procedure MiBordersClick(Sender: TObject); + procedure MiStayOnTopClick(Sender: TObject); + procedure dirBufferHandleFile(const SearchRec: TSearchRec; + const FullPath: String); + procedure d1MouseDown(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); + procedure d1MouseMove(Sender: TObject; Shift: TShiftState; X, + Y: Integer); + procedure d1MouseUp(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); + procedure MiMouseTrackClick(Sender: TObject); + procedure MiBufferImagesClick(Sender: TObject); + procedure PopupMenu1Popup(Sender: TObject); + procedure MiSaveFrameClick(Sender: TObject); + procedure Mi176x144Click(Sender: TObject); + procedure MiHideCursorClick(Sender: TObject); + procedure FormMouseWheel(Sender: TObject; Shift: TShiftState; + WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean); + procedure MiUndockClick(Sender: TObject); + procedure dirUseHandleFile(const SearchRec: TSearchRec; + const FullPath: String); + protected + fx1, fx2: TFastDIB; + private + { Private declarations } + AutoFlip, Smooth: Boolean; + picBuf: TFastDIBList; + picIndex: Integer; + AutoSend: Boolean; + AutoSend_Address: String; + AutoSend_jpegqualitynet: Integer; + AutoSend_sendjpg: Boolean; + MouseTrack: Boolean; // report mouse x y + MouseRect: Boolean; // report dragged rectangle + FHideCursor: Boolean; // hide cursor in this frame + jpgquality: Integer; + jpegqualitynet: Integer; + prevtop: Integer; + prevmute: Boolean; + filelist: TStringList; + filelistIndex: Integer; + + procedure ClearPicBuf; + procedure StayOnTop(const Yes: Boolean); + function Getnextfilename(const dir, ext: String): String; + procedure _prefx; + procedure _postfx(const f: TFastDIB); + procedure _postavi; + procedure SendMouseTrack(const X, Y: Integer); + procedure SendMouseRect(const x1, y1, x2, y2: Integer); + function GetDocked: Boolean; + procedure SetHideCursor(const Value: Boolean); + procedure NewButton(const receivename: String; + const x, y: Integer; const buttoncaption: String); + public + { Public declarations } + avi: TDcAviPlayer; + NameTag: String; + procedure Borders(const Yes: Boolean); + procedure Parse(const S: String); override; + procedure FlipRequest; + procedure AutoSendRequest; + procedure HandleDroppedFile(const S: String); + property Docked: Boolean read GetDocked; + property HideCursor: Boolean read FHideCursor write SetHideCursor; + end; + +var + fsframe: Tfsframe; + +function FindFrame(const S: String): TFsFrame; + +implementation + +{$R *.DFM} + +uses + ShellApi, + FastFX, FastFiles, + mainunit, effectsunit, fsspeedbutton, + Strz, + FileCtrl, + pshostunit; + +function FindFrame(const S: String): TFsFrame; +begin + Result := TFsFrame(main.FindComponent(main.CompName(S))); +end; + +{ Tfsframe } + +procedure Tfsframe._prefx; +begin + dDib.DIB.Assign( d1.Surface ); + fx1.LoadFromHandle( dDib.DIB.Handle ); +end; + +procedure Tfsframe._postfx(const f: TFastDIB); +begin + f.Draw(d1.Surface.Canvas.Handle, 0, 0); + d1.Surface.Canvas.Release; + FlipRequest; +end; + +procedure Tfsframe._postavi; +begin + d1.SetSize(avi.Width, avi.Height); + avi.DrawFrameToDC(d1.Surface.Canvas.Handle); + d1.Surface.Canvas.Release; + FlipRequest; +end; + +procedure Tfsframe.Parse(const S: String); +var + fs, s1, Ext: String; + i, o, u, x, y: Integer; + fpic: TFastDIB; + savejpg, sendjpg: Boolean; + R: TRect; +begin + if S='' then Exit; + if (ParentWindow>0) and not + IsWindow(ParentWindow) then Exit; + + s1 := UpperCase(ExtractWord(1, S, [' '])); + Ext := UpperCase(ExtractFileExt(S)); + if s1='SAVE' then begin // SAVE <"bmp" or number for jpeg quality> + s1 := ExtractWord(2, S, [' ']); + if s1='' then Exit; + savejpg := True; + if WordCount(S, [' '])>2 then begin + Ext := UpperCase(ExtractWord(3, S, [' '])); + if Ext='BMP' then savejpg := False else begin + i := StrToInt(Ext); if i>0 then jpgquality := i; + end; + end; + if not DirectoryExists(s1) then begin + main.Post('Save: Directory '+s1+' doesn''t exist.'); + Exit; + end; + if savejpg then Ext:='.jpg' else Ext:='.bmp'; + fs := Getnextfilename(s1, Ext); + _prefx; + if savejpg then + SaveJPGFile(fx1, s1+'\'+fs, jpgquality) + else + fx1.SaveToFile(s1+'\'+fs); + end; + if (s1='BUFFER') or (Ext='.JPG') or (Ext='.BMP') then begin + fs := S; + if UpperCase(ExtractWord(1, fs, [' ']))<>'BUFFER' then begin + if main.FileExistsInSearchPath(fs) then begin + d1.Surface.LoadFromFile(fs); + FlipRequest; + end else + main.Post('Failed opening '+fs); + end else begin + fs := Copy(fs, 8, 255); + if main.FileExistsInSearchPath(fs) then begin + main.Post('buffering '+fs); + fpic := TFastDIB.Create; + fpic.Bpp := 16; + if Ext='.JPG' then + LoadJPGFile(fpic, fs, True) + else if Ext='.BMP' then + fpic.LoadFromFile(fs); + picBuf.Add(fpic); + end else + if DirectoryExists(fs) then begin + main.Post('buffering directory '+fs); + dirBuffer.Scan(fs); + end else + main.Post('Failed opening '+fs); + end; + end else + if s1='FLIP_MANUAL' then begin + AutoFlip := False; + end else + if s1='FLIP_AUTO' then begin + AutoFlip := True; + end else + if s1='FLIP' then begin + d1.Flip; + AutoSendRequest; + end else + if s1='NEXT' then begin + if picBuf.Count=0 then begin + if filelist.Count=0 then begin + if avi.Open then begin + if avi.Position=avi.FrameCount-1 then + avi.Seek(0) + else + avi.Seek(avi.Position+1); + _postavi; + end; + Exit; + end; + Inc(filelistIndex); + if filelistIndex>=filelist.Count then + filelistIndex := 0; + Parse(filelist.Strings[filelistIndex]); + Exit; + end; + Inc(picIndex); + if picIndex>=picBuf.Count then + picIndex := 0; + fpic := picBuf[picIndex]; + d1.Surface.SetSize(fpic.Width, fpic.Height); + _postfx(fpic); + end else + if s1='PREV' then begin + if picBuf.Count=0 then begin + if filelist.Count=0 then begin + // avi + if avi.Open then begin + if avi.Position=0 then + avi.Seek(avi.FrameCount-1) + else + avi.Seek(avi.Position-1); + _postavi; + end; + Exit; + end; + + // filelist + Dec(filelistIndex); + if filelistIndex<0 then + filelistIndex := filelist.Count-1; + Parse(filelist.Strings[filelistIndex]); + Exit; + + end; + // picbuf + Dec(picIndex); + if picIndex<0 then + picIndex := PicBuf.Count-1; + fpic := picBuf[picIndex]; + d1.Surface.SetSize(fpic.Width, fpic.Height); + _postfx(fpic); + + end else + if s1='SEEK' then begin + s1 := ExtractWord(2, S, [' ']); + if s1='' then Exit; + if picBuf.Count=0 then begin + if filelist.Count=0 then begin + if avi.Open then begin + if s1[Length(s1)]='*' then + i := Trunc(MyStrToFloat(Copy(s1, 1, Length(s1)-1))*avi.FrameCount-1) + else + i := MyStrToInt(s1); + avi.Seek(i); + _postavi; + end; + Exit; + end; + + if s1[Length(s1)]='*' then + i := Trunc(MyStrToFloat(Copy(s1, 1, Length(s1)-1))*filelist.Count-1) + else + i := MyStrToInt(s1); + if (i>=0) and (i=0) and (i0 then begin + x := MyStrToInt(Trim(ExtractWord(1, s1, ['X']))); + y := MyStrToInt(Trim(ExtractWord(2, s1, ['X']))); + d1.Surface.SetSize(x, y); + d1.Initialize; + ClientWidth := x; + ClientHeight := y; + end else + if Pos('+', s1)>0 then begin + x := MyStrToInt(Trim(ExtractWord(1, s1, ['+']))); + y := MyStrToInt(Trim(ExtractWord(2, s1, ['+']))); + Left := x; + Top := y; + end else + Exit; + end else + if s1='DISPLAY' then begin + s1 := UpperCase(Trim(Copy(S, 8, 255))); + x := MyStrToInt(Trim(ExtractWord(1, s1, ['X']))); + y := MyStrToInt(Trim(ExtractWord(2, s1, ['X']))); + if (x>0) and (y>0) then begin + ClientWidth := x; + ClientHeight := y; + end; + end else + if s1='BORDERS_0' then begin + Borders(False); + end else + if s1='BORDERS_1' then begin + Borders(True); + end else + if s1='STAYONTOP_1' then begin + StayOnTop(True); + end else + if s1='STAYONTOP_0' then begin + StayOnTop(False); + end else + if s1='MUTE_0' then begin + MiMute.Checked := True; + MiMute.Click; + end else + if s1='MUTE_1' then begin + MiMute.Checked := False; + MiMute.Click; + end else + // FastLib effects + if s1='MOSAIC' then begin + i := MyStrToInt(ExtractWord(2, S, [' '])); + if i=0 then i:=6; + _prefx; + FastFX.Mosaic(fx1, i, i); + _postfx(fx1); + end else + if s1='SMOOTH_0' then begin + Smooth := False; + end else + if s1='SMOOTH_1' then begin + Smooth := True; + end else + if s1='ROTATE' then begin + i := MyStrToInt(ExtractWord(2, S, [' '])); + if i=0 then Exit; + _prefx; + fx2.SetSize(fx1.Width, fx1.Height, fx1.Bpp); + fx2.Clear(IntToColor(0)); + FastFX.Rotate(fx1, fx2, i, Smooth); + _postfx(fx2); + end else + if s1='ROTOZOOM' then begin + i := MyStrToInt(ExtractWord(2, S, [' '])); + o := MyStrToInt(ExtractWord(3, S, [' '])); + if (i=0) and (o=0) then Exit; + _prefx; + fx2.SetSize(fx1.Width, fx1.Height, fx1.Bpp); + fx2.Clear(IntToColor(0)); + FastFX.Rotozoom(fx1, fx2, i, o, Smooth); + _postfx(fx2); + end else + if s1='SATURATION' then begin + i := MyStrToInt(ExtractWord(2, S, [' '])); + _prefx; + FastFX.Saturation(fx1, i); + _postfx(fx1); + end else + if s1='INVERT' then begin + _prefx; + FastFX.Invert(fx1); + _postfx(fx1); + end else + if s1='SOFT' then begin + _prefx; + FastFX.QuickSoft(fx1); + _postfx(fx1); + end else + if s1='SHARP' then begin + _prefx; + FastFX.QuickSharp(fx1); + _postfx(fx1); + end else + if s1='EMBOSS' then begin + _prefx; + FastFX.QuickEmboss(fx1); + _postfx(fx1); + end else + if s1='ADDITION' then begin + i := MyStrToInt(ExtractWord(2, S, [' '])); + o := MyStrToInt(ExtractWord(3, S, [' '])); + u := MyStrToInt(ExtractWord(4, S, [' '])); + if (i=0) and (o=0) and (u=0) then Exit; + _prefx; + FastFX.Addition(fx1, i, o, u); + _postfx(fx1); + end else + if s1='GAMMA' then begin + i := MyStrToInt(ExtractWord(2, S, [' '])); + o := MyStrToInt(ExtractWord(3, S, [' '])); + u := MyStrToInt(ExtractWord(4, S, [' '])); + if (i=0) and (o=0) and (u=0) then Exit; + _prefx; + FastFX.Gamma(fx1, i, o, u); + _postfx(fx1); + end else + if s1='CONTRAST' then begin + i := MyStrToInt(ExtractWord(2, S, [' '])); + o := MyStrToInt(ExtractWord(3, S, [' '])); + u := MyStrToInt(ExtractWord(4, S, [' '])); + if (i=0) and (o=0) and (u=0) then Exit; + _prefx; + FastFX.Contrast(fx1, i, o, u); + _postfx(fx1); + end else + if s1='LIGHTNESS' then begin + i := MyStrToInt(ExtractWord(2, S, [' '])); + o := MyStrToInt(ExtractWord(3, S, [' '])); + u := MyStrToInt(ExtractWord(4, S, [' '])); + if (i=0) and (o=0) and (u=0) then Exit; + _prefx; + FastFX.Lightness(fx1, i, o, u); + _postfx(fx1); + end else + if s1='SCRAMBLE' then begin + scramble(d1.Surface); + FlipRequest; + end else + if s1='CONNECT' then begin + i:=WordCount(S, [' ']); + if i<3 then begin + main.Post('Usage: Connect '); + Exit; + end; + s1:=ExtractWord(2, S, [' ']); + i := MyStrToInt(ExtractWord(3, S, [' '])); + if i<=0 then Exit; + if (main.csfs.Host<>s1) or (main.csfs.Port<>i) then begin + if main.csfs.Active then + main.csfs.Active:=False; + main.csfs.Host:=s1; + main.csfs.Port:=i; + end; + main.csfs.Open; + end else + if s1='DISCONNECT' then begin + main.csfs.Close; + end else + if (s1='SEND') or (s1='SEND_AUTO') then begin + i:=WordCount(S, [' ']); + if i<2 then begin + main.Post('Usage: Send ["pure" for uncompressed or jpeg quality (default=80)]'); + main.Post('Use "receive " to set receiving fs.frame on the other end.'); + Exit; + end; + sendjpg := True; + if i>2 then begin + Ext := UpperCase(ExtractWord(3, S, [' '])); + if Ext='PURE' then + sendjpg := False + else begin + jpegqualitynet := MyStrToInt(Ext); + if jpegqualitynet<=0 then jpegqualitynet:=80; + end; + end; + if sendjpg then + _prefx; + main.SendFrame(Self, ExtractWord(2, S, [' ']), + fx1, jpegqualitynet, sendjpg); + if s1='SEND_AUTO' then begin + AutoSend := True; + AutoSend_Address := ExtractWord(2, S, [' ']); + AutoSend_jpegqualitynet := jpegqualitynet; + AutoSend_sendjpg := sendjpg; + end; + end else + if s1='SEND_MANUAL' then begin + AutoSend := False; + end else + if s1='RECEIVE' then begin + Self.NameTag := ExtractWord(2, S, [' ']); + end else + if s1='MOUSETRACK_1' then begin + MouseTrack := True; + MiMouseTrack.Checked := True; + end else + if s1='MOUSETRACK_0' then begin + MouseTrack := False; + MiMouseTrack.Checked := False; + end else + if s1='MOUSERECT_1' then begin + MouseRect := True; + end else + if s1='MOUSERECT_0' then begin + MouseRect := False; + end else + if s1='HIDECURSOR_1' then begin + MiHideCursor.Checked := True; + HideCursor := True; + end else + if s1='HIDECURSOR_0' then begin + MiHideCursor.Checked := False; + HideCursor := False; + end else + if s1='DOCK' then begin + DockTitle := Copy(S, Length(s1)+2, 255); + DockHandle:=0; + EnumWindows(@mainunit.WinEnumerator_SubStr, 0); + if DockHandle>0 then begin + if MiBorders.Checked then + MiBorders.Click; + if GetWindowRect(DockHandle, R) then begin + d1.Hide; + WindowState := wsNormal; + ParentWindow := 0; + Parent := nil; + ParentWindow := DockHandle; + Left := 0; + Top := 0; + d1.Show; + d1.Initialize; + BringToFront; + DragAcceptFiles(Handle, True); + end; + end; + end else + if s1='SHOW' then begin + Self.Top := prevtop; + if not prevmute and MiMute.Checked then + MiMute.Click; + end else + if s1='HIDE' then begin + // ugly, but. + prevtop := Self.Top; + Self.Top := Screen.Height; + prevmute := MiMute.Checked; + if not prevmute then MiMute.Click; + end else + if s1='BUFFERIZE' then begin + _prefx; + fpic := TFastDIB.Create; + fpic.LoadFromHandle(fx1.Handle); + picBuf.Add(fpic); + end else + if s1='MAXIMIZE' then begin + WindowState := wsMaximized; + end else + if s1='MINIMIZE' then begin + WindowState := wsMinimized; + end else + if s1='BRINGTOFRONT' then begin + BringToFront; + end else + if s1='USE' then begin // use directory + s1 := Copy(S, Length(s1)+2, 255); + if DirectoryExists(s1) then begin + i := filelist.Count; + dirUse.Scan(s1); + main.Post('Using '+IntToStr(filelist.Count-i)+' images from '+s1+', total of '+IntToStr(filelist.Count)); + end else + main.Post('nonexistent directory: '+s1); + end else + if s1='BUTTON' then begin + s1 := Copy(S, Length(s1)+2, 255); + if WordCount(s1, [' '])<>4 then Exit; + NewButton(ExtractWord(1, s1, [' ']), // receive name + MyStrToInt(ExtractWord(2, s1, [' '])), // x + MyStrToInt(ExtractWord(3, s1, [' '])), // y + ExtractWord(4, s1, [' ']) // caption + ); + end else + if False{your new effect here} then begin + end else + if main.Plugins.IsPlugin(s1) then begin + if main.Plugins.CallEffect(d1.Surface, s1, Copy(S, Length(s1)+2, 255)) then + FlipRequest; + end else + if pshostunit.IsFilter(s1) then begin + pshostunit.Filter_effect(framepsh, d1.Surface, s1, Copy(S, Length(s1)+2, 255)); + FlipRequest; + end else +end; + +procedure Tfsframe.FormClose(Sender: TObject; var Action: TCloseAction); +begin + Action := caFree; +end; + +procedure Tfsframe.Mi11Click(Sender: TObject); +begin + ClientWidth := d1.Surface.Width; + ClientHeight := d1.Surface.Height; +end; + +procedure Tfsframe.Mi12Click(Sender: TObject); +begin + ClientWidth := d1.Surface.Width * 2; + ClientHeight := d1.Surface.Height * 2; +end; + +procedure Tfsframe.MiMuteClick(Sender: TObject); +begin + MiMute.Checked := not MiMute.Checked; + d1.Visible := not MiMute.Checked; +end; + +procedure Tfsframe.ClearPicBuf; +var + f: TFastDIB; + i: Integer; +begin + if picBuf.Count=0 then Exit; + for i:=picBuf.Count-1 downto 0 do begin + f := picBuf[i]; + f.Free; + picBuf.Delete(i); + end; +end; + +procedure Tfsframe.FlipRequest; +begin + if AutoFlip then begin + d1.Flip; + AutoSendRequest; + end; +end; + +procedure Tfsframe.AutoSendRequest; +begin + if AutoSend and main.csfs.Active then begin + if AutoSend_sendjpg then + _prefx; + main.SendFrame(Self, AutoSend_address, + fx1, AutoSend_jpegqualitynet, AutoSend_sendjpg); + end; +end; + +procedure Tfsframe.Borders(const Yes: Boolean); +begin + _prefx; + d1.Hide; + if Yes and (ParentWindow=0) then + BorderStyle := bsSizeable + else + BorderStyle := bsNone; + d1.Show; + d1.Initialize; + _postfx(fx1); + MiBorders.Checked := Yes; + DragAcceptFiles(Handle, True); +end; + +procedure Tfsframe.StayOnTop(const Yes: Boolean); +begin + _prefx; + d1.Hide; + if Yes and (ParentWindow=0) then + FormStyle := fsStayOnTop + else + FormStyle := fsNormal; + d1.Show; + d1.Initialize; + _postfx(fx1); + MiStayOnTop.Checked := Yes; + DragAcceptFiles(Handle, True); +end; + +procedure Tfsframe.MiBordersClick(Sender: TObject); +begin + if Docked then Exit; + MiBorders.Checked := not MiBorders.Checked; + Borders(MiBorders.Checked); +end; + +procedure Tfsframe.MiStayOnTopClick(Sender: TObject); +begin + if Docked then Exit; + MiStayOnTop.Checked := not MiStayOnTop.Checked; + StayOnTop(MiStayOnTop.Checked); +end; + +procedure Tfsframe.dirBufferHandleFile(const SearchRec: TSearchRec; + const FullPath: String); +var + S: String; +begin + S := UpperCase(ExtractFileExt(FullPath)); + if (S='.BMP') or (S='.JPG') then + Parse('BUFFER '+FullPath); +end; + +procedure Tfsframe.dirUseHandleFile(const SearchRec: TSearchRec; + const FullPath: String); +var + S: String; +begin + S := UpperCase(ExtractFileExt(FullPath)); + if (S='.BMP') or (S='.JPG') then + filelist.Add(FullPath); +end; + +function Tfsframe.Getnextfilename(const dir, ext: String): String; +const + pref = 'fs'; + last: Integer = 0; + predir: string = ''; +var + S: String; +begin + if dir<>predir then last := 0; + repeat + Inc(last); + S := pref + IntToStr(last); + while Length(S)<8 do Insert('0', S, 3); + S := S+ext; + until not FileExists(S); + Result := S; + predir := dir; +end; + +procedure Tfsframe.FormCreate(Sender: TObject); +begin + ClientWidth := 176; + ClientHeight := 144; + d1.SetSize( ClientWidth, ClientHeight ); + d1.Initialize; + with d1.Surface.Canvas do begin + Pen.Color := clWhite; + Brush.Color := clWhite; + Font.Color := clWhite; + end; + d1.Surface.Canvas.Release; + AutoFlip := True; + AutoSend := False; + Smooth := True; + avi := TDcAviPlayer.Create(Self); + avi.Parent := Self; + avi.Visible := False; + avi.Transparent := False; + avi.Stretch := False; + avi.PlaySound := False; + fx1 := TFastDIB.Create; + fx2 := TFastDIB.Create; + picBuf := TFastDIBList.Create; + picIndex := -1; + MouseTrack := False; + MouseRect := False; + HideCursor := False; + jpgquality := 85; + jpegqualitynet := 80; + prevtop := 0; + prevmute := False; + filelist := TStringList.Create; + filelistIndex := -1; + DragAcceptFiles(Handle, True); +end; + +procedure Tfsframe.FormDestroy(Sender: TObject); +begin + avi.Free; + fx1.Free; + fx2.Free; + ClearPicBuf; + picBuf.Free; + filelist.Free; +end; + +var + LeftDown: Boolean; + OrgX, OrgY: Integer; + +procedure Tfsframe.d1MouseDown(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); +begin + case Button of + mbLeft: begin + LeftDown := True; + main.SendReturnValues(PdName+'mousedown=1'); + if MouseTrack and not MouseRect and not (ssAlt in Shift) then + SendMouseTrack(X, Y) + else begin + OrgX := X; + OrgY := Y; + end; + end; + end; +end; + +procedure Tfsframe.d1MouseMove(Sender: TObject; Shift: TShiftState; X, + Y: Integer); +begin + if LeftDown then begin + if MouseTrack and not (ssAlt in Shift) then begin + if not MouseRect then + SendMouseTrack(X, Y) + else + SendMouseRect(OrgX, OrgY, X, Y); + end else begin + Left := Left + (X-OrgX); + Top := Top + (Y-OrgY); + end; + end; +end; + +procedure Tfsframe.d1MouseUp(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); +begin + case Button of + mbLeft: begin + LeftDown:=False; +(* these values were sent at "mousemove" + if MouseRect then + SendMouseRect(OrgX, OrgY, X, Y);*) + main.SendReturnValues(PdName+'mouseup=1'); + if not MouseTrack or (ssAlt in Shift) then begin +// main.Post('moved to '+ +// IntToStr(Left)+'+'+ +// IntToStr(Top) +// ); + main.SendReturnValues( + PdName+'winy='+IntToStr(Top)+';'+ + PdName+'winx='+IntToStr(Left) + ); + end; + end; + end; +end; + +procedure Tfsframe.SendMouseTrack(const X, Y: Integer); +var + a, b: Integer; +begin + a := X; + b := Y; + // handle aspect ratios different from 1:1 + if d1.Surface.Width<>d1.Width then + a := Trunc((d1.Surface.Width / d1.Width) * X); + if d1.Surface.Height<>d1.Height then + b := Trunc((d1.Surface.Height / d1.Height) * Y); + + main.SendReturnValues( + PdName+'y='+IntToStr(b)+';'+ + PdName+'x='+IntToStr(a) + ); +end; + +procedure Tfsframe.SendMouseRect(const x1, y1, x2, y2: Integer); +var + a, b, c, d: Integer; +begin + a := x1; + b := y1; + c := x2; + d := y2; + // handle aspect ratios different from 1:1 + if d1.Surface.Width<>d1.Width then + a := Trunc((d1.Surface.Width / d1.Width) * x1); + if d1.Surface.Height<>d1.Height then + b := Trunc((d1.Surface.Height / d1.Height) * y1); + if d1.Surface.Width<>d1.Width then + c := Trunc((d1.Surface.Width / d1.Width) * x2); + if d1.Surface.Height<>d1.Height then + d := Trunc((d1.Surface.Height / d1.Height) * y2); + + main.SendReturnValues( + PdName+'y2='+IntToStr(d)+';'+ + PdName+'x2='+IntToStr(c)+';'+ + PdName+'y1='+IntToStr(b)+';'+ + PdName+'x1='+IntToStr(a) + ); +end; + +procedure Tfsframe.MiMouseTrackClick(Sender: TObject); +begin + MouseTrack := not MouseTrack; + MiMouseTrack.Checked := MouseTrack; +end; + +procedure Tfsframe.HandleDroppedFile(const S: String); +var + i: Integer; + St: String; +begin + Parse(S); + main.SendReturnValues(PdName+'bang=1'); + // send string as a series of ascii.. + main.SendReturnValuesString(PDName+'file', S); +end; + +procedure Tfsframe.MiBufferImagesClick(Sender: TObject); +var + i: Integer; + s: String; +begin + if opd1.Execute then begin + if opd1.Files.Count>0 then + for i:=0 to opd1.Files.Count-1 do begin + if '.AVI'<>UpperCase(ExtractFileExt(opd1.files[i])) then + s := 'BUFFER ' + else + s := ''; + Parse(s+opd1.files[i]); + end; + // tee uusi canvas jossa valitut failit.... + end; +{ +#N canvas 0 0 700 300 12; +#X obj 23 17 inlet; +#X obj 15 45 outlet; +#X msg 71 17 buffer file1.bmp \, buffer file2.bmp \, buffer file3.bmp; +#X connect 0 0 2 0; +#X connect 2 0 1 0; +} +end; + +function Tfsframe.GetDocked: Boolean; +begin + Result := ParentWindow<>0; +end; + +procedure Tfsframe.PopupMenu1Popup(Sender: TObject); +begin + MiBorders.Enabled := not Docked; + MiStayOnTop.Enabled := not Docked; + MiUndock.Enabled := Docked; +end; + +procedure Tfsframe.MiSaveFrameClick(Sender: TObject); +var + S: String; +begin + if svd1.Execute then begin + S := svd1.Filename; + if Uppercase(ExtractFileExt(S))<>'.BMP' then + S := S+'.bmp'; + _prefx; + fx1.SaveToFile(S); + end; +{ + _prefx; + if savejpg then + SaveJPGFile(fx1, s1+'\'+fs, jpgquality) + else + fx1.SaveToFile(s1+'\'+fs); +} +end; + +procedure Tfsframe.Mi176x144Click(Sender: TObject); +begin + Parse('display 176x144'); +end; + +procedure Tfsframe.SetHideCursor(const Value: Boolean); +begin + FHideCursor := Value; + if Value then + d1.Cursor := crNone + else + d1.Cursor := crDefault; +end; + +procedure Tfsframe.MiHideCursorClick(Sender: TObject); +begin + MiHideCursor.Checked := not MiHideCursor.Checked; + HideCursor := MiHideCursor.Checked; +end; + +procedure Tfsframe.FormMouseWheel(Sender: TObject; Shift: TShiftState; + WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean); +var + asp: Extended; +begin + if WheelDelta>0 then begin + ClientWidth := Trunc(ClientWidth * (WheelDelta / 100)); + if not (ssShift in Shift) then + ClientHeight := Trunc(ClientHeight * (WheelDelta / 100)); + end else begin + ClientWidth := Trunc(ClientWidth / Abs(WheelDelta / 100)); + if not (ssShift in Shift) then + ClientHeight := Trunc(ClientHeight / Abs(WheelDelta / 100)); + end; + // correct aspect ratio... + if ssShift in Shift then begin + asp := d1.Surface.Width / d1.Surface.Height; + if asp>0 then + ClientHeight := Trunc(ClientWidth / asp); + end; +end; + +procedure Tfsframe.MiUndockClick(Sender: TObject); +begin + ParentWindow := 0; + Borders(True); +end; + +procedure Tfsframe.NewButton(const receivename: String; const x, + y: Integer; const buttoncaption: String); +var + p: TPanel; + b: TFSSpeedButton; +begin + p := TPanel.Create(Self); + b := TFSSpeedButton.Create(Self); + + b.Width := LabelFoo.Canvas.TextWidth(buttoncaption)+12; + b.Height := 18; + b.Parent := p; + b.Left := 0; + b.Top := 0; + b.Flat := True; + b.Caption := buttoncaption; + b.Receivename := receivename; + p.AutoSize := True; + p.Left := x; + p.Top := y; + p.BevelOuter := bvNone; + p.Parent := d1; +end; + +end. + diff --git a/Source/fsinfounit.dfm b/Source/fsinfounit.dfm new file mode 100644 index 0000000..3079d24 --- /dev/null +++ b/Source/fsinfounit.dfm @@ -0,0 +1,16 @@ +object fsinfo: Tfsinfo + Left = 242 + Top = 103 + Width = 356 + Height = 122 + Caption = 'fsinfo' + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [] + OldCreateOrder = False + PixelsPerInch = 96 + TextHeight = 13 +end diff --git a/Source/fsinfounit.pas b/Source/fsinfounit.pas new file mode 100644 index 0000000..d8de65d --- /dev/null +++ b/Source/fsinfounit.pas @@ -0,0 +1,53 @@ +unit fsinfounit; + +interface + +uses + Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, + fsformunit; + +type + Tfsinfo = class(TFsForm) + private + { Private declarations } + public + { Public declarations } + procedure Parse(const S: String); override; + end; + +var + fsinfo: Tfsinfo; + +implementation + +uses + mainunit, fsframeunit, + Strz; + +{$R *.DFM} + +{ Tfsinfo } + +procedure Tfsinfo.Parse(const S: String); +var + s1: String; + f: TFsFrame; +begin + if (S='') or + (WordCount(S, [' '])<5) or + (not main.cstoPd.Active) then Exit; + + s1 := ExtractWord(1, S, [' ']); + f := FindFrame(s1); + if f=nil then Exit; + + main.SendReturnValues( + ExtractWord(5, S, [' '])+'='+IntToStr(f.Avi.FrameRate)+';'+ + ExtractWord(4, S, [' '])+'='+IntToStr(f.Avi.FrameCount)+';'+ + ExtractWord(3, S, [' '])+'='+IntToStr(f.d1.Surface.Height)+';'+ + ExtractWord(2, S, [' '])+'='+IntToStr(f.d1.Surface.Width) + ); +end; + +end. + diff --git a/Source/fsspeedbutton.pas b/Source/fsspeedbutton.pas new file mode 100644 index 0000000..da3d53a --- /dev/null +++ b/Source/fsspeedbutton.pas @@ -0,0 +1,48 @@ +unit fsspeedbutton; + +interface + +uses + Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, + Buttons; + +type + TFSSpeedButton = class(TSpeedButton) + private + { Private declarations } + procedure MyOnClick(Sender: TObject); + protected + { Protected declarations } + public + { Public declarations } + Receivename: String; + constructor Create(AOwner: TComponent); override; + published + { Published declarations } + end; + +procedure Register; + +implementation + +uses + mainunit; + +procedure Register; +begin +end; + +{ TFSSpeedButton } + +constructor TFSSpeedButton.Create(AOwner: TComponent); +begin + inherited; + OnClick := MyOnClick; +end; + +procedure TFSSpeedButton.MyOnClick(Sender: TObject); +begin + main.SendReturnValues(Receivename+'=1'); +end; + +end. diff --git a/Source/fstextunit.dfm b/Source/fstextunit.dfm new file mode 100644 index 0000000..c8ff138 --- /dev/null +++ b/Source/fstextunit.dfm @@ -0,0 +1,18 @@ +object fstext: Tfstext + Left = 231 + Top = 103 + Width = 236 + Height = 79 + Caption = 'fstext' + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [] + OldCreateOrder = False + WindowState = wsMinimized + OnCreate = FormCreate + PixelsPerInch = 96 + TextHeight = 13 +end diff --git a/Source/fstextunit.pas b/Source/fstextunit.pas new file mode 100644 index 0000000..92230db --- /dev/null +++ b/Source/fstextunit.pas @@ -0,0 +1,148 @@ +{ Copyright (C) 2001 Juha Vehviläinen + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details.} + +unit fstextunit; + +interface + +uses + Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, + mainunit, fsformunit, fsframeunit; + +type + Tfstext = class(TFsForm) + procedure FormCreate(Sender: TObject); + private + { Private declarations } + dest: TFsFrame; + x, y: Integer; + public + { Public declarations } + procedure Parse(const S: String); override; + end; + +var + fstext: Tfstext; + +function ParsePenProperties(const Canvas: TCanvas; const S: String): Boolean; + +implementation + +{$R *.DFM} + +uses + Strz; + +function ParsePenProperties(const Canvas: TCanvas; const S: String): Boolean; +var + s1: String; + r, g, b: Integer; +begin + Result := False; + s1 := UpperCase(ExtractWord(1, S, [' '])); + if s1='PEN' then begin + if WordCount(S, [' '])<4 then + main.Post('Usage: PEN ') + else begin + r := MyStrToInt(ExtractWord(2, S, [' '])); + g := MyStrToInt(ExtractWord(3, S, [' '])); + b := MyStrToInt(ExtractWord(4, S, [' '])); + Canvas.Pen.Color := RGB(r, g, b); + end; + Result := True; + end else + if s1='BRUSH' then begin + if WordCount(S, [' '])<4 then + main.Post('Usage: BRUSH ') + else begin + r := MyStrToInt(ExtractWord(2, S, [' '])); + g := MyStrToInt(ExtractWord(3, S, [' '])); + b := MyStrToInt(ExtractWord(4, S, [' '])); + Canvas.Brush.Color := RGB(r, g, b); + end; + Result := True; + end else + if s1='COLOR' then begin + if WordCount(S, [' '])<4 then + main.Post('Usage: COLOR ') + else begin + r := MyStrToInt(ExtractWord(2, S, [' '])); + g := MyStrToInt(ExtractWord(3, S, [' '])); + b := MyStrToInt(ExtractWord(4, S, [' '])); + Canvas.Font.Color := RGB(r, g, b); + end; + Result := True; + end else + if s1='SIZE' then begin + Canvas.Font.Size := MyStrToInt(ExtractWord(2, S, [' '])); + Result := True; + end else + if s1='FONT' then begin + Canvas.Font.Name := Copy(S, Length(s1)+2, 255); + Result := True; + end else +end; + +{ Tfstext } + +procedure Tfstext.Parse(const S: String); +const + y: Integer = 0; +var + s1, sa: String; + b: Boolean; +begin + if (S='') then Exit; + + s1 := ExtractWord(WordCount(S, [' ']), S, [' ']); + dest := FindFrame(s1); + if (dest=nil) or (dest.d1=nil) then Exit; + + sa := Copy(S, 1, Pos(s1, S)-2); + + b := ParsePenProperties(dest.d1.Surface.Canvas, UpperCase(sa)); + dest.d1.Surface.Canvas.Release; + if b then Exit; + + s1 := UpperCase(ExtractWord(1, sa, [' '])); + if s1='POS' then begin + self.x := MyStrToInt(ExtractWord(2, sa, [' '])); + self.y := MyStrToInt(ExtractWord(3, sa, [' '])); + Exit; + end; + + with dest.d1.Surface.Canvas do begin + Brush.Style := bsClear; + + if (self.x>-1) and (self.y>-1) then + TextOut(self.x, self.y, sa) + else begin + TextOut(0, y, sa); + + Inc(Y, TextHeight(S)); + if y>dest.d1.Surface.Height then + y := 0; + end; + end; + dest.d1.Surface.Canvas.Release; + + dest.FlipRequest; +end; + +procedure Tfstext.FormCreate(Sender: TObject); +begin + dest := nil; + x := -1; + y := -1; +end; + +end. + diff --git a/Source/logunit.dfm b/Source/logunit.dfm new file mode 100644 index 0000000..bd8c429 --- /dev/null +++ b/Source/logunit.dfm @@ -0,0 +1,100 @@ +object log: Tlog + Left = 239 + Top = 39 + Width = 603 + Height = 666 + BorderStyle = bsSizeToolWin + Caption = 'Console / Log' + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [] + OldCreateOrder = False + Position = poDesktopCenter + OnCreate = FormCreate + PixelsPerInch = 96 + TextHeight = 13 + object PanelLog: TPanel + Left = 0 + Top = 221 + Width = 595 + Height = 418 + Align = alClient + BevelOuter = bvNone + TabOrder = 0 + object Panel2: TPanel + Left = 0 + Top = 400 + Width = 595 + Height = 18 + Align = alBottom + AutoSize = True + BevelOuter = bvNone + TabOrder = 0 + object ButtonClear: TButton + Left = 75 + Top = 0 + Width = 75 + Height = 18 + Caption = 'Clear' + TabOrder = 1 + OnClick = ButtonClearClick + end + object ButtonClose: TButton + Left = 0 + Top = 0 + Width = 75 + Height = 18 + Caption = 'Close' + Default = True + TabOrder = 0 + OnClick = ButtonCloseClick + end + end + object RELog: TRichEdit + Left = 0 + Top = 0 + Width = 595 + Height = 400 + Align = alClient + BorderStyle = bsNone + Ctl3D = True + ParentCtl3D = False + PlainText = True + ScrollBars = ssVertical + TabOrder = 1 + WordWrap = False + end + end + object Panel1: TPanel + Left = 0 + Top = 203 + Width = 595 + Height = 18 + Align = alTop + BevelOuter = bvLowered + Caption = 'Log' + TabOrder = 2 + end + object PanelConsole: TPanel + Left = 0 + Top = 18 + Width = 595 + Height = 185 + Align = alTop + BevelOuter = bvNone + TabOrder = 1 + end + object Panel3: TPanel + Left = 0 + Top = 0 + Width = 595 + Height = 18 + Align = alTop + BevelOuter = bvLowered + Caption = 'Console' + TabOrder = 3 + end +end diff --git a/Source/logunit.pas b/Source/logunit.pas new file mode 100644 index 0000000..187684f --- /dev/null +++ b/Source/logunit.pas @@ -0,0 +1,60 @@ +unit logunit; + +interface + +uses + Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, + StdCtrls, ComCtrls, ExtCtrls; + +type + Tlog = class(TForm) + PanelLog: TPanel; + Panel2: TPanel; + ButtonClear: TButton; + RELog: TRichEdit; + PanelConsole: TPanel; + Panel1: TPanel; + Panel3: TPanel; + ButtonClose: TButton; + procedure ButtonClearClick(Sender: TObject); + procedure FormCreate(Sender: TObject); + procedure ButtonCloseClick(Sender: TObject); + private + { Private declarations } + public + { Public declarations } + procedure add(const s: String); + end; + +var + log: Tlog; + +implementation + +uses mainunit; + +{$R *.DFM} + +procedure Tlog.add(const s: String); +begin + RELog.Lines.Add(s); +end; + +procedure Tlog.ButtonCloseClick(Sender: TObject); +begin + main.MiLog.Click; +end; + +procedure Tlog.ButtonClearClick(Sender: TObject); +begin + main.REConsole.Lines.Clear; + RELog.Lines.Clear; +end; + +procedure Tlog.FormCreate(Sender: TObject); +begin + main.REConsole.Parent := PanelConsole; + main.REConsole.Align := alClient; +end; + +end. diff --git a/Source/mainunit.dfm b/Source/mainunit.dfm new file mode 100644 index 0000000..46a9252 --- /dev/null +++ b/Source/mainunit.dfm @@ -0,0 +1,3547 @@ +object main: Tmain + Left = 16 + Top = 497 + Width = 239 + Height = 223 + Caption = 'Framestein' + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [] + OldCreateOrder = False + OnClose = FormClose + OnCreate = FormCreate + OnDestroy = FormDestroy + PixelsPerInch = 96 + TextHeight = 13 + object ImageLogo: TImage + Left = 0 + Top = 0 + Width = 231 + Height = 196 + Align = alClient + Picture.Data = { + 07544269746D617086AE0100424D86AE0100000000003600000028000000D700 + 0000AA000000010018000000000050AE0100120B0000120B0000000000000000 + 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF + 00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2 + FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2 + FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF + 00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2 + FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF + 00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00 + D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2 + FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5CED + EB325C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF + 00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2 + FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5CBDADAF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C6D05BB5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5CF56EED5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2 + FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C2F + E8ED5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C4D6FF85C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2 + FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00 + D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF + 00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2 + FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00 + D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF + 00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF + 00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00 + D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2 + FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00 + D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF + 00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2 + FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00 + D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF + 00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2 + FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF + 00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2 + FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00 + D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF + 00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2 + FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C0000005C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00 + 00005C5C5C5C5C5C5C5C5C5C5C5C5C5C5C00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2 + FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00 + D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF + 00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF00D2FF5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5CEDEB325C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5CBDADAF5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C6D05BB5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5CF5 + 6EED5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C2FE8ED5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C4D6FF8} + PopupMenu = PopupMenu1 + Stretch = True + OnDblClick = ImageLogoDblClick + end + object REConsole: TRichEdit + Left = 136 + Top = 104 + Width = 81 + Height = 73 + BorderStyle = bsNone + ReadOnly = True + ScrollBars = ssVertical + TabOrder = 0 + end + object ss1: TServerSocket + Active = False + Port = 6001 + ServerType = stNonBlocking + OnClientConnect = ss1ClientConnect + OnClientDisconnect = ss1ClientDisconnect + OnClientRead = ss1ClientRead + OnClientError = ss1ClientError + end + object PopupMenu1: TPopupMenu + Left = 64 + object MiConfig: TMenuItem + Caption = 'Configure' + OnClick = MiConfigClick + end + object MiReset: TMenuItem + Caption = 'Reset' + OnClick = MiResetClick + end + object MiReloadPlugins: TMenuItem + Caption = 'Reload plugins' + OnClick = MiReloadPluginsClick + end + object MiLog: TMenuItem + Caption = 'Show debug' + OnClick = MiLogClick + end + object MiExit: TMenuItem + Caption = 'E&xit' + OnClick = MiExitClick + end + end + object ssfs: TServerSocket + Active = False + Port = 6002 + ServerType = stNonBlocking + OnClientConnect = ssfsClientConnect + OnClientDisconnect = ssfsClientDisconnect + OnClientRead = ssfsClientRead + OnClientError = ssfsClientError + Top = 56 + end + object csfs: TClientSocket + Active = False + ClientType = ctNonBlocking + Port = 6010 + OnConnect = csfsConnect + OnDisconnect = csfsDisconnect + OnError = csfsError + Left = 32 + Top = 56 + end + object csToPd: TClientSocket + Active = False + ClientType = ctNonBlocking + Host = 'localhost' + Port = 6002 + OnConnect = csToPdConnect + OnDisconnect = csToPdDisconnect + OnError = csToPdError + Left = 32 + end +end diff --git a/Source/mainunit.pas b/Source/mainunit.pas new file mode 100644 index 0000000..ebf3f46 --- /dev/null +++ b/Source/mainunit.pas @@ -0,0 +1,903 @@ +{ Copyright (C) 2001-2002 Juha Vehviläinen + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details.} + +unit mainunit; + +interface + +uses + Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, + StdCtrls, ScktComp, + pluginunit, fsformunit, fsframeunit, + FastDIB, + ExtCtrls, Menus, C2PhotoShopHost, Filez, ComCtrls; + +type + Tmain = class(TFsForm) + ss1: TServerSocket; + ImageLogo: TImage; + PopupMenu1: TPopupMenu; + MiConfig: TMenuItem; + MiReset: TMenuItem; + MiReloadPlugins: TMenuItem; + ssfs: TServerSocket; + csfs: TClientSocket; + MiLog: TMenuItem; + csToPd: TClientSocket; + MiExit: TMenuItem; + REConsole: TRichEdit; + procedure ss1ClientRead(Sender: TObject; Socket: TCustomWinSocket); + procedure FormCreate(Sender: TObject); + procedure ss1ClientError(Sender: TObject; Socket: TCustomWinSocket; + ErrorEvent: TErrorEvent; var ErrorCode: Integer); + procedure ss1ClientDisconnect(Sender: TObject; + Socket: TCustomWinSocket); + procedure MiConfigClick(Sender: TObject); + procedure ss1ClientConnect(Sender: TObject; Socket: TCustomWinSocket); + procedure MiResetClick(Sender: TObject); + procedure FormDestroy(Sender: TObject); + procedure MiReloadPluginsClick(Sender: TObject); + procedure ssfsClientRead(Sender: TObject; Socket: TCustomWinSocket); + procedure csfsError(Sender: TObject; Socket: TCustomWinSocket; + ErrorEvent: TErrorEvent; var ErrorCode: Integer); + procedure csfsDisconnect(Sender: TObject; Socket: TCustomWinSocket); + procedure ssfsClientError(Sender: TObject; Socket: TCustomWinSocket; + ErrorEvent: TErrorEvent; var ErrorCode: Integer); + procedure csfsConnect(Sender: TObject; Socket: TCustomWinSocket); + procedure ssfsClientConnect(Sender: TObject; Socket: TCustomWinSocket); + procedure ssfsClientDisconnect(Sender: TObject; + Socket: TCustomWinSocket); + procedure MiLogClick(Sender: TObject); + procedure csToPdError(Sender: TObject; Socket: TCustomWinSocket; + ErrorEvent: TErrorEvent; var ErrorCode: Integer); + procedure csToPdConnect(Sender: TObject; Socket: TCustomWinSocket); + procedure csToPdDisconnect(Sender: TObject; Socket: TCustomWinSocket); + procedure MiExitClick(Sender: TObject); + procedure ImageLogoDblClick(Sender: TObject); + procedure FormClose(Sender: TObject; var Action: TCloseAction); + private + { Private declarations } + SocketMem: Pointer; + fbmp: TFastDIB; + procedure LoadRegSettings; + procedure ParsePrim(const S: String); + procedure FreeIfCompExists(const S: String); + function GetFrameByTag(const tag: String): TFsFrame; + function ItemCount( const ClassName: String ): Integer; + procedure Reset; + procedure minimizeall; + procedure ExceptionHandler(Sender: TObject; E: Exception); + procedure DropFileHandler(const h: HWND; const DroppedFileName: String); + procedure AppMessage(var Msg: Tmsg; var Handled: Boolean); + public + { Public declarations } + RunConfig: Boolean; + PdHost: String; // Host running PD + PDReceivePort: Integer; // data from PD + PDSendPort: Integer; // data to PD + FSPort: Integer; // Framestein connections + EnableFSConns: Boolean; + DockMain: Boolean; + logstate: Boolean; + Plugins: TPlugins; + SearchPath: TStringList; + + function CompName(const S: String): String; + procedure Parse(const S: String); override; + procedure Post(const S: String); + procedure SendFrame(const f: TFsFrame; + const NameTag: String; const bmp: TFastDIB; + const quality: Integer; const sendjpg: Boolean ); + procedure SendReturnValues(const S: String); + procedure SendReturnValuesString( + const PdName: String; const S: String); + function FileExistsInSearchPath(var S: String): Boolean; // modifying S allowed! + end; + +const + STARTMSG = 'Framestein 0.30 running...'; + MCAPTION = 'Framestein 0.30'; + SocketBufferSize = 100000; + +var + main: Tmain; + DockTitle: String; + DockHandle: HWND; + +function WinEnumerator(h: HWND; i: LongInt): BOOL; stdcall; +function WinEnumerator_Exact(h: HWND; i: LongInt): BOOL; stdcall; +function WinEnumerator_SubStr(h: HWND; i: LongInt): BOOL; stdcall; + +implementation + +{$R *.DFM} + +uses + Registry, DirectX, DxDraws, ShellApi, + fscopyunit, fstextunit, fsdrawunit, fsbrowserunit, + fsinfounit, fsaviunit, + fastfiles, + Strz, logunit, configureunit; + +function WinEnumerator(h: HWND; i: LongInt): BOOL; stdcall; +var + Title: array[0..255] of Char; +begin + Result := True; + if GetWindowText(h, Title, SizeOf(Title))>0 then begin + if UpperCase(DockTitle)= + Copy(UpperCase(StrPas(@Title)), 1, Length(DockTitle)) then begin + DockHandle := h; + Result := False; // stop enumerating + end; + end; +end; + +function WinEnumerator_SubStr(h: HWND; i: LongInt): BOOL; stdcall; +var + Title: array[0..255] of Char; +begin + Result := True; + if GetWindowText(h, Title, SizeOf(Title))>0 then begin + if Pos(UpperCase(DockTitle), UpperCase(StrPas(@Title)))>0 then begin + DockHandle := h; + Result := False; // stop enumerating + end; + end; +end; + +function WinEnumerator_Exact(h: HWND; i: LongInt): BOOL; stdcall; +var + Title: array[0..255] of Char; +begin + Result := True; + if GetWindowText(h, Title, SizeOf(Title))>0 then begin + if UpperCase(DockTitle)= + UpperCase(StrPas(@Title)) then begin + DockHandle := h; + Result := False; // stop enumerating + end; + end; +end; + +{ TForm1 } + +function Tmain.ItemCount( const ClassName: String ): Integer; +var + i, count: Integer; +begin + count:=0; + if ComponentCount>0 then + for i:=1 to ComponentCount-1 do + if UpperCase(Components[i].ClassName)=UpperCase(ClassName) then + Inc(count); + Result := count; +end; + +function Tmain.CompName(const S: String): String; +var + St: String; + a: Integer; +begin + St := S; + if Length(St)>0 then + for a:=Length(St) downto 1 do + if St[a] in ['-','.',',',#10,#13] then + Delete(St, a, 1); + + if Length(St)>0 then + for a:=1 to Length(St) do + if St[a] in ['0'..'9'] then + St[a] := Char(Ord('A')+(Ord(St[a])-Ord('0'))); + + Result := St; +end; + +procedure Tmain.ParsePrim(const S: String); +var + s1, s2, s_args: String; + i: Integer; + fsframe: TFsFrame; + fscopy: TFsCopy; + fstext: TFsText; + fsdraw: TFsDraw; + fsbrowser: TFsBrowser; + fsinfo: TFsInfo; + fsavi: TFsAvi; + f: TFsForm; +begin + if logstate then + log.add(s); + + s1 := UpperCase(ExtractWord(1, S, [' '])); + s_args := Copy(S, Length(s1)+2, 255); + + f := TFsForm(FindComponent(CompName(s1))); + if f<>nil then begin + f.Parse(s_args); + Exit; + end; + + s2 := ExtractWord(2, S, [' ']); + + if S1='RESET' then begin + Reset; + end else + if S1='FRAME' then begin + FreeIfCompExists(CompName(s2)); + fsframe := TFsFrame.Create(Self); + fsframe.PdName := s2; + fsframe.Name := CompName(s2); + fsframe.Caption := s2; + i := ItemCount('TFsFrame')-1; + fsframe.Left := fsframe.Width*(i div 4); + fsframe.Top := fsframe.Height*(i mod 4); + fsframe.Show; + end else + if S1='COPY' then begin + FreeIfCompExists(CompName(s2)); + fscopy := TFsCopy.Create(Self); + fscopy.Name := CompName(s2); + fscopy.Caption := s2; + end else + if S1='TEXT' then begin + FreeIfCompExists(CompName(s2)); + fstext := TFsText.Create(Self); + fstext.Name := CompName(s2); + fstext.Caption := s2; + end else + if S1='DRAW' then begin + FreeIfCompExists(CompName(s2)); + fsdraw := TFsDraw.Create(Self); + fsdraw.Name := CompName(s2); + fsdraw.Caption := s2; + end else + if S1='BROWSER' then begin + FreeIfCompExists(CompName(s2)); + fsbrowser := TFsBrowser.Create(Self); + fsbrowser.PdName := s2; + fsbrowser.Name := CompName(s2); + fsbrowser.Caption := s2; + i := ItemCount('TFsBrowser')-1; + fsbrowser.Left := fsbrowser.Width*(i div 4); + fsbrowser.Top := fsbrowser.Height*(i mod 4); + fsbrowser.Show; + end else + if S1='INFO' then begin + FreeIfCompExists(CompName(s2)); + fsinfo := TFsInfo.Create(Self); + fsinfo.Name := CompName(s2); + fsinfo.Caption := s2; + end else + if S1='AVI' then begin + FreeIfCompExists(CompName(s2)); + fsavi := TFsAvi.Create(Self); + fsavi.PdName := s2; + fsavi.Name := CompName(s2); + fsavi.Caption := s2; + end else + if S1='MINIMIZEALL' then begin + minimizeall; + end else + if s1='PATH' then begin + SearchPath.Add(Copy(S, Length(s1)+2, 255)); + end else +end; + +procedure Tmain.Parse(const S: String); + + function ComponentCreator(const Str: String): Boolean; + var + s1: String; + begin + s1 := UpperCase(ExtractWord(1, Str, [' '])); + Result := + (s1='RESET') or + (s1='FRAME') or + (s1='COPY') or + (s1='TEXT') or + (s1='DRAW') or + (s1='BROWSER') or + (s1='INFO') or + (s1='AVI'); + end; + +var + i, c: Integer; + Str: String; +begin + if Pos(';', S)=0 then + ParsePrim(S) + else begin + c := WordCount(S, [';']); + // first commands that create fs.* objects + for i:=1 to c do begin + Str := ExtractWord(i, S, [';']); + if ComponentCreator(Str) then + ParsePrim(Str); + end; + // all the rest + for i:=1 to c do begin + Str := ExtractWord(i, S, [';']); + if not ComponentCreator(Str) then + ParsePrim(Str); + end; + end; +end; + +procedure Tmain.ss1ClientRead(Sender: TObject; Socket: TCustomWinSocket); +var + S: String; +begin + S := socket.ReceiveText; + while Pos(#10, S)>0 do + Delete(S, Pos(#10, S), 1); + Parse(S); +end; + +procedure Tmain.FreeIfCompExists(const S: String); +var + c: TComponent; +begin + c := FindComponent(S); + if c<>nil then + c.Free; +end; + +procedure Tmain.FormCreate(Sender: TObject); +begin + Randomize; + RunConfig:=False; + PdHost := 'localhost'; + PDReceivePort := 6001; + PDSendPort := 6002; + FSPort := 6010; + EnableFSConns := False; + DockMain := True; + LoadRegSettings; + if not RunConfig then begin + ss1.Port := PDReceivePort; + ss1.Active := True; + csToPd.Host := PdHost; + csToPd.Port := PdSendPort; + csToPd.Active := True; + ssfs.Port := FSPort; + ssfs.Active := EnableFSConns; + end; + + main.Post(STARTMSG); + Caption := MCAPTION; + + Plugins := TPlugins.Create(Self); + Plugins.Load; + + SocketMem := AllocMem(SocketBufferSize); + fBmp := TFastDIB.Create; + logstate := False; + + SearchPath := TStringList.Create; + SearchPath.Add(ExtractFilePath(Application.ExeName)); + + Application.OnException := ExceptionHandler; + Application.OnMessage := AppMessage; +end; + +procedure Tmain.FormDestroy(Sender: TObject); +begin + Plugins.Free; + SearchPath.Free; + FreeMem(SocketMem); + fBmp.Free; +end; + +procedure Tmain.ss1ClientConnect(Sender: TObject; + Socket: TCustomWinSocket); +begin + Post('Connected on port '+IntToStr(PDReceivePort)); + if not csToPd.Active then + csToPd.Active := True; + +// just a crazy idea + if DockMain then begin + DockTitle := 'pd'; + DockHandle:=0; + EnumWindows(@WinEnumerator_Exact, 0); + if DockHandle>0 then begin + ParentWindow := DockHandle; + BorderStyle := bsNone; + Left := 4; + Top := 120; + Width := 40; + Height := 40; + BringToFront; + end; + end; +end; + +procedure Tmain.ss1ClientDisconnect(Sender: TObject; + Socket: TCustomWinSocket); +begin + Post('Disconnected'); + csToPd.Active := False; + Reset; +end; + +procedure Tmain.csToPdConnect(Sender: TObject; Socket: TCustomWinSocket); +begin + Post('Connected on port '+IntToStr(PDSendPort)); +end; + +procedure Tmain.csToPdDisconnect(Sender: TObject; + Socket: TCustomWinSocket); +begin + Post('Disconnected'); +end; + +procedure Tmain.ss1ClientError(Sender: TObject; Socket: TCustomWinSocket; + ErrorEvent: TErrorEvent; var ErrorCode: Integer); +begin + Post('Disconnected'); + ErrorCode := 0; +end; + +procedure Tmain.LoadRegSettings; +var + Reg: TRegistry; +begin + Reg := TRegistry.Create; + try + Reg.RootKey := HKEY_CURRENT_USER; + if Reg.OpenKey('\Software\Framestein', True) then begin + PdHost := Reg.ReadString('PdHost'); + PDReceivePort := Reg.ReadInteger('PDReceivePort'); + PDSendPort := Reg.ReadInteger('PDSendPort'); + FSPort := Reg.ReadInteger('FSPort'); + EnableFSConns := Reg.ReadBool('EnableFSConns'); + DockMain := Reg.ReadBool('DockMain'); + end; + except + RunConfig := True; + end; + Reg.CloseKey; + Reg.Free; +end; + +procedure Tmain.MiConfigClick(Sender: TObject); +begin + configure.Execute; +end; + +procedure Tmain.Post(const S: String); +begin +// Writeln(TimeToStr(Time), ' ', S); + REConsole.Lines.Add(TimeToStr(Time)+' '+S); +end; + +procedure Tmain.Reset; +var + i: Integer; +begin + if ComponentCount=0 then Exit; + for i:=ComponentCount-1 downto 0 do + if Components[i] is TfsForm then + Components[i].Free; +end; + +procedure Tmain.MiResetClick(Sender: TObject); +begin + Reset; +end; + +procedure Tmain.MiReloadPluginsClick(Sender: TObject); +begin + Plugins.Reload; +end; + +function Tmain.GetFrameByTag(const tag: String): TFsFrame; +var + i: Integer; + fsframe: TFsFrame; + + function makenew: TfsFrame; + begin + FreeIfCompExists(CompName(tag)); + fsframe := TFsFrame.Create(Self); + fsframe.Name := CompName(tag); + fsframe.Caption := tag; + fsframe.NameTag := tag; + fsframe.Show; + Result := fsframe; + end; + +begin + if ComponentCount=0 then begin + Result := makenew; + Exit; + end; + for i:=ComponentCount-1 downto 0 do + if Components[i] is TfsFrame then begin + fsframe := Components[i] as TfsFrame; + if fsframe.NameTag = tag then begin + Result := fsframe; + Exit; + end; + end; + Result := makenew; +end; + +const + fsframeHeader = '!FS'; + fsframeHeaderLen = 27; + +procedure Tmain.SendFrame(const F: TFsFrame; + const NameTag: String; const bmp: TFastDIB; + const quality: Integer; const sendjpg: Boolean ); + + function Header(const _size: Integer): String; + var + s, s2: String; + begin + s2 := Copy(IntToStr(f.d1.Surface.Width), 1, 4); + while Length(s2)<4 do s2:='0'+s2; + s := fsframeHeader+s2; + s2 := Copy(IntToStr(f.d1.Surface.Height), 1, 4); + while Length(s2)<4 do s2:='0'+s2; + s := s+s2; + s2 := Copy(IntToStr(_size), 1, 7); + while Length(s2)<7 do s2:='0'+s2; + s := s+s2; + s2 := Copy(NameTag, 1, 8); + while Length(s2)<8 do s2:=s2+' '; + s := s+s2; + if sendjpg then s:=s+'1' else s:=s+'0'; + Result := s; + end; + +var + sd: TDDSurfaceDesc; + jSize, dSize: Integer; + JP: Pointer; +begin + if not csfs.Active then begin + Post('send: not connected'); + Exit; + end; + if sendjpg then begin + JP := AllocMem(bmp.Size); + jSize := SaveJPGMem(bmp, JP, bmp.Size, quality); + while csfs.Socket.SendText(Header(jSize))=-1 do + Application.HandleMessage; + while csfs.Socket.SendBuf(JP^, jSize)=-1 do + Application.HandleMessage; + FreeMem(JP); + end else begin + f.d1.Surface.Lock(sd); + dSize := sd.lPitch*f.d1.Surface.Height+f.d1.Surface.Width; + while csfs.Socket.SendText(Header(dSize))=-1 do + Application.HandleMessage; + while csfs.Socket.SendBuf(sd.lpSurface^, dSize)=-1 do + Application.HandleMessage; + f.d1.Surface.UnLock; + end; +end; + +// TODO: this procedure is more confusing than it needs to be +procedure Tmain.ssfsClientRead(Sender: TObject; Socket: TCustomWinSocket); +const + Receiving: Boolean = False; + Recd: Integer = 0; + fWidth: Integer = 0; + fHeight: Integer = 0; + fSize: Integer = 0; + fJpg: Boolean = True; + nametag: String = ''; + Buf: Pointer = nil; + BufPos: Integer = 0; +var + read: Integer; + tp: Pointer; + s: String; + f: TFsFrame; + sd: TDDSurfaceDesc; + temp: array[0..255] of Char; + + // header was received, extract data about incoming frame + procedure GetHeader; + var + i: Integer; + begin + S := StrPas(StrLCopy(tp, PChar(SocketMem), fsframeHeaderLen)); + fWidth := MyStrToInt(Copy(S, 4, 4)); + fHeight := MyStrToInt(Copy(S, 8, 4)); + fSize := MyStrToInt(Copy(S, 12, 7)); + nametag := Trim(Copy(S, 19, 8)); + fJpg := Boolean(S[27]='1'); +{ Post('Width: '+IntToStr(fWidth)+' Height: '+ + IntToStr(fHeight)+' Size: '+IntToStr(fSize)+ + ' nametag: '+nametag+' jpg: '+IntToStr(Integer(fJpg))); +} + Receiving := True; + Recd := 0; + Buf := AllocMem(fSize); + BufPos := 0; + if read>fsframeHeaderLen then begin + i := read-fsframeHeaderLen; + if fSizefWidth) or (f.d1.Surface.Height<>fHeight) then + f.d1.SetSize(fWidth, fHeight); + + if fJpg then begin + LoadJPGMem(fBmp, Buf, fSize, False); + fBmp.Draw(f.d1.Surface.Canvas.Handle, 0, 0); + f.d1.Surface.Canvas.Release; + end else begin + f.d1.Surface.Lock(sd); + Move(Buf^, sd.lpSurface^, fSize); + f.d1.Surface.UnLock; + end; + f.FlipRequest; + FreeMem(Buf); + Receiving := False; + + if BufPos>fSize then begin + // read: bytes read from socket + // bufpos: amount of total data from this and previous reads + // fsize: bytes needed for this frame + // bufpos - fsize: bytes read belonging to next frame + // read - (bufpos - fsize): offset for the next frame + offset := read - (BufPos - fSize); + read := (BufPos - fSize); + Move(Pointer(Integer(SocketMem)+offset)^, SocketMem^, read); + Result := True; + end; + end; + +begin + tp := @temp; + read := Socket.ReceiveBuf(SocketMem^, 100000); + + while True do begin +// Post('read '+IntToStr(read)); + if Receiving then begin + Inc(Recd, read); + + if BufPos+read > fSize then + Move(SocketMem^, Pointer(Integer(Buf)+BufPos)^, fSize-BufPos) + else + Move(SocketMem^, Pointer(Integer(Buf)+BufPos)^, read); + + Inc(BufPos, read); + + if Recd>=fSize then + if DoFrame then + Continue; + Exit; + end; + if (StrLComp(PChar(SocketMem), fsframeHeader, Length(fsframeHeader))=0) then begin + GetHeader; + if Recd>=fSize then + if DoFrame then + Continue; + end; + Break; + end; +end; + +procedure Tmain.csfsError(Sender: TObject; Socket: TCustomWinSocket; + ErrorEvent: TErrorEvent; var ErrorCode: Integer); +begin + ErrorCode := 0; +end; + +procedure Tmain.ssfsClientError(Sender: TObject; Socket: TCustomWinSocket; + ErrorEvent: TErrorEvent; var ErrorCode: Integer); +begin + ErrorCode := 0; +end; + +procedure Tmain.csToPdError(Sender: TObject; Socket: TCustomWinSocket; + ErrorEvent: TErrorEvent; var ErrorCode: Integer); +begin + ErrorCode := 0; +end; + +procedure Tmain.csfsConnect(Sender: TObject; Socket: TCustomWinSocket); +begin + Post('connected '+csfs.Host+' '+IntToStr(csfs.Port)); +end; + +procedure Tmain.csfsDisconnect(Sender: TObject; Socket: TCustomWinSocket); +begin + Post('disconnected '+csfs.Host+' '+IntToStr(csfs.Port)); +end; + +procedure Tmain.ssfsClientConnect(Sender: TObject; + Socket: TCustomWinSocket); +begin + Post('Connection from '+Socket.RemoteAddress); +end; + +procedure Tmain.ssfsClientDisconnect(Sender: TObject; + Socket: TCustomWinSocket); +begin + Post('Disconnected '+Socket.RemoteAddress); +end; + +procedure Tmain.MiLogClick(Sender: TObject); +begin + MiLog.Checked := not MiLog.Checked; + log.Visible := MiLog.Checked; + logstate := log.Visible; +end; + +procedure Tmain.SendReturnValues(const S: String); +var + i, c: Integer; + s2: String; +begin + if not csToPd.Active then Exit; + c := WordCount(S, [';']); + for i:=1 to c do begin + s2 := ExtractWord(i, S, [';']); + if Pos('=', s2)>0 then begin + csToPd.Socket.SendText( + ExtractWord(1, s2, ['='])+' '+ + ExtractWord(2, s2, ['='])+';' + ); + end; + end; +end; + +procedure Tmain.SendReturnValuesString( + const PdName: String; const S: String); +var + St: String; + i: Integer; +begin + St := S; + for i:=1 to Length(St) do begin + if St[i]='\' then St[i]:='/'; + SendReturnValues(PdName+'='+Long2Str(Ord(St[i]))); + end; + SendReturnValues(PdName+'=0'); +end; + +procedure Tmain.ExceptionHandler(Sender: TObject; E: Exception); +var + i: Integer; + f: TFsFrame; +begin + if Pos('1400', E.Message)>0 then begin // invalid window handle + // check any fs.frames with invalid window handles + // (due to closing a patch with docked fs.frames) + if ComponentCount=0 then Exit; + for i:=ComponentCount-1 downto 0 do + if Components[i] is TFsFrame then begin + f := Components[i] as TFsFrame; + if (f.ParentWindow>0) and + not IsWindow(f.ParentWindow) then begin +// Q: close or undock fs.frame? +// A: this will not happed immediately when a patch is closed, +// so closing the frame is more intuitive than popping it up +// after a while. + f.Free; +{ f.ParentWindow := 0; + f.Borders(True);} + end; + end else + end else + ShowMessage(E.Message); +end; + +procedure Tmain.DropFileHandler(const h: HWND; const DroppedFileName: String); +var + i: Integer; + f: TFsFrame; +begin + if ComponentCount=0 then Exit; + for i:=ComponentCount-1 downto 0 do + if Components[i] is TFsFrame then begin + f := Components[i] as TFsFrame; + if f.Handle=h then begin + f.HandleDroppedFile(DroppedFileName); + Break; + end; + end; +end; + +procedure Tmain.AppMessage(var Msg: Tmsg; var Handled: Boolean); +const + BufferLength : word = 255; +var + DroppedFilename : string; + FileIndex : Longword; + QtyDroppedFiles : word; + pDroppedFilename : array [0..255] of Char; +// DroppedFileLength : word; +begin + if Msg.Message = WM_DROPFILES then begin + FileIndex := $FFFFFFFF; + QtyDroppedFiles := DragQueryFile(Msg.WParam, FileIndex, + pDroppedFilename, BufferLength); + for FileIndex := 0 to (QtyDroppedFiles - 1) do begin +// DroppedFileLength := + DragQueryFile(Msg.WParam, FileIndex, + pDroppedFilename, BufferLength); + DroppedFilename := StrPas(pDroppedFilename); + DropFileHandler(msg.HWND, DroppedFilename); + end; + DragFinish(Msg.WParam); + Handled := True; + end; +end; + +procedure Tmain.minimizeall; +var + i: Integer; +begin + if ComponentCount=0 then Exit; + for i:=ComponentCount-1 downto 0 do + if Components[i] is TfsForm then + TForm(Components[i]).WindowState := wsMinimized; +end; + +procedure Tmain.MiExitClick(Sender: TObject); +begin + Application.Terminate; +end; + +function Tmain.FileExistsInSearchPath(var S: String): Boolean; +var + i: Integer; + filestr: String; +begin + Result := FileExists(S); + if not Result and (SearchPath.Count>0) then begin + filestr := ExtractFileName(S); + for i:=0 to SearchPath.Count-1 do begin + if FileExists(SearchPath.Strings[i]+'\'+filestr) then begin + S := SearchPath.Strings[i]+'\'+filestr; + Result := True; + Exit; + end; + end; + end; +end; + +procedure Tmain.ImageLogoDblClick(Sender: TObject); +begin + Reset; +end; + +procedure Tmain.FormClose(Sender: TObject; var Action: TCloseAction); +begin + if main.ParentWindow<>0 then begin + main.ParentWindow:=0; + end; +end; + +end. + diff --git a/Source/pluginunit.pas b/Source/pluginunit.pas new file mode 100644 index 0000000..d4fd51e --- /dev/null +++ b/Source/pluginunit.pas @@ -0,0 +1,227 @@ +{ Copyright (C) 2001 Juha Vehviläinen + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details.} + +unit pluginunit; + +interface + +uses + Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, + DirectX, DXDraws; + +type + TEffectProc = procedure(const Bits: Pointer; + const lPitch, Width, Height, BitCount: Integer; + const args: PChar; + const ret: PChar); cdecl; + + TCopyProc = procedure( + const Bits1: Pointer; + const lPitch1, Width1, Height1, BitCount1: Integer; + const Bits2: Pointer; + const lPitch2, Width2, Height2, BitCount2: Integer; + const args: PChar; + const ret: PChar + ); cdecl; + + TPointerList = TList; + TLibraryList = TList; + + TPlugins = class(TComponent) + private + Names: TStringList; + EffectProcs: TPointerList; + CopyProcs: TPointerList; + Libs: TLibraryList; + procedure LoadHandleFile(const SearchRec: TSearchRec; + const FullPath: String); + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + procedure Load; + procedure Reload; + procedure Clear; + function IsPlugin(const s: String): Boolean; + function CallEffect(const d: TDirectDrawSurface; + const procname: String; const args: String): Boolean; + function CallCopy(const d1: TDirectDrawSurface; + const d2: TDirectDrawSurface; + const procname: String; const args: String): Boolean; + end; + +implementation + +uses + mainunit, + Filez; + +type + THandlePtr = ^THandle; + +const + EffectProcName = 'perform_effect'; + CopyProcName = 'perform_copy'; + +{ TPlugins } + +constructor TPlugins.Create(AOwner: TComponent); +begin + inherited; + Names := TStringList.Create; + EffectProcs := TPointerList.Create; + CopyProcs := TPointerList.Create; + Libs := TLibraryList.Create; +end; + +destructor TPlugins.Destroy; +begin + Clear; + Names.Free; + EffectProcs.Free; + CopyProcs.Free; + Libs.Free; + inherited; +end; + +procedure TPlugins.Clear; +var + hp: THandlePtr; +begin + while Names.Count>0 do Names.Delete(0); + while EffectProcs.Count>0 do EffectProcs.Delete(0); + while CopyProcs.Count>0 do CopyProcs.Delete(0); + while Libs.Count>0 do begin + hp := Libs[0]; + FreeLibrary(hp^); + Libs.Delete(0); + end; +end; + +procedure TPlugins.LoadHandleFile(const SearchRec: TSearchRec; + const FullPath: String); +var + h: THandle; + p: PChar; + b: array[0..255] of Char; + EffectProc: TEffectProc; + CopyProc: TCopyProc; + s: String; + i: Integer; +begin + p:=@b; + if UpperCase(ExtractFileExt(FullPath))='.DLL' then begin + h := LoadLibrary(StrPCopy(p, FullPath)); + if h<>0 then begin + @EffectProc := GetProcAddress(h, EffectProcName); + @CopyProc := GetProcAddress(h, CopyProcName); + s := ExtractFileName(FullPath); + i := Pos('.DLL', UpperCase(s)); + if i>0 then Delete(s, i, 255); + Names.Add(s); + EffectProcs.Add(@EffectProc); + CopyProcs.Add(@CopyProc); + Libs.Add(@h); + end; + end; +end; + +procedure TPlugins.Load; +var + sd: TScanDir; + s: String; + i: Integer; +begin + sd := TScanDir.Create(Self); + sd.OnHandleFile := LoadHandleFile; + sd.Scan(ExtractFilePath(Application.ExeName)+'\Plugins'); + sd.Free; + if Names.Count>0 then begin + s := ''; + for i:=0 to Names.Count-1 do begin + if s<>'' then s:=s+' '; + s:=s+Names[i]; + end; + main.Post('Plugins: '+s); + end; +end; + +procedure TPlugins.Reload; +begin + Clear; + Load; +end; + +function TPlugins.IsPlugin(const s: String): Boolean; +begin + Result := Names.IndexOf(s)<>-1; +end; + +var + argsBuf: array[0..255] of Char; + +function TPlugins.CallEffect(const d: TDirectDrawSurface; + const procname: String; const args: String): Boolean; +var + i: Integer; + Proc: TEffectProc; + sd: TDDSurfaceDesc; + P: PChar; +begin + Result := False; + if (Names.Count=0) or (d.Width=0) or (d.Height=0) then Exit; + i := Names.IndexOf(procname); + if (i=-1) or (i>=EffectProcs.Count) then Exit; + @Proc := EffectProcs[i]; + if @Proc=nil then Exit; + P:=@argsBuf; + P[0]:=#0; + d.Lock(sd); + Proc(sd.lpSurface, sd.lPitch, d.Width, d.Height, d.BitCount, + PChar(args), P); + d.UnLock; + if P[0]<>#0 then + main.SendReturnValues(StrPas(P)); + Result := True; +end; + +function TPlugins.CallCopy(const d1, d2: TDirectDrawSurface; + const procname: String; const args: String): Boolean; +var + i: Integer; + Proc: TCopyProc; + sd1: TDDSurfaceDesc; + sd2: TDDSurfaceDesc; + P: PChar; +begin + Result := False; + if (Names.Count=0) or + (d1.Width=0) or (d1.Height=0) or + (d2.Width=0) or (d2.Height=0) then Exit; + i := Names.IndexOf(procname); + if (i=-1) or (i>=CopyProcs.Count) then Exit; + @Proc := CopyProcs[i]; + if @Proc=nil then Exit; + P:=@argsBuf; + P[0]:=#0; + d1.Lock(sd1); + d2.Lock(sd2); + Proc(sd1.lpSurface, sd1.lPitch, d1.Width, d1.Height, d1.BitCount, + sd2.lpSurface, sd2.lPitch, d2.Width, d2.Height, d2.BitCount, + PChar(args), P); + d1.UnLock; + d2.UnLock; + if P[0]<>#0 then + main.SendReturnValues(StrPas(P)); + Result := True; +end; + +end. + diff --git a/Source/pshostunit.pas b/Source/pshostunit.pas new file mode 100644 index 0000000..42868c3 --- /dev/null +++ b/Source/pshostunit.pas @@ -0,0 +1,145 @@ +unit pshostunit; + +interface + +uses + Forms, SysUtils, DirectX, DxDraws, + fsframeunit, C2PhotoShopHost; + +function IsFilter(const S: String): Boolean; + +function Filter_effect(const psh: TC2PhotoShopHost; + const d: TDirectDrawSurface; + const procname: String; const args: String): Boolean; + +function Filter_copy(const psh: TC2PhotoShopHost; + const d1, d2: TDirectDrawSurface; + const procname: String; const args: String): Boolean; + +implementation + +uses + Windows, Graphics, DIB, + mainunit; + +var + FilterPath: String; + +function FullFilterPath(const S: String): String; +begin + Result := FilterPath+'\'+S; + if Uppercase(ExtractFileExt(S))<>'.8BF' then + Result := Result+'.8BF'; +end; + +function IsFilter(const S: String): Boolean; +begin + Result := FileExists(FullFilterPath(S)); +end; + +function Filter_effect(const psh: TC2PhotoShopHost; + const d: TDirectDrawSurface; + const procname: String; const args: String): Boolean; +const + Active: Boolean = False; +var + sd: TDDSurfaceDesc; + dib: TDxDib; +begin + Result := False; + if Active then Exit; // disable recursion + Active := True; + if not psh.LoadFilterDLL(FullFilterPath(procname)) then begin + main.Post('Filter load error: '+procname+'. Requires Adobe''s Plugin.dll?'); + Active := False; + Exit; + end; + + d.Lock(sd); + psh.Surface := @sd; + + if d.BitCount=24 then begin + psh.SrcPtr := sd.lpSurface; + psh.DstPtr := sd.lpSurface; + end else begin + // DIB will ensure we're @ 24 bits per pixel... + dib := TDxDib.Create(main); + dib.DIB.Assign(d); + + psh.DIB := dib; + psh.SrcPtr := dib.DIB.PBits; + psh.DstPtr := dib.DIB.PBits; + end; + + psh.CallDialog := (args=''); + psh.args := args; + psh.RunFilter; + + d.UnLock; + + if d.BitCount<>24 then begin + d.Assign(dib.DIB); + dib.Free; + end; + Result := True; + Active := False; +end; + +function Filter_copy(const psh: TC2PhotoShopHost; + const d1, d2: TDirectDrawSurface; + const procname: String; const args: String): Boolean; +const + Active: Boolean = False; +var + sd1, sd2: TDDSurfaceDesc; + dib1, dib2: TDxDib; +begin + Result := False; + if Active then Exit; // disable recursion + Active := True; + if not psh.LoadFilterDLL(FullFilterPath(procname)) then begin + main.Post('Filter load error: '+procname+'. Requires Adobe''s Plugin.dll?'); + Active := False; + Exit; + end; + + d1.Lock(sd1); + d2.Lock(sd2); + + psh.Surface := @sd1; + + if d1.BitCount=24 then begin + psh.SrcPtr := sd1.lpSurface; + psh.DstPtr := sd2.lpSurface; + end else begin + // DIB will ensure we're @ 24 bits per pixel... + dib1 := TDxDib.Create(main); + dib2 := TDxDib.Create(main); + dib1.DIB.Assign(d1); + dib2.DIB.SetSize(dib1.DIB.Width, dib1.DIB.Height, 24); + + psh.DIB := dib1; + psh.SrcPtr := dib1.DIB.PBits; + psh.DstPtr := dib2.DIB.PBits; + end; + + psh.CallDialog := (args=''); + psh.args := args; + psh.RunFilter; + + d1.UnLock; + d2.UnLock; + + if d1.BitCount<>24 then begin + d2.Assign(dib2.DIB); + dib1.Free; + dib2.Free; + end; + Result := True; + Active := False; +end; + +begin + FilterPath := ExtractFilePath(Application.ExeName)+'\Filters' +end. + diff --git a/extract.wav b/extract.wav new file mode 100644 index 0000000..11c1b7b Binary files /dev/null and b/extract.wav differ diff --git a/head.avi b/head.avi new file mode 100644 index 0000000..dcae3c1 Binary files /dev/null and b/head.avi differ diff --git a/ijl15.dll b/ijl15.dll new file mode 100644 index 0000000..0ea9873 Binary files /dev/null and b/ijl15.dll differ -- cgit v1.2.1