[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] /srv/bzr/gnash/trunk r10592: merge from 'rtmp' branch.
From: |
rob |
Subject: |
[Gnash-commit] /srv/bzr/gnash/trunk r10592: merge from 'rtmp' branch. |
Date: |
Mon, 16 Feb 2009 20:18:15 -0700 |
User-agent: |
Bazaar (1.5) |
------------------------------------------------------------
revno: 10592
committer: address@hidden
branch nick: trunk
timestamp: Mon 2009-02-16 20:18:15 -0700
message:
merge from 'rtmp' branch.
renamed:
libnet/rtmp_server.cpp => cygnal/rtmp_server.cpp
libnet/rtmp_server.h => cygnal/rtmp_server.h
modified:
cygnal/Makefile.am
cygnal/README
cygnal/cygnal.cpp
libamf/amf.cpp
libamf/amf.h
libamf/buffer.cpp
libamf/buffer.h
libamf/element.cpp
libamf/element.h
libamf/flv.cpp
libnet/Makefile.am
libnet/cache.h
libnet/diskstream.cpp
libnet/handler.cpp
libnet/http.cpp
libnet/http.h
libnet/network.cpp
libnet/rtmp.cpp
libnet/rtmp.h
libnet/rtmp_client.cpp
libnet/rtmp_msg.cpp
libnet/rtmp_msg.h
packaging/redhat/gnash.spec
packaging/xpi/install.rdf
packaging/xpi/update.rdf
testsuite/libamf.all/test_amf.cpp
testsuite/libnet.all/Makefile.am
testsuite/libnet.all/test_http.cpp
testsuite/libnet.all/test_rtmp.cpp
utilities/Makefile.am
utilities/flvdumper.cpp
cygnal/rtmp_server.cpp
cygnal/rtmp_server.h
------------------------------------------------------------
revno: 9483.4.247
committer: address@hidden
branch nick: rtmp
timestamp: Fri 2008-12-26 12:02:59 -0700
message:
merge from trunk after syncing from branch.
renamed:
libcore/asobj/Boolean.cpp => libcore/asobj/Boolean_as.cpp
libcore/asobj/Boolean.h => libcore/asobj/Boolean_as.h
libcore/asobj/LocalConnection.cpp => libcore/asobj/LocalConnection_as.cpp
libcore/asobj/LocalConnection.h => libcore/asobj/LocalConnection_as.h
libcore/asobj/Sound.cpp => libcore/asobj/Sound_as.cpp
libcore/asobj/Sound.h => libcore/asobj/Sound_as.h
modified:
libcore/as_value.cpp
libcore/asobj/ClassHierarchy.cpp
libcore/asobj/Global.cpp
libcore/asobj/Makefile.am
testsuite/libnet.all/test_cache.cpp
testsuite/libnet.all/test_diskstream.cpp
testsuite/libnet.all/test_http.cpp
libcore/asobj/Boolean_as.cpp
libcore/asobj/Boolean_as.h
libcore/asobj/LocalConnection_as.cpp
libcore/asobj/LocalConnection_as.h
libcore/asobj/Sound_as.cpp
libcore/asobj/Sound_as.h
------------------------------------------------------------
revno: 9483.4.248
committer: address@hidden
branch nick: rtmp
timestamp: Sat 2008-12-27 09:51:48 -0700
message:
call hexify() ourselves to be more convienient when debugging Buffer
contents.
modified:
libamf/buffer.cpp
libamf/buffer.h
------------------------------------------------------------
revno: 9483.4.249
committer: address@hidden
branch nick: rtmp
timestamp: Sat 2008-12-27 18:41:44 -0700
message:
bring the RTMP support back to life.
add --only-port= option to force RTMPT or RTMP when in single threaded
mode.
This is only used for testing of course.
modified:
cygnal/cygnal.cpp
------------------------------------------------------------
revno: 9483.4.250
committer: address@hidden
branch nick: rtmp
timestamp: Sat 2008-12-27 18:44:57 -0700
message:
fix usage of boost::shared_ptr.
refactor heavily to deal with the new network engine.
completely change how sendMsg() and recvMsg() work.
modified:
libnet/rtmp.cpp
libnet/rtmp.h
------------------------------------------------------------
revno: 9483.4.251
committer: address@hidden
branch nick: rtmp
timestamp: Sat 2008-12-27 18:47:36 -0700
message:
RTMP_BODY_SIZE has been renamed to RTMP_HANDSHAKE_SIZE.
modified:
libnet/rtmp_msg.cpp
------------------------------------------------------------
revno: 9483.4.252
committer: address@hidden
branch nick: rtmp
timestamp: Sat 2008-12-27 18:47:56 -0700
message:
RTMP_BODY_SIZE has been renamed to RTMP_HANDSHAKE_SIZE.
modified:
libnet/rtmp_client.cpp
------------------------------------------------------------
revno: 9483.4.253
committer: address@hidden
branch nick: rtmp
timestamp: Sat 2008-12-27 18:48:41 -0700
message:
refactor heavily to work with the new network engine and threading scheme.
modified:
libnet/rtmp_server.cpp
libnet/rtmp_server.h
------------------------------------------------------------
revno: 9483.4.254
committer: address@hidden
branch nick: rtmp
timestamp: Sat 2008-12-27 19:43:55 -0700
message:
decode the msg body from the right offset
modified:
libnet/rtmp_server.cpp
------------------------------------------------------------
revno: 9483.4.255
committer: address@hidden
branch nick: rtmp
timestamp: Sat 2008-12-27 19:44:43 -0700
message:
parse the Elements correctly for the first message.
modified:
libnet/rtmp.cpp
------------------------------------------------------------
revno: 9483.4.256
committer: address@hidden
branch nick: rtmp
timestamp: Sun 2008-12-28 12:06:41 -0700
message:
fix the split() method to be less complex.
modified:
libnet/rtmp.cpp
libnet/rtmp.h
------------------------------------------------------------
revno: 9483.4.257
committer: address@hidden
branch nick: rtmp
timestamp: Sun 2008-12-28 12:07:29 -0700
message:
Only do the handshake the first time the handkler is called. Process the
connect() message now.
modified:
libnet/rtmp_server.cpp
------------------------------------------------------------
revno: 9483.4.258
committer: address@hidden
branch nick: rtmp
timestamp: Sun 2008-12-28 12:47:57 -0700
message:
improve exception error messages.
modified:
libamf/buffer.cpp
------------------------------------------------------------
revno: 9483.4.259
committer: address@hidden
branch nick: rtmp
timestamp: Sun 2008-12-28 14:42:55 -0700
message:
adjust the seek pointer when manually adding data. Send Ping and then
Response messages to the connect() mesage.
modified:
libnet/rtmp_server.cpp
------------------------------------------------------------
revno: 9483.4.260
committer: address@hidden
branch nick: rtmp
timestamp: Sun 2008-12-28 15:34:58 -0700
message:
make a buffer bigger.
modified:
libamf/element.cpp
------------------------------------------------------------
revno: 9483.4.261
committer: address@hidden
branch nick: rtmp
timestamp: Sun 2008-12-28 15:36:56 -0700
message:
implement sendMsg to a working point.
modified:
libnet/rtmp.cpp
------------------------------------------------------------
revno: 9483.4.262
committer: address@hidden
branch nick: rtmp
timestamp: Sun 2008-12-28 15:37:53 -0700
message:
don't name the object 'application', add the code property before
descritption.
modified:
libnet/rtmp_server.cpp
------------------------------------------------------------
revno: 9483.4.263
committer: address@hidden
branch nick: rtmp
timestamp: Sun 2008-12-28 16:53:10 -0700
message:
find the properties of objects in the message.
modified:
libnet/rtmp_msg.cpp
libnet/rtmp_msg.h
------------------------------------------------------------
revno: 9483.4.264
committer: address@hidden
branch nick: rtmp
timestamp: Sun 2008-12-28 16:53:56 -0700
message:
extract data from the connect() object so we know what file it wants.
only do the connect() when initializing.
modified:
libnet/rtmp_server.cpp
------------------------------------------------------------
revno: 9483.4.265
committer: address@hidden
branch nick: rtmp
timestamp: Sun 2008-12-28 18:14:01 -0700
message:
add methods to parse and format responses to the Red5 tests.
modified:
libnet/rtmp_server.cpp
libnet/rtmp_server.h
------------------------------------------------------------
revno: 9483.4.266
committer: Benjamin Wolsey <address@hidden>
branch nick: rtmp
timestamp: Mon 2008-12-29 17:05:34 +0100
message:
Merge warning and build fixes from trunk.
modified:
libnet/http.cpp
------------------------------------------------------------
revno: 9483.4.267
committer: address@hidden
branch nick: rtmp
timestamp: Mon 2008-12-29 11:08:47 -0700
message:
add the encoded NULL object before the echo'd data.
modified:
cygnal/cygnal.cpp
libnet/rtmp_server.cpp
------------------------------------------------------------
revno: 9483.4.268
committer: address@hidden
branch nick: rtmp
timestamp: Tue 2008-12-30 14:06:14 -0700
message:
use the port_offset option for RTMP too.
modified:
cygnal/cygnal.cpp
------------------------------------------------------------
revno: 9483.4.269
committer: address@hidden
branch nick: rtmp
timestamp: Tue 2008-12-30 14:06:48 -0700
message:
minor change to error handling return codes.
modified:
libnet/network.cpp
------------------------------------------------------------
revno: 9483.4.270
committer: address@hidden
branch nick: rtmp
timestamp: Tue 2008-12-30 14:07:49 -0700
message:
minor change to error handling return codes.
modified:
libnet/rtmp.cpp
------------------------------------------------------------
revno: 9483.4.271
committer: address@hidden
branch nick: rtmp
timestamp: Tue 2008-12-30 14:08:34 -0700
message:
move rtmp_handler to the end of the file. Build the handshake response as
one big packet to keep the other players happy.
modified:
libnet/rtmp_server.cpp
------------------------------------------------------------
revno: 9483.4.272
committer: address@hidden
branch nick: rtmp
timestamp: Tue 2008-12-30 14:56:25 -0700
message:
for the echo tests, stay in the handler as we're also in single threaded
mode.
modified:
libnet/rtmp_server.cpp
------------------------------------------------------------
revno: 9483.4.273
committer: address@hidden
branch nick: rtmp
timestamp: Tue 2008-12-30 15:39:46 -0700
message:
move rtmp_server from libnet to cygnal, as it's becoming less generic,
and more cygnal specific.
check the threading flag from the config file. If in single threaded mode,
all RTMP packets are processed in the one function, as there is no
distpatch
thread. When multi-threaded, return to the top level after processing a
packet
as the distpatch handler will call the rtmp_handler for the next packet
of data.
cygnal almost survives the red5 echo test all the way through!
renamed:
libnet/rtmp_server.cpp => cygnal/rtmp_server.cpp
libnet/rtmp_server.h => cygnal/rtmp_server.h
modified:
cygnal/Makefile.am
libnet/Makefile.am
libnet/handler.cpp
libnet/rtmp.cpp
cygnal/rtmp_server.cpp
cygnal/rtmp_server.h
------------------------------------------------------------
revno: 9483.4.274
committer: address@hidden
branch nick: rtmp
timestamp: Tue 2008-12-30 16:09:31 -0700
message:
encode the right element to get more test sucesses.
modified:
cygnal/rtmp_server.cpp
------------------------------------------------------------
revno: 9483.4.275
committer: address@hidden
branch nick: rtmp
timestamp: Tue 2008-12-30 16:19:50 -0700
message:
encode as a Null String if the length is zero.
modified:
libamf/amf.cpp
------------------------------------------------------------
revno: 9483.4.276
committer: address@hidden
branch nick: rtmp
timestamp: Tue 2008-12-30 21:00:25 -0700
message:
add support for decoding and encoding Reference types too.
modified:
libamf/amf.cpp
libamf/amf.h
------------------------------------------------------------
revno: 9483.4.277
committer: address@hidden
branch nick: rtmp
timestamp: Tue 2008-12-30 21:00:44 -0700
message:
add tests for Reference types.
modified:
testsuite/libamf.all/test_amf.cpp
------------------------------------------------------------
revno: 9483.4.278
committer: address@hidden
branch nick: rtmp
timestamp: Tue 2008-12-30 21:01:32 -0700
message:
add to_short() and to_integer() accessors for the Element data.
modified:
libamf/element.cpp
libamf/element.h
------------------------------------------------------------
revno: 9483.4.279
committer: address@hidden
branch nick: rtmp
timestamp: Wed 2008-12-31 15:45:37 -0700
message:
correctly jump past the terminator bytes for Object.
modified:
libamf/amf.cpp
------------------------------------------------------------
revno: 9483.4.280
committer: address@hidden
branch nick: rtmp
timestamp: Thu 2009-01-01 12:00:02 -0700
message:
add tests cases to make sure we can handle corrupted packets when
decoding AMF.
modified:
testsuite/libnet.all/test_http.cpp
------------------------------------------------------------
revno: 9483.4.281
committer: address@hidden
branch nick: rtmp
timestamp: Thu 2009-01-01 12:00:41 -0700
message:
add corrupt() methods to randomly corrupt data in a Buffer for stress
testing.
modified:
libamf/buffer.cpp
libamf/buffer.h
------------------------------------------------------------
revno: 9483.4.282
committer: address@hidden
branch nick: rtmp
timestamp: Thu 2009-01-01 12:06:21 -0700
message:
remove useless commented out stuff.
modified:
testsuite/libamf.all/test_amf.cpp
------------------------------------------------------------
revno: 9483.4.283
committer: address@hidden
branch nick: rtmp
timestamp: Thu 2009-01-01 18:11:48 -0700
message:
uncomment test_rtmp.
modified:
testsuite/libnet.all/Makefile.am
------------------------------------------------------------
revno: 9483.4.284
committer: address@hidden
branch nick: rtmp
timestamp: Thu 2009-01-01 18:12:26 -0700
message:
fixed enough to compile and not core dump, but has failures.
modified:
testsuite/libnet.all/test_rtmp.cpp
------------------------------------------------------------
revno: 9483.4.285
committer: address@hidden
branch nick: rtmp
timestamp: Thu 2009-01-01 18:13:56 -0700
message:
split all buffers at chunksize boundaries into distinct messages.
modified:
cygnal/rtmp_server.cpp
------------------------------------------------------------
revno: 9483.4.286
committer: address@hidden
branch nick: rtmp
timestamp: Sun 2009-01-04 22:23:50 -0700
message:
make Sane string length the max size.
modified:
libamf/amf.h
------------------------------------------------------------
revno: 9483.4.287
committer: address@hidden
branch nick: rtmp
timestamp: Sun 2009-01-04 22:24:52 -0700
message:
treat Typed Object like regular Objects with a different type.
modified:
libamf/amf.cpp
------------------------------------------------------------
revno: 9483.4.288
committer: address@hidden
branch nick: rtmp
timestamp: Sun 2009-01-04 22:25:42 -0700
message:
add additional test case for split.
modified:
testsuite/libnet.all/test_rtmp.cpp
------------------------------------------------------------
revno: 9483.4.289
committer: address@hidden
branch nick: rtmp
timestamp: Sun 2009-01-04 22:26:50 -0700
message:
use a shared_ptr for the active channels instead of a private data
variabel.
modified:
libnet/rtmp.cpp
libnet/rtmp.h
------------------------------------------------------------
revno: 9483.4.290
committer: address@hidden
branch nick: rtmp
timestamp: Sun 2009-01-04 22:32:18 -0700
message:
track AMF references.
modified:
cygnal/rtmp_server.cpp
cygnal/rtmp_server.h
------------------------------------------------------------
revno: 9483.4.291
committer: address@hidden
branch nick: rtmp
timestamp: Sun 2009-01-18 17:57:22 +1100
message:
set the seek pointer when copying data into the buffer.
modified:
libamf/buffer.cpp
------------------------------------------------------------
revno: 9483.4.292
committer: address@hidden
branch nick: rtmp
timestamp: Sun 2009-01-18 17:58:20 +1100
message:
add private data for the parameter to an URL.
modified:
libnet/http.h
------------------------------------------------------------
revno: 9483.4.293
committer: address@hidden
branch nick: rtmp
timestamp: Sun 2009-01-18 17:59:53 +1100
message:
look for the ? that seperates the parameters from the filespec.
modified:
libnet/http.cpp
------------------------------------------------------------
revno: 9483.4.294
committer: address@hidden
branch nick: rtmp
timestamp: Sun 2009-01-18 18:00:33 +1100
message:
don't wait for more data if we read it all.
modified:
libnet/rtmp.cpp
------------------------------------------------------------
revno: 9483.4.295
committer: address@hidden
branch nick: rtmp
timestamp: Sun 2009-01-18 18:01:34 +1100
message:
add back test cases for parsing the GET request line.
modified:
testsuite/libnet.all/test_http.cpp
------------------------------------------------------------
revno: 9483.4.296
committer: address@hidden
branch nick: rtmp
timestamp: Sat 2009-01-31 17:21:59 +1100
message:
parse the parameters in a GET request if they exist.
modified:
libnet/http.cpp
------------------------------------------------------------
revno: 9483.4.297
committer: address@hidden
branch nick: rtmp
timestamp: Sat 2009-01-31 17:23:06 +1100
message:
make less vesbose when corrupting the file for testing.
modified:
libamf/buffer.cpp
------------------------------------------------------------
revno: 9483.4.298
committer: address@hidden
branch nick: rtmp
timestamp: Sat 2009-01-31 17:24:01 +1100
message:
return an error if the file doesn't exist.
modified:
libnet/diskstream.cpp
------------------------------------------------------------
revno: 9483.4.299
committer: address@hidden
branch nick: rtmp
timestamp: Sat 2009-01-31 17:25:22 +1100
message:
allocate new memory for thread argumwnts as gcc seems to optimize them to
be the same address otherwise.
modified:
cygnal/cygnal.cpp
------------------------------------------------------------
revno: 9483.4.300
committer: address@hidden
branch nick: rtmp
timestamp: Sun 2009-02-01 19:07:06 -0700
message:
merge from trunk
removed:
backend/render_handler_agg_compat.h
gui/klash.moc.in
testsuite/misc-ming.all/SharedObjectTest.sol/sol1.sol
added:
gui/GuiKde4.cpp
gui/Kde4Glue.h
gui/Kde4GlueAgg.cpp
gui/Kde4GlueAgg.h
gui/Kde4Gui.cpp
gui/Kde4Gui.h
gui/am-frag/kde4.am
gui/klash3.moc.in
gui/klash4.moc.in
libbase/GnashFileUtilities.cpp
libbase/GnashFileUtilities.h
macros/kde4.m4
macros/qt4.m4
macros/swfmill.m4
plugin/klash4/
plugin/klash4/Makefile.am
plugin/klash4/README
plugin/klash4/klash.desktop
plugin/klash4/klash_part.cpp
plugin/klash4/klash_part.desktop
plugin/klash4/klash_part.h
plugin/klash4/klash_part.moc.in
plugin/klash4/klashpartui.rc
plugin/klash4/klashplayer.lsm
plugin/klash4/pluginsinfo
testsuite/actionscript.all/HitTest.as
testsuite/misc-ming.all/SharedObjectTest.sol/sol1.sol
renamed:
gui/am-frag/kde.am => gui/am-frag/kde3.am
gui/am-frag/qtopia.am => gui/am-frag/qtopia3.am
libcore/array.cpp => libcore/asobj/Array_as.cpp
libcore/array.h => libcore/asobj/Array_as.h
libcore/asobj/Date.cpp => libcore/asobj/Date_as.cpp
libcore/asobj/Date.h => libcore/asobj/Date_as.h
macros/kde.m4 => macros/kde3.m4
macros/qt.m4 => macros/qt3.m4
modified:
Makefile.am
backend/Makefile.am
backend/render_handler.h
backend/render_handler_agg.cpp
backend/render_handler_agg_style.h
backend/render_handler_cairo.cpp
backend/render_handler_ogl.cpp
backend/render_handler_ogl.h
configure.ac
cygnal/Makefile.am
extensions/fileio/fileio.cpp
extensions/mysql/mysql_db.cpp
gui/Makefile.am
gui/Player.cpp
gui/gnash.cpp
gui/gnash.in
gui/gtk.cpp
gui/gtksup.h
gui/gui.cpp
gui/gui.h
gui/gui_kde.cpp
gui/kde.cpp
libbase/GnashSystemIOHeaders.h
libbase/IOChannel.h
libbase/Makefile.am
libbase/NetworkAdapter.h
libbase/curl_adapter.cpp
libbase/rc.cpp
libbase/rc.h
libbase/utility.h
libcore/Button.cpp
libcore/Makefile.am
libcore/MovieClip.cpp
libcore/MovieClip.h
libcore/PropertyList.h
libcore/RGBA.cpp
libcore/RGBA.h
libcore/SWFMatrix.cpp
libcore/SWFMatrix.h
libcore/SWFStream.cpp
libcore/SWFStream.h
libcore/StreamProvider.cpp
libcore/StreamProvider.h
libcore/TextField.cpp
libcore/TextField.h
libcore/Video.cpp
libcore/Video.h
libcore/as_environment.cpp
libcore/as_environment.h
libcore/as_function.cpp
libcore/as_object.cpp
libcore/as_object.h
libcore/as_value.cpp
libcore/as_value.h
libcore/asobj/AsBroadcaster.cpp
libcore/asobj/AsBroadcaster.h
libcore/asobj/ClassHierarchy.cpp
libcore/asobj/Error_as.cpp
libcore/asobj/Global.cpp
libcore/asobj/Key_as.cpp
libcore/asobj/Key_as.h
libcore/asobj/LoadVars_as.cpp
libcore/asobj/LoadVars_as.h
libcore/asobj/LoadableObject.cpp
libcore/asobj/LocalConnection_as.cpp
libcore/asobj/Makefile.am
libcore/asobj/Math_as.cpp
libcore/asobj/Mouse_as.cpp
libcore/asobj/MovieClipLoader.cpp
libcore/asobj/NetConnection_as.cpp
libcore/asobj/NetStream_as.cpp
libcore/asobj/Number_as.cpp
libcore/asobj/Object.cpp
libcore/asobj/Selection_as.cpp
libcore/asobj/SharedObject_as.cpp
libcore/asobj/SharedObject_as.h
libcore/asobj/String_as.cpp
libcore/asobj/TextFormat_as.cpp
libcore/asobj/XMLNode_as.cpp
libcore/asobj/XMLNode_as.h
libcore/asobj/XML_as.cpp
libcore/asobj/XML_as.h
libcore/character.cpp
libcore/character.h
libcore/cxform.cpp
libcore/debugger.cpp
libcore/event_id.h
libcore/fill_style.cpp
libcore/fill_style.h
libcore/generic_character.cpp
libcore/gnash.h
libcore/impl.cpp
libcore/impl.h
libcore/movie_root.cpp
libcore/movie_root.h
libcore/parser/SWFMovieDefinition.cpp
libcore/parser/action_buffer.cpp
libcore/parser/action_buffer.h
libcore/parser/morph2_character_def.cpp
libcore/parser/morph2_character_def.h
libcore/parser/shape_character_def.cpp
libcore/parser/shape_character_def.h
libcore/parser/sprite_definition.cpp
libcore/render.cpp
libcore/render.h
libcore/styles.cpp
libcore/styles.h
libcore/swf.h
libcore/swf/CSMTextSettingsTag.cpp
libcore/swf/CSMTextSettingsTag.h
libcore/swf/DefineButtonCxformTag.cpp
libcore/swf/DefineButtonCxformTag.h
libcore/swf/DefineButtonSoundTag.cpp
libcore/swf/DefineButtonSoundTag.h
libcore/swf/DefineButtonTag.cpp
libcore/swf/DefineButtonTag.h
libcore/swf/DefineEditTextTag.cpp
libcore/swf/DefineEditTextTag.h
libcore/swf/DefineFontAlignZonesTag.cpp
libcore/swf/DefineFontAlignZonesTag.h
libcore/swf/DefineFontNameTag.h
libcore/swf/DefineFontTag.cpp
libcore/swf/DefineFontTag.h
libcore/swf/DefineTextTag.cpp
libcore/swf/DefineTextTag.h
libcore/swf/DefineVideoStreamTag.cpp
libcore/swf/DefineVideoStreamTag.h
libcore/swf/DisplayListTag.h
libcore/swf/DoActionTag.h
libcore/swf/DoInitActionTag.h
libcore/swf/PlaceObject2Tag.cpp
libcore/swf/PlaceObject2Tag.h
libcore/swf/RemoveObjectTag.cpp
libcore/swf/RemoveObjectTag.h
libcore/swf/ScriptLimitsTag.h
libcore/swf/SetBackgroundColorTag.h
libcore/swf/StartSoundTag.cpp
libcore/swf/StartSoundTag.h
libcore/swf/StreamSoundBlockTag.cpp
libcore/swf/StreamSoundBlockTag.h
libcore/swf/TagLoadersTable.cpp
libcore/swf/TagLoadersTable.h
libcore/swf/TextRecord.cpp
libcore/swf/TextRecord.h
libcore/swf/VideoFrameTag.cpp
libcore/swf/VideoFrameTag.h
libcore/swf/tag_loaders.cpp
libcore/swf/tag_loaders.h
libcore/swf_function.cpp
libcore/swf_function.h
libcore/vm/ASHandlers.cpp
libcore/vm/ASHandlers.h
libcore/vm/ActionExec.cpp
libcore/vm/ActionExec.h
libcore/vm/CallStack.cpp
libcore/vm/Machine.cpp
libcore/vm/VM.cpp
libcore/vm/VM.h
libcore/vm/action.cpp
libmedia/AudioDecoderNellymoser.cpp
libmedia/FLVParser.cpp
libmedia/FLVParser.h
libmedia/Makefile.am
libmedia/MediaHandler.cpp
libmedia/MediaHandler.h
libmedia/MediaParser.cpp
libmedia/MediaParser.h
libmedia/ffmpeg/MediaHandlerFfmpeg.cpp
libmedia/ffmpeg/MediaParserFfmpeg.cpp
libmedia/ffmpeg/VideoDecoderFfmpeg.cpp
libmedia/gst/MediaHandlerGst.cpp
libnet/cque.h
macros/ffmpeg.m4
macros/libslist
plugin/Makefile.am
plugin/klash/Makefile.am
plugin/mozilla-sdk/np_entry.cpp
plugin/mozilla-sdk/npn_gate.cpp
plugin/mozilla-sdk/npp_gate.cpp
plugin/mozilla-sdk/npplat.h
plugin/mozilla-sdk/pluginbase.h
plugin/plugin.cpp
po/fi.po
testsuite/actionscript.all/ASnative.as
testsuite/actionscript.all/Date.as
testsuite/actionscript.all/Error.as
testsuite/actionscript.all/Global.as
testsuite/actionscript.all/LoadVars.as
testsuite/actionscript.all/Makefile.am
testsuite/actionscript.all/Math.as
testsuite/actionscript.all/MovieClip.as
testsuite/actionscript.all/Number.as
testsuite/actionscript.all/TextField.as
testsuite/actionscript.all/XML.as
testsuite/actionscript.all/ops.as
testsuite/gnashrc.in
testsuite/libcore.all/Makefile.am
testsuite/misc-ming.all/DrawingApiTestRunner.cpp
testsuite/misc-ming.all/NetStream-SquareTest.c
testsuite/misc-ming.all/SharedObjectTest.as
testsuite/misc-ming.all/SharedObjectTestRunner.sh
testsuite/misc-swfc.all/check.sc
testsuite/swfdec/PASSING
testsuite/swfdec/swfdec_gnash_tester
utilities/Makefile.am
gui/am-frag/kde3.am
gui/am-frag/qtopia3.am
libcore/asobj/Array_as.cpp
libcore/asobj/Array_as.h
libcore/asobj/Date_as.cpp
libcore/asobj/Date_as.h
macros/kde3.m4
macros/qt3.m4
------------------------------------------------------------
revno: 9483.4.301
committer: address@hidden
branch nick: rtmp
timestamp: Tue 2009-02-03 10:43:02 -0700
message:
one too many for a short.
modified:
libamf/amf.h
------------------------------------------------------------
revno: 9483.4.302
committer: address@hidden
branch nick: rtmp
timestamp: Wed 2009-02-04 14:12:35 -0700
message:
better handling of multiple RTMP messages that aren't the echo test.
modified:
cygnal/rtmp_server.cpp
------------------------------------------------------------
revno: 9483.4.303
committer: address@hidden
branch nick: rtmp
timestamp: Wed 2009-02-04 14:17:43 -0700
message:
process an ECMA array's like an Object with terminator bytes.
modified:
libamf/amf.cpp
libamf/amf.h
------------------------------------------------------------
revno: 9483.4.304
committer: address@hidden
branch nick: rtmp
timestamp: Wed 2009-02-04 14:18:29 -0700
message:
don't try to process properties if there aren't any.
modified:
libamf/flv.cpp
------------------------------------------------------------
revno: 9483.4.305
committer: address@hidden
branch nick: rtmp
timestamp: Wed 2009-02-04 14:18:47 -0700
message:
drop newline in debug message.
modified:
libamf/element.cpp
------------------------------------------------------------
revno: 9483.4.306
committer: address@hidden
branch nick: rtmp
timestamp: Wed 2009-02-04 14:20:09 -0700
message:
don't use a reference to a class in a std::map, older versions of g++
don't like it.
modified:
libnet/rtmp.cpp
libnet/rtmp.h
libnet/rtmp_msg.cpp
libnet/rtmp_msg.h
------------------------------------------------------------
revno: 9483.4.307
committer: address@hidden
branch nick: rtmp
timestamp: Wed 2009-02-04 14:21:48 -0700
message:
multi threaded is now the default, change to -s to force single threaded.
modified:
cygnal/cygnal.cpp
------------------------------------------------------------
revno: 9483.4.308
committer: address@hidden
branch nick: rtmp
timestamp: Wed 2009-02-04 14:22:01 -0700
message:
don't use a reference to a class in a std::map, older versions of g++
don't like it.
modified:
cygnal/rtmp_server.h
------------------------------------------------------------
revno: 9483.4.309
committer: address@hidden
branch nick: rtmp
timestamp: Wed 2009-02-04 17:42:18 -0700
message:
when only using one port, force single threaded mode.
modified:
cygnal/cygnal.cpp
------------------------------------------------------------
revno: 9483.4.310
committer: address@hidden
branch nick: rtmp
timestamp: Wed 2009-02-04 17:42:44 -0700
message:
less verbosity.
modified:
libnet/rtmp.cpp
------------------------------------------------------------
revno: 9483.4.311
committer: address@hidden
branch nick: rtmp
timestamp: Wed 2009-02-04 17:43:21 -0700
message:
improved main message processing loop.
modified:
cygnal/rtmp_server.cpp
------------------------------------------------------------
revno: 9483.4.312
committer: address@hidden
branch nick: rtmp
timestamp: Mon 2009-02-09 17:21:27 +0100
message:
use the target arguments, and check for the correctly offset RTMP port.
modified:
cygnal/cygnal.cpp
------------------------------------------------------------
revno: 9483.4.313
committer: address@hidden
branch nick: rtmp
timestamp: Mon 2009-02-09 17:23:39 +0100
message:
process all messages in a loop, leave old way ifdef'd out for now.
modified:
cygnal/rtmp_server.cpp
------------------------------------------------------------
revno: 9483.4.314
committer: address@hidden
branch nick: rtmp
timestamp: Tue 2009-02-10 17:27:07 +0100
message:
add a flag to not encode as an object, but merely as a list of the
properties
as used by some response packets.
if makeString() is done to an existing object, replace the old value with
the
new one after adjusting the buffer size if need be.
modified:
libamf/element.cpp
libamf/element.h
------------------------------------------------------------
revno: 9483.4.315
committer: address@hidden
branch nick: rtmp
timestamp: Tue 2009-02-10 17:29:12 +0100
message:
add enum value for createStream reponse.
modified:
libnet/rtmp_msg.h
------------------------------------------------------------
revno: 9483.4.316
committer: address@hidden
branch nick: rtmp
timestamp: Tue 2009-02-10 17:30:41 +0100
message:
add support to encode a onStatus packet.
modified:
cygnal/rtmp_server.cpp
cygnal/rtmp_server.h
------------------------------------------------------------
revno: 9483.4.317
committer: address@hidden
branch nick: rtmp
timestamp: Tue 2009-02-10 20:23:05 +0100
message:
add accesot to return only one element from the vector of properties.
modified:
libnet/rtmp_msg.h
------------------------------------------------------------
revno: 9483.4.318
committer: address@hidden
branch nick: rtmp
timestamp: Tue 2009-02-10 20:24:33 +0100
message:
create the responses for NetStream::Play() and NetStream::Reset().
modified:
cygnal/rtmp_server.cpp
cygnal/rtmp_server.h
------------------------------------------------------------
revno: 9483.4.319
committer: address@hidden
branch nick: rtmp
timestamp: Wed 2009-02-11 10:27:20 +0100
message:
add room for the NULL string terminator when resizing a string element.
modified:
libamf/element.cpp
------------------------------------------------------------
revno: 9483.4.320
committer: address@hidden
branch nick: rtmp
timestamp: Thu 2009-02-12 19:04:19 +0100
message:
the object has 4 properties, not 3.
modified:
testsuite/libamf.all/test_amf.cpp
------------------------------------------------------------
revno: 9483.4.321
committer: address@hidden
branch nick: rtmp
timestamp: Fri 2009-02-13 16:45:08 -0700
message:
get the relationship beteen streamid and clientids correct.
create new stream ids correctly.
clean up creating a new stream.
modified:
cygnal/rtmp_server.cpp
cygnal/rtmp_server.h
------------------------------------------------------------
revno: 9483.4.322
committer: address@hidden
branch nick: rtmp
timestamp: Sat 2009-02-14 15:42:54 -0700
message:
move where th cache size is defined. add overload for sendMsg() to take a
raw pointer and byte count.
modified:
cygnal/README
cygnal/rtmp_server.cpp
cygnal/rtmp_server.h
libnet/cache.h
libnet/http.cpp
libnet/rtmp.cpp
libnet/rtmp.h
testsuite/libnet.all/Makefile.am
testsuite/libnet.all/test_http.cpp
testsuite/libnet.all/test_rtmp.cpp
utilities/flvdumper.cpp
------------------------------------------------------------
revno: 9483.4.323
committer: address@hidden
branch nick: rtmp
timestamp: Mon 2009-02-16 15:13:07 -0700
message:
parse Typed objects correctly.
modified:
libamf/amf.cpp
------------------------------------------------------------
revno: 9483.4.324
committer: address@hidden
branch nick: rtmp
timestamp: Mon 2009-02-16 16:11:30 -0700
message:
Only enable the memory corruption tests sometimes as they keep test cases
from running valgrind clean.
modified:
testsuite/libnet.all/test_http.cpp
------------------------------------------------------------
revno: 9483.4.325
committer: address@hidden
branch nick: rtmp
timestamp: Mon 2009-02-16 16:12:42 -0700
message:
trap some strings when the length has been corrupted.
modified:
libnet/http.cpp
------------------------------------------------------------
revno: 9483.4.326
committer: address@hidden
branch nick: rtmp
timestamp: Mon 2009-02-16 16:36:18 -0700
message:
fix encoded of Typed AMF Objects by adding the name.
modified:
libamf/amf.cpp
------------------------------------------------------------
revno: 9483.4.327
committer: address@hidden
branch nick: rtmp
timestamp: Mon 2009-02-16 17:36:57 -0700
message:
reverse the properties in the echo response for a Typed Object array.
modified:
libnet/http.cpp
------------------------------------------------------------
revno: 9483.4.328
committer: address@hidden
branch nick: rtmp
timestamp: Mon 2009-02-16 17:59:30 -0700
message:
reduce verbosity.
modified:
libamf/amf.cpp
------------------------------------------------------------
revno: 9483.4.329
committer: address@hidden
branch nick: rtmp
timestamp: Mon 2009-02-16 18:00:08 -0700
message:
add method to clear all the properties held by an Element.
modified:
libamf/element.h
------------------------------------------------------------
revno: 9483.4.330
committer: address@hidden
branch nick: rtmp
timestamp: Mon 2009-02-16 18:01:10 -0700
message:
verify all test cases after fixing bugs in core library.
modified:
testsuite/libnet.all/test_http.cpp
------------------------------------------------------------
revno: 9483.4.331
committer: address@hidden
branch nick: rtmp
timestamp: Mon 2009-02-16 18:02:00 -0700
message:
reverse the properties of a typed object when responding to a red5 echo
test.
modified:
libnet/http.cpp
------------------------------------------------------------
revno: 9483.4.332
committer: address@hidden
branch nick: rtmp
timestamp: Mon 2009-02-16 18:09:27 -0700
message:
ifdef out the XFAIL test case, as cxfail() isn't in a released version of
DejaGnu yet.
modified:
testsuite/libnet.all/test_http.cpp
=== modified file 'cygnal/Makefile.am'
--- a/cygnal/Makefile.am 2009-02-14 18:10:55 +0000
+++ b/cygnal/Makefile.am 2009-02-17 03:18:15 +0000
@@ -68,11 +68,12 @@
noinst_HEADERS = \
cygnal.h \
+ rtmp_server.h \
crc.h
bin_PROGRAMS = cygnal
-cygnal_SOURCES = cygnal.cpp crc.cpp cvm.cpp
+cygnal_SOURCES = cygnal.cpp crc.cpp cvm.cpp rtmp_server.cpp
cygnal_LDADD = $(AM_LDFLAGS)
# Rebuild with GCC 4.x Mudflap support
=== modified file 'cygnal/README'
--- a/cygnal/README 2008-12-18 03:40:16 +0000
+++ b/cygnal/README 2009-02-14 22:42:54 +0000
@@ -139,5 +139,36 @@
rtmp_handler - ditto.
+../../../rtmp-logs/red5-rtmpstream-test.log
+connect #3
+ping #2
+_result #3
+createStream #3 -> streamid #2
+_result #3 -> streamid #2, #1
+_play #8
+ping #2
+onStatus #4 <- reset
+onStatus #4 <- play
+deleteStream #3
+
+.Reset 12 bytes
+.Play 8 bytes
+
+
+../../../rtmp-logs/ngrep-flowplayer-seek.log
+connect #3
+ping #2
+_result #3
+createStream #3 -> streamid #3
+_result #3 -> streamid #d
+_play #8
+ping #2
+onStatus #4 <- reset -> streamid #1
+onStatus #5 <- play -> streamid #1
+onStatus #5 <- data start
+onMetaData #5 <- flv file
+
+.Reset 12 bytes
+.Play 8 bytes
=== modified file 'cygnal/cygnal.cpp'
--- a/cygnal/cygnal.cpp 2008-12-18 00:47:43 +0000
+++ b/cygnal/cygnal.cpp 2009-02-09 16:21:27 +0000
@@ -32,6 +32,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
+
#include "gettext.h"
//#include "cvm.h"
@@ -64,6 +65,7 @@
#include "diskstream.h"
#include "arg_parser.h"
#include "GnashException.h"
+#include "GnashSleep.h" // for usleep comptibility.
// classes internal to Cygnal
#include "buffer.h"
@@ -128,6 +130,10 @@
// Admin commands are small
const int ADMINPKTSIZE = 80;
+// If set to a non zero value, this limits Cygnal to only one protocol
+// at a time. This is for debugging only.
+static int only_port = 0;
+
// These keep track of the number of active threads.
ThreadCounter tids;
@@ -158,12 +164,13 @@
<< _(" -h, --help Print this help and exit") << endl
<< _(" -V, --version Print version information and exit") <<
endl
<< _(" -v, --verbose Output verbose debug info") << endl
+ << _(" -m, --multithread Enable Multi Threading") << endl
+ << _(" -n, --netdebug Turn on net debugging messages") << endl
+ << _(" -o --only-port Only use port for debugging") << endl
<< _(" -p --port-offset Port offset for debugging") << endl
- << _(" -n, --netdebug Turn on net debugging messages") << endl
<< _(" -t, --testing Turn on special Gnash testing support")
<< endl
<< _(" -a, --admin Enable the administration thread") << endl
<< _(" -r, --root Document root for all files") << endl
- << _(" -c, --threads Enable Threading") << endl
<< endl;
}
@@ -188,7 +195,8 @@
{ 't', "testing", Arg_parser::no },
{ 'a', "admin", Arg_parser::no },
{ 'r', "root", Arg_parser::yes },
- { 'm', "multithreaded", Arg_parser::no }
+ { 'o', "only-port", Arg_parser::yes },
+ { 's', "singlethreaded", Arg_parser::no }
};
Arg_parser parser(argc, argv, opts);
@@ -247,12 +255,15 @@
case 'r':
docroot = parser.argument(i).c_str();
break;
- case 'm':
- crcfile.setThreadingFlag(true);
+ case 's':
+ crcfile.setThreadingFlag(false);
break;
case 'n':
netdebug = true;
break;
+ case 'o':
+ only_port = parser.argument<int>(i);
+ break;
case 'd':
crcfile.dump();
exit(0);
@@ -261,6 +272,11 @@
log_error (_("Extraneous argument: %s"),
parser.argument(i).c_str());
}
}
+
+ // If a port is specified, we only want to run single threaded.
+ if (only_port) {
+ crcfile.setThreadingFlag(false);
+ }
// Trap ^C (SIGINT) so we can kill all the threads
act1.sa_handler = cntrlc_handler;
@@ -271,16 +287,11 @@
boost::mutex::scoped_lock lk(alldone_mutex);
-// struct thread_params rtmp_data;
-// struct thread_params ssl_data;
-// rtmp_data.port = port_offset + 1935;
-// boost::thread rtmp_port(boost::bind(&rtmp_thread, &rtmp_data));
// Admin handler
if (admin) {
Network::thread_params_t admin_data;
admin_data.port = gnash::ADMIN_PORT;
boost::thread admin_thread(boost::bind(&admin_handler, &admin_data));
-// admin_thread.join();
}
// Cvm cvm;
@@ -292,29 +303,32 @@
// server. Since this port offset changes the constant to test
// for which protocol, we pass the info to the start thread so
// it knows which handler to invoke.
- Network::thread_params_t http_data;
- http_data.port = port_offset + gnash::RTMPT_PORT;
- http_data.netfd = 0;
- http_data.filespec = docroot;
- if (crcfile.getThreadingFlag()) {
- boost::thread http_thread(boost::bind(&connection_handler, &http_data));
- } else {
- connection_handler(&http_data);
- }
-
-#if 0
- // Incomming connection handler for port 1935, RTMP. As RTMP
- // is not a priviledged port, we just open it without an offset.
- Handler::thread_params_t rtmp_data;
- rtmp_data.port = port_offset + gnash::RTMP_PORT;
- rtmp_data.netfd = 0;
- rtmp_data.filespec = docroot;
- if (crcfile.getThreadingFlag()) {
- boost::thread rtmp_thread(boost::bind(&connection_handler,
&rtmp_data));
- } else {
- connection_handler(&rtmp_data);
- }
-#endif
+ Network::thread_params_t *http_data = new Network::thread_params_t;
+ if ((only_port == 0) || (only_port == gnash::RTMPT_PORT)) {
+ http_data->port = port_offset + gnash::RTMPT_PORT;
+ http_data->netfd = 0;
+ http_data->filespec = docroot;
+ if (crcfile.getThreadingFlag()) {
+ boost::thread http_thread(boost::bind(&connection_handler,
http_data));
+ } else {
+ connection_handler(http_data);
+ }
+ }
+
+
+ Network::thread_params_t *rtmp_data = new Network::thread_params_t;
+ // Incomming connection handler for port 1935, RTMP. As RTMP
+ // is not a priviledged port, we just open it without an offset.
+ if ((only_port == 0) || (only_port == gnash::RTMP_PORT)) {
+ rtmp_data->port = port_offset + gnash::RTMP_PORT;
+ rtmp_data->netfd = 0;
+ rtmp_data->filespec = docroot;
+ if (crcfile.getThreadingFlag()) {
+ boost::thread rtmp_thread(boost::bind(&connection_handler,
rtmp_data));
+ } else {
+ connection_handler(rtmp_data);
+ }
+ }
// wait for the thread to finish
// http_thread.join();
@@ -325,6 +339,9 @@
log_debug (_("Cygnal done..."));
+ delete rtmp_data;
+ delete http_data;
+
return(0);
}
@@ -496,7 +513,12 @@
}
// Start a server on this tcp/ip port.
fd = net.createServer(args->port);
- log_debug("Starting Connection Handler for fd #%d, port %hd", fd,
args->port);
+ if (fd <= 0) {
+ log_error("Can't start Connection Handler for fd #%d, port %hd", fd,
args->port);
+ return;
+ } else {
+ log_debug("Starting Connection Handler for fd #%d, port %hd", fd,
args->port);
+ }
// Get the number of cpus in this system. For multicore
// systems we'll get better load balancing if we keep all the
@@ -527,6 +549,7 @@
// Handler *hand = new Handler;
args->handler = &net;
+ boost::thread handler;
// FIXME: this may run forever, we probably want a cleaner way to
// test for the end of time.
@@ -579,11 +602,11 @@
tnet = networks[tid];
}
if (args->port == (port_offset + RTMPT_PORT)) {
- boost::bind(http_handler, args);
+ boost::bind(http_handler, targs);
tnet->addPollFD(fds, http_handler);
- } else if (args->port == RTMP_PORT) {
-// tnet->addPollFD(fds, rtmp_handler);
- log_unimpl("Not ready for RTMP data yet.");
+ } else if (args->port == (port_offset + RTMP_PORT)) {
+ boost::bind(rtmp_handler, targs);
+ tnet->addPollFD(fds, rtmp_handler);
}
if (networks[tid] == 0) {
networks[tid] = tnet;
@@ -597,9 +620,8 @@
log_debug("Single threaded mode for fd #%d", args->netfd);
if (args->port == (port_offset + RTMPT_PORT)) {
http_handler(args);
- } else if (args->port == RTMP_PORT) {
-// hand->addPollFD(fds, rtmp_handler);
- log_unimpl("Not ready for RTMP data yet.");
+ } else if (args->port == (port_offset + RTMP_PORT)) {
+ rtmp_handler(args);
}
}
@@ -653,14 +675,15 @@
log_debug("Got something on fd #%d, 0x%x", it->fd,
it->revents);
// Call the protocol handler for this network connection
bool ret = net->getEntry(it->fd)(args);
+
// log_debug("Handler returned %s", (ret) ? "true" :
"false");
// FIXME: we currently force a 'close connection' at
the end
// of sending a file, since apache does too. This
pretty much
// blows persistance,
// if (ret) {
- networks[args->tid] = 0;
- net->closeNet(it->fd);
- net->erasePollFD(it->fd);
+ networks[args->tid] = 0;
+ net->closeNet(it->fd);
+ net->erasePollFD(it->fd);
// }
}
}
@@ -670,8 +693,6 @@
if (hits) {
for (it = hits->begin(); it != hits->end(); it++) {
log_debug("Need to disconnect fd #%d, it got an
error.", (*it).fd);
-// hand->erasePollFD(it);
-// net.closeNet(it->fd);
}
}
}
@@ -682,8 +703,6 @@
}
}
} while (!done);
-
-// network[];
tids.decrement();
} // end of dispatch_handler
=== renamed file 'libnet/rtmp_server.cpp' => 'cygnal/rtmp_server.cpp'
--- a/libnet/rtmp_server.cpp 2008-12-20 17:11:55 +0000
+++ b/cygnal/rtmp_server.cpp 2009-02-14 22:42:54 +0000
@@ -27,6 +27,8 @@
#include <boost/cstdint.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/detail/endian.hpp>
+#include <boost/random/uniform_real.hpp>
+#include <boost/random/mersenne_twister.hpp>
#if ! (defined(_WIN32) || defined(WIN32))
# include <netinet/in.h>
@@ -41,24 +43,36 @@
#include "handler.h"
#include "utility.h"
#include "buffer.h"
+#include "GnashSleep.h"
+#include "crc.h"
+#include "cache.h"
+#include "diskstream.h"
using namespace gnash;
using namespace std;
using namespace amf;
-namespace gnash
+namespace cygnal
{
+// Get access to the global config data for Cygnal
+static CRcInitFile& crcfile = CRcInitFile::getDefaultInstance();
+
+// Get access to the global Cygnal cache
+static Cache& cache = Cache::getDefaultInstance();
+
extern map<int, Handler *> handlers;
RTMPServer::RTMPServer()
+ : _filesize(0),
+ _streamid(1)
{
// GNASH_REPORT_FUNCTION;
// _inbytes = 0;
// _outbytes = 0;
-// _body = new unsigned char(RTMP_BODY_SIZE+1);
-// memset(_body, 0, RTMP_BODY_SIZE+1);
+// _body = new unsigned char(RTMP_HANDSHAKE_SIZE+1);
+// memset(_body, 0, RTMP_HANDSHAKE_SIZE+1);
}
RTMPServer::~RTMPServer()
@@ -68,36 +82,35 @@
// delete _body;
}
+#if 0
// The handshake is a byte with the value of 0x3, followed by 1536
// bytes of gibberish which we need to store for later.
bool
-RTMPServer::handShakeWait()
+RTMPServer::processClientHandShake(int fd, amf::Buffer &buf)
{
GNASH_REPORT_FUNCTION;
-// char buffer[RTMP_BODY_SIZE+16];
-// memset(buffer, 0, RTMP_BODY_SIZE+16);
- boost::shared_ptr<amf::Buffer> buf = _handler->pop();
-
- if (buf == 0) {
- log_debug("Que empty, net connection dropped for fd #%d", getFileFd());
+ if (buf.reference() == 0) {
+ log_debug("no data in buffer, net connection dropped for fd #%d", fd);
return false;
- }
+ }
- if (*buf->reference() == RTMP_HANDSHAKE) {
+ cerr << buf.hexify(false) << endl;
+
+ if (*buf.reference() == RTMP_HANDSHAKE) {
log_debug (_("Handshake request is correct"));
} else {
log_error (_("Handshake request isn't correct"));
return false;
}
-// if (buf->size() >= RTMP_BODY_SIZE) {
+// if (buf->size() >= RTMP_HANDSHAKE_SIZE) {
// secret = _handler->merge(buf->reference());
// }
- if (buf->size() >= static_cast<size_t>(RTMP_BODY_SIZE)) {
- _handshake = new amf::Buffer(RTMP_BODY_SIZE);
- _handshake->copy(buf->reference() + 1, RTMP_BODY_SIZE);
+ if (buf.size() >= static_cast<size_t>(RTMP_HANDSHAKE_SIZE)) {
+ _handshake = new amf::Buffer(RTMP_HANDSHAKE_SIZE);
+ _handshake->copy(buf.reference() + 1, RTMP_HANDSHAKE_SIZE);
log_debug (_("Handshake Data matched"));
// return true;
} else {
@@ -107,93 +120,98 @@
return true;
}
+#endif
// The response is the gibberish sent back twice, preceeded by a byte
-// with the value of 0x3.
+// with the value of 0x3. We have to very carefully send the handshake
+// in one big packet as doing otherwise seems to cause subtle timing
+// problems with the Adobe player. Tis way it connects every time.
bool
-RTMPServer::handShakeResponse()
+RTMPServer::handShakeResponse(int fd, amf::Buffer &handshake)
{
GNASH_REPORT_FUNCTION;
- boost::shared_ptr<amf::Buffer> buf1(new amf::Buffer(RTMP_BODY_SIZE + 1));
- *buf1 = RTMP_HANDSHAKE;
- *buf1 += _handshake;
-// _handler->pushout(buf1); FIXME:
-
- boost::shared_ptr<amf::Buffer> buf2(new amf::Buffer(RTMP_BODY_SIZE));
- buf2->copy(_handshake->begin(), RTMP_BODY_SIZE);
-// _handler->pushout(buf2); FIXME:
+ boost::uint8_t byte;
+ byte = RTMP_HANDSHAKE;
+
+ boost::shared_ptr<amf::Buffer> zeros(new
amf::Buffer(RTMP_HANDSHAKE_SIZE*2+1));
+ zeros->clear();
+
+ boost::uint8_t *ptr = zeros->reference();
+ *ptr = RTMP_HANDSHAKE;
+ zeros->setSeekPointer(ptr + RTMP_HANDSHAKE_SIZE+1);
+
+ zeros->append(handshake.reference()+1, handshake.allocated() - 1);
+ size_t ret = writeNet(fd, *zeros);
-// std::copy(_handshake->begin(), _handshake->end(), (buf1->begin() + 1));
-// boost::shared_ptr<amf::Buffer> buf = new amf::Buffer(RTMP_BODY_SIZE +
1);
-// std::copy(_handshake->begin(), _handshake->end(), buf->begin() + 1 +
RTMP_BODY_SIZE);
-// _handler->notifyout();
-
- log_debug("Sent RTMP Handshake response");
+ if (ret == zeros->allocated()) {
+ log_debug("Sent RTMP Handshake response");
+ } else {
+ log_error("Couldn't sent RTMP Handshake response!");
+ }
return true;
}
-bool
-RTMPServer::serverFinish()
+boost::shared_ptr<amf::Buffer>
+RTMPServer::serverFinish(int fd, amf::Buffer &handshake1, amf::Buffer
&handshake2)
{
GNASH_REPORT_FUNCTION;
-
- boost::shared_ptr<amf::Buffer> buf = _handler->pop();
- boost::shared_ptr<amf::Buffer> obj = buf;
-
- if (buf == 0) {
- log_debug("Que empty, net connection dropped for fd #%d", getFileFd());
- return false;
- }
-
- // The first data packet is often buried in with the end of the handshake.
- // So after the handshake block, we strip that part off, and just pass on
- // the remainder for processing.
- if (buf->size() >= static_cast<size_t>(RTMP_BODY_SIZE)) {
- size_t size = buf->size() - RTMP_BODY_SIZE;
- obj.reset(new amf::Buffer[size]);
- obj->copy(buf->begin()+RTMP_BODY_SIZE, size);
- } else {
- _handler->wait();
- obj = _handler->pop();
- }
-
- int diff = std::memcmp(buf->begin(), _handshake->begin(), RTMP_BODY_SIZE);
- if (diff == 0) {
+ boost::shared_ptr<amf::Buffer> buf;
+
+ if ((handshake1.reference() == 0) || (handshake2.reference() == 0)) {
+ log_debug("Que empty, net connection dropped for fd #%d", fd);
+ return buf;
+ }
+
+ int diff = std::memcmp(handshake1.begin(), handshake2.begin(),
RTMP_HANDSHAKE_SIZE);
+ if (diff <= 1) {
log_debug (_("Handshake Finish Data matched"));
} else {
log_error (_("Handshake Finish Data didn't match by %d bytes"), diff);
-// return false;
+ }
+
+ // Copy the extra data from the end of the handshake to the new buffer.
Normally we
+ // try to avoid copying anything around, but as this is only used once for
each connection,
+ // there isn't a real performance hit from it.
+ if (handshake2.allocated() >= static_cast<size_t>(RTMP_HANDSHAKE_SIZE)) {
+ log_debug("Got extra data in handshake, %d bytes for fd #%d",
+ handshake2.allocated() - RTMP_HANDSHAKE_SIZE, fd);
+ buf.reset(new Buffer(handshake2.allocated() - RTMP_HANDSHAKE_SIZE));
+ buf->copy(handshake2.reference() + RTMP_HANDSHAKE_SIZE,
handshake2.allocated() - RTMP_HANDSHAKE_SIZE);
}
- packetRead(obj);
-
- return true;
+// packetRead(*buf);
+ return buf;
}
bool
-RTMPServer::packetSend(boost::shared_ptr<amf::Buffer> /* buf */)
+RTMPServer::packetSend(amf::Buffer &/* buf */)
{
GNASH_REPORT_FUNCTION;
return false;
}
+// This overrides using same method from the base RTMP class.
bool
-RTMPServer::packetRead(boost::shared_ptr<amf::Buffer> buf)
+RTMPServer::packetRead(amf::Buffer &buf)
{
GNASH_REPORT_FUNCTION;
- unsigned int amf_index, headersize;
- boost::uint8_t *ptr = buf->reference();
+ boost::uint8_t amf_index, headersize;
+ boost::uint8_t *ptr = buf.reference();
AMF amf;
- if (buf->reference() == 0) {
+ if (ptr == 0) {
return false;
}
-
- amf_index = *buf->reference() & RTMP_INDEX_MASK;
- headersize = headerSize(*buf->reference());
+
+ cerr << "FIXME3: " << buf.hexify(true) << endl;
+
+// ptr += 1; // skip past the header byte
+
+ amf_index = *ptr & RTMP_INDEX_MASK;
+ headersize = headerSize(*ptr);
log_debug (_("The Header size is: %d"), headersize);
log_debug (_("The AMF index is: 0x%x"), amf_index);
@@ -262,7 +280,7 @@
// buf->dump();
if (buf->size() < actual_size) {
log_debug("FIXME: MERGING");
- buf = _handler->merge(buf);
+ buf = _que->merge(buf);
}
while ((ptr - buf->begin()) < static_cast<int>(actual_size)) {
boost::shared_ptr<amf::Element> el(new amf::Element);
@@ -286,7 +304,7 @@
break;
case PING:
{
- rtmp_ping_t *ping = decodePing(ptr);
+ boost::shared_ptr<rtmp_ping_t> ping = decodePing(ptr);
switch (ping->type) {
case PING_CLEAR:
break;
@@ -331,21 +349,7 @@
log_error (_("ERROR: Unidentified RTMP message content type 0x%x"),
_header.type);
break;
};
-
- boost::shared_ptr<amf::Element> url = getProperty("tcUrl");
- boost::shared_ptr<amf::Element> file = getProperty("swfUrl");
- boost::shared_ptr<amf::Element> app = getProperty("app");
- if (file) {
- log_debug("SWF file %s", file->to_string());
- }
- if (url) {
- log_debug("is Loading video %s", url->to_string());
- }
- if (app) {
- log_debug("is file name is %s", app->to_string());
- }
-
return true;
}
@@ -366,8 +370,37 @@
boost::shared_ptr<Buffer>
RTMPServer::encodeResult(RTMPMsg::rtmp_status_e status)
{
- GNASH_REPORT_FUNCTION;
+// GNASH_REPORT_FUNCTION;
+ return encodeResult(status, _filespec, _streamid);
+}
+boost::shared_ptr<amf::Buffer>
+RTMPServer::encodeResult(gnash::RTMPMsg::rtmp_status_e status, const
std::string &filename)
+{
+// GNASH_REPORT_FUNCTION;
+ double clientid = 0.0;
+ return encodeResult(status, filename, _streamid, clientid);
+}
+
+boost::shared_ptr<amf::Buffer>
+RTMPServer::encodeResult(gnash::RTMPMsg::rtmp_status_e status, const
std::string &filename, double &clientid)
+{
+// GNASH_REPORT_FUNCTION;
+ return encodeResult(status, filename, _streamid, clientid);
+}
+
+boost::shared_ptr<amf::Buffer>
+RTMPServer::encodeResult(gnash::RTMPMsg::rtmp_status_e status, double
&streamid)
+{
+// GNASH_REPORT_FUNCTION;
+ double clientid = 0.0;
+ return encodeResult(status, "", streamid, clientid);
+}
+
+boost::shared_ptr<amf::Buffer>
+RTMPServer::encodeResult(gnash::RTMPMsg::rtmp_status_e status, const
std::string &filename, double &streamid, double &clientid)
+{
+// GNASH_REPORT_FUNCTION;
// Buffer *buf = new Buffer;
// boost::uint8_t *ptr = buf->reference();
// buf->clear(); // default everything to zeros, real data gets
optionally added.
@@ -376,16 +409,18 @@
// const char *description = 0;
// const char *code = 0;
// const char *status = 0;
+ bool notobject = false;
Element *str = new Element;
str->makeString("_result");
Element *number = new Element;
// add The server ID
- number->makeNumber(1); // FIXME: needs a real value, which should
increment
+ number->makeNumber(streamid); // FIXME: needs a real value, which
should increment
Element top;
- top.makeObject("application");
+// top.makeObject("application");
+ top.makeObject();
switch (status) {
case RTMPMsg::APP_GC:
@@ -438,18 +473,20 @@
boost::shared_ptr<amf::Element> level(new Element);
level->makeString("level", "status");
top.addProperty(level);
+
+ boost::shared_ptr<amf::Element> code(new Element);
+ code->makeString("code", "NetConnection.Connect.Success");
+ top.addProperty(code);
boost::shared_ptr<amf::Element> description(new Element);
description->makeString("description", "Connection succeeded.");
top.addProperty(description);
-
- boost::shared_ptr<amf::Element> code(new Element);
- code->makeString("code", "NetConnection.Connect.Success");
- top.addProperty(code);
}
break;
case RTMPMsg::NS_CLEAR_FAILED:
case RTMPMsg::NS_CLEAR_SUCCESS:
+ // After a successful NetConnection, we get a
+ // NetStream::createStream.
case RTMPMsg::NS_DATA_START:
case RTMPMsg::NS_FAILED:
case RTMPMsg::NS_INVALID_ARGUMENT:
@@ -460,8 +497,69 @@
case RTMPMsg::NS_PLAY_INSUFFICIENT_BW:
case RTMPMsg::NS_PLAY_NO_SUPPORTED_TRACK_FOUND:
case RTMPMsg::NS_PLAY_PUBLISHNOTIFY:
+ break;
+ // Reset the stream. We also do this after receiving a
+ // NetStream::createStream() packet
case RTMPMsg::NS_PLAY_RESET:
+ {
+ str->makeString("onStatus");
+// "clientid"
+ boost::shared_ptr<amf::Element> level(new Element);
+ level->makeString("level", "status");
+ top.addProperty(level);
+
+ boost::shared_ptr<amf::Element> code(new Element);
+ code->makeString("code", "NetStream.Play.Reset");
+ top.addProperty(code);
+
+ boost::shared_ptr<amf::Element> description(new Element);
+ string field = "Playing and resetting ";
+ if (!filename.empty()) {
+ field += filename;
+ }
+ description->makeString("description", field);
+ top.addProperty(description);
+
+ boost::shared_ptr<amf::Element> details(new Element);
+ details->makeString("details", filename);
+ top.addProperty(details);
+
+ boost::shared_ptr<amf::Element> cid(new Element);
+ cid->makeNumber("clientid", clientid);
+ top.addProperty(cid);
+
+ break;
+ }
case RTMPMsg::NS_PLAY_START:
+ {
+ str->makeString("onStatus");
+
+ boost::shared_ptr<amf::Element> level(new Element);
+ level->makeString("level", "status");
+ top.addProperty(level);
+
+ boost::shared_ptr<amf::Element> code(new Element);
+ code->makeString("code", "NetStream.Play.Start");
+ top.addProperty(code);
+
+ boost::shared_ptr<amf::Element> description(new Element);
+ string field = "Started playing ";
+ if (!filename.empty()) {
+ field += filename;
+ }
+ description->makeString("description", field);
+ top.addProperty(description);
+
+ boost::shared_ptr<amf::Element> details(new Element);
+ details->makeString("details", filename);
+ top.addProperty(details);
+
+ boost::shared_ptr<amf::Element> cid(new Element);
+ cid->makeNumber("clientid", clientid);
+ top.addProperty(cid);
+
+ break;
+ }
case RTMPMsg::NS_PLAY_STOP:
case RTMPMsg::NS_PLAY_STREAMNOTFOUND:
case RTMPMsg::NS_PLAY_SWITCH:
@@ -480,13 +578,28 @@
case RTMPMsg::SO_NO_READ_ACCESS:
case RTMPMsg::SO_NO_WRITE_ACCESS:
case RTMPMsg::SO_PERSISTENCE_MISMATCH:
+ break;
+ // Anything below here is specific to Gnash's implementation
+ case RTMPMsg::NS_CREATE_STREAM:
+ {
+ // Don't encode as an object, just the properties
+ notobject = true;
+
+ boost::shared_ptr<amf::Element> id2(new Element);
+ double sid = createStreamID();
+ id2->makeNumber(sid);
+ top.addProperty(id2);
+
+ break;
+ }
+ case RTMPMsg::NS_DELETE_STREAM:
default:
break;
};
boost::shared_ptr<amf::Buffer> strbuf = str->encode();
boost::shared_ptr<amf::Buffer> numbuf = number->encode();
- boost::shared_ptr<amf::Buffer> topbuf = top.encode();
+ boost::shared_ptr<amf::Buffer> topbuf = top.encode(notobject);
boost::shared_ptr<amf::Buffer> buf(new Buffer(strbuf->size() +
numbuf->size() + topbuf->size()));
*buf += strbuf;
@@ -500,91 +613,6 @@
return buf;
}
-
-// This is the thread for all incoming RTMP connections
-void
-rtmp_handler(Network::thread_params_t *args)
-{
- GNASH_REPORT_FUNCTION;
- Handler *hand = reinterpret_cast<Handler *>(args->handler);
- RTMPServer rtmp;
-
- rtmp.setHandler(hand);
- string docroot = args->filespec;
-
- log_debug(_("Starting RTMP Handler for fd #%d, tid %ld"),
- args->netfd, get_thread_id());
-
- while (!hand->timetodie()) {
- log_debug(_("Waiting for RTMP request on fd #%d..."), args->netfd);
- hand->wait();
- // This thread is the last to wake up when the browser
- // closes the network connection. When browsers do this
- // varies, elinks and lynx are very forgiving to a more
- // flexible HTTP protocol, which Firefox/Mozilla & Opera
- // are much pickier, and will hang or fail to load if
- // you aren't careful.
- if (hand->timetodie()) {
- log_debug("Not waiting no more, no more for RTMP data for fd
#%d...", args->netfd);
- map<int, Handler *>::iterator hit = handlers.find(args->netfd);
- if ((*hit).second) {
- log_debug("Removing handle %x for RTMP on fd #%d", (void
*)hand, args->netfd);
- handlers.erase(args->netfd);
- }
-
- return;
- }
-#ifdef USE_STATISTICS
- struct timespec start;
- clock_gettime (CLOCK_REALTIME, &start);
-#endif
- if (!rtmp.handShakeWait()) {
- // hand->clearout(); // remove all data from the outgoing que
- hand->die(); // tell all the threads for this connection to
die
- hand->notifyin();
- log_debug("Net RTMP done for fd #%d...", args->netfd);
-// hand->closeNet(args->netfd);
- return;
- }
- string url, filespec;
- url = docroot;
-
- rtmp.handShakeResponse();
-
- hand->wait();
- // This thread is the last to wake up when the browser
- // closes the network connection. When browsers do this
- // varies, elinks and lynx are very forgiving to a more
- // flexible HTTP protocol, which Firefox/Mozilla & Opera
- // are much pickier, and will hang or fail to load if
- // you aren't careful.
- if (hand->timetodie()) {
- log_debug("Not waiting no more, no more for RTMP data for fd
#%d...", args->netfd);
- map<int, Handler *>::iterator hit = handlers.find(args->netfd);
- if ((*hit).second) {
- log_debug("Removing handle %x for RTMP on fd #%d", (void
*)hand, args->netfd);
- handlers.erase(args->netfd);
- }
-
- return;
- }
- rtmp.serverFinish();
-
- // Keep track of the network statistics
-// Statistics st;
-// st.setFileType(NetStats::RTMP);
-// st.stopClock();
-// log_debug (_("Bytes read: %d"), proto.getBytesIn());
-// log_debug (_("Bytes written: %d"), proto.getBytesOut());
-// st.setBytes(proto.getBytesIn() + proto.getBytesOut());
-// st.addStats();
-// proto.resetBytesIn();
-// proto.resetBytesOut();
-
-// st.dump();
- }
-}
-
// A Ping packet has two parameters that ae always specified, and 2 that are
optional.
// The first two bytes are the ping type, as in rtmp_ping_e, the second is the
ping
// target, which is always zero as far as we can tell.
@@ -608,23 +636,27 @@
boost::shared_ptr<Buffer>
RTMPServer::encodePing(rtmp_ping_e type)
{
- GNASH_REPORT_FUNCTION;
+// GNASH_REPORT_FUNCTION;
return encodePing(type, 0);
}
boost::shared_ptr<Buffer>
RTMPServer::encodePing(rtmp_ping_e type, boost::uint32_t milliseconds)
{
- GNASH_REPORT_FUNCTION;
+// GNASH_REPORT_FUNCTION;
+
+ // An encoded ping message
boost::shared_ptr<amf::Buffer> buf(new Buffer(sizeof(boost::uint16_t) *
3));
- boost::uint8_t *ptr = buf->reference();
- buf->clear(); // default everything to zeros, real data gets
optionally added.
+// boost::uint8_t *ptr = buf->reference();
+ // Set the type of this ping message
boost::uint16_t typefield = htons(type);
- ptr += sizeof(boost::uint16_t); // go past the first short
+ *buf = typefield;
+
+// // go past the first short, which is the type field
+// ptr += sizeof(boost::uint16_t);
boost::uint32_t swapped = 0;
- *buf = typefield;
switch (type) {
// These two don't appear to have any paramaters
case PING_CLEAR:
@@ -633,30 +665,600 @@
// the third parameter is the buffer time in milliseconds
case PING_TIME:
{
- ptr += sizeof(boost::uint16_t); // go past the second short
+// ptr += sizeof(boost::uint16_t); // go past the second short
swapped = milliseconds;
swapBytes(&swapped, sizeof(boost::uint32_t));
- buf->append((boost::uint8_t *)&swapped, sizeof(boost::uint32_t));
+ *buf += swapped;
break;
}
- // reset doesn't have any parameters
+ // reset doesn't have any parameters but zeros
case PING_RESET:
+ {
+ boost::uint16_t zero = 0;
+ *buf += zero;
+ *buf += zero;
break;
- // For Ping and Pong, the second parameter is always the milliseconds
+ }
+ // For Ping and Pong, the second parameter is always the milliseconds
case PING_CLIENT:
case PONG_CLIENT:
{
// swapped = htonl(milliseconds);
swapped = milliseconds;
swapBytes(&swapped, sizeof(boost::uint32_t));
- buf->append((boost::uint8_t *)&swapped, sizeof(boost::uint32_t));
+ *buf += swapped;
break;
}
default:
break;
};
- return buf;
+ // Manually adjust the seek pointer since we added the data by
+ // walking ou own temporary pointer, so none of the regular ways
+ // of setting the seek pointer are appropriate.
+// buf->setSeekPointer(buf->reference() + buf->size());
+
+ return buf;
+}
+
+// Parse an Echo Request message coming from the Red5 echo_test. This
+// method should only be used for testing purposes.
+vector<boost::shared_ptr<amf::Element > >
+RTMPServer::parseEchoRequest(boost::uint8_t *ptr, size_t size)
+{
+// GNASH_REPORT_FUNCTION;
+
+ AMF amf;
+ vector<boost::shared_ptr<amf::Element > > headers;
+
+ // The first element is the name of the test, 'echo'
+ boost::shared_ptr<amf::Element> el1 = amf.extractAMF(ptr, ptr+size);
+ ptr += amf.totalsize();
+ headers.push_back(el1);
+
+ // The second element is the number of the test,
+ boost::shared_ptr<amf::Element> el2 = amf.extractAMF(ptr, ptr+size);
+ ptr += amf.totalsize();
+ headers.push_back(el2);
+
+ // This one has always been a NULL object from my tests
+ boost::shared_ptr<amf::Element> el3 = amf.extractAMF(ptr, ptr+size);
+ ptr += amf.totalsize();
+ headers.push_back(el3);
+
+ // This one has always been an NULL or Undefined object from my tests
+ boost::shared_ptr<amf::Element> el4 = amf.extractAMF(ptr, ptr+size);
+ if (!el4) {
+ log_error("Couldn't reliably extract the echo data!");
+ }
+ ptr += amf.totalsize();
+ headers.push_back(el4);
+
+ return headers;
+}
+
+// format a response to the 'echo' test used for testing Gnash. This
+// is only used for testing by developers. The format appears to be
+// a string '_result', followed by the number of the test, and then two
+// NULL objects.
+boost::shared_ptr<amf::Buffer>
+RTMPServer::formatEchoResponse(double num, amf::Element &el)
+{
+// GNASH_REPORT_FUNCTION;
+ boost::shared_ptr<amf::Buffer> data = amf::AMF::encodeElement(el);
+ return formatEchoResponse(num, data->reference(), data->allocated());
+}
+
+boost::shared_ptr<amf::Buffer>
+RTMPServer::formatEchoResponse(double num, amf::Buffer &data)
+{
+// GNASH_REPORT_FUNCTION;
+ return formatEchoResponse(num, data.reference(), data.allocated());
+}
+
+boost::shared_ptr<amf::Buffer>
+RTMPServer::formatEchoResponse(double num, boost::uint8_t *data, size_t size)
+{
+// GNASH_REPORT_FUNCTION;
+
+ string result = "_result";
+ Element echo;
+ echo.makeString(result);
+
+ Element index;
+ index.makeNumber(num);
+
+ Element null;
+ null.makeNull();
+
+ boost::shared_ptr<amf::Buffer> encecho = echo.encode();
+ boost::shared_ptr<amf::Buffer> encidx = index.encode();
+ boost::shared_ptr<amf::Buffer> encnull = null.encode();
+
+ boost::shared_ptr<amf::Buffer> buf(new amf::Buffer(encecho->size()
+ + encidx->size()
+ + encnull->size() +
size));
+
+ *buf = encecho;
+ *buf += encidx;
+ *buf += encnull;
+ buf->append(data, size);
+
+ return buf;
+}
+
+// Create a new client ID, which appears to be a random double.
+double
+RTMPServer::createClientID()
+{
+// GNASH_REPORT_FUNCTION;
+ boost::mt19937 seed;
+ // Pick the number of errors to create based on the Buffer's data size
+ boost::uniform_real<> numbers(1, 65535);
+
+ double id = numbers(seed);
+ _clientids.push_back(id);
+
+ return id;
+}
+
+// Get the next streamID
+double
+RTMPServer::createStreamID()
+{
+// GNASH_REPORT_FUNCTION;
+ return _streamid++;
+}
+
+bool
+RTMPServer::sendFile(int fd, const std::string &filespec)
+{
+ GNASH_REPORT_FUNCTION;
+ // See if the file is in the cache and already opened.
+ boost::shared_ptr<DiskStream> filestream(cache.findFile(filespec));
+ if (filestream) {
+ cerr << "FIXME: found file in cache!" << endl;
+ } else {
+ filestream.reset(new DiskStream);
+// cerr << "New Filestream at 0x" << hex << filestream.get() << endl;
+
+// cache.addFile(url, filestream); FIXME: always reload from disk
for now.
+
+ // Oopen the file and read the first chunk into memory
+ if (!filestream->open(filespec)) {
+ return false;
+ } else {
+ // Get the file size for the HTTP header
+ if (filestream->getFileType() == DiskStream::FILETYPE_NONE) {
+ return false;
+ } else {
+ cache.addPath(filespec, filestream->getFilespec());
+ }
+ }
+ }
+
+ size_t filesize = filestream->getFileSize();
+ size_t bytes_read = 0;
+ int ret;
+ size_t page = 0;
+ if (filesize) {
+#ifdef USE_STATS_CACHE
+ struct timespec start;
+ clock_gettime (CLOCK_REALTIME, &start);
+#endif
+ size_t getbytes = 0;
+ if (filesize <= filestream->getPagesize()) {
+ getbytes = filesize;
+ } else {
+ getbytes = filestream->getPagesize();
+ }
+ if (filesize >= CACHE_LIMIT) {
+ if (sendMsg(fd, getChannel(), RTMP::HEADER_12, filesize,
+ RTMP::NOTIFY, RTMPMsg::FROM_SERVER, filestream->get(),
+ filesize)) {
+ }
+ do {
+ filestream->loadToMem(page);
+// ret = writeNet(fd, filestream->get(), getbytes);
+// if (ret <= 0) {
+// break;
+// }
+ if (sendMsg(fd, getChannel(), RTMP::HEADER_4, filesize,
+ RTMP::NOTIFY, RTMPMsg::FROM_SERVER,
filestream->get(),
+ getbytes)) {
+ }
+ bytes_read += ret;
+ page += filestream->getPagesize();
+ } while (bytes_read <= filesize);
+ } else {
+ filestream->loadToMem(filesize, 0);
+// ret = writeNet(fd, filestream->get(), filesize);
+ if (sendMsg(fd, getChannel(), RTMP::HEADER_12, filesize,
+ RTMP::NOTIFY, RTMPMsg::FROM_SERVER,
filestream->get()+24,
+ filesize-24)) {
+ }
+
+ }
+ filestream->close();
+#ifdef USE_STATS_CACHE
+ struct timespec end;
+ clock_gettime (CLOCK_REALTIME, &end);
+ double time = (end.tv_sec - start.tv_sec) + ((end.tv_nsec -
start.tv_nsec)/1e9);
+ cerr << "File " << _filespec
+ << " transferred " << filesize << " bytes in: " << fixed
+ << time << " seconds for net fd #" << fd << endl;
+#endif
+ }
+
+ return true;
+}
+
+// This is the thread for all incoming RTMP connections
+bool
+rtmp_handler(Network::thread_params_t *args)
+{
+ GNASH_REPORT_FUNCTION;
+// Handler *hand = reinterpret_cast<Handler *>(args->handler);
+ RTMPServer *rtmp = new RTMPServer;
+ string docroot = args->filespec;
+ string url, filespec;
+ url = docroot;
+ bool done = false;
+ RTMPMsg *body = 0;
+ static bool initialize = true;
+ static bool echo = false;
+ bool sendfile = false;
+ log_debug(_("Starting RTMP Handler for fd #%d, tid %ld"),
+ args->netfd, get_thread_id());
+
+#ifdef USE_STATISTICS
+ struct timespec start;
+ clock_gettime (CLOCK_REALTIME, &start);
+#endif
+
+ // Adjust the timeout
+ rtmp->setTimeout(10);
+
+ boost::shared_ptr<amf::Buffer> pkt;
+ boost::shared_ptr<amf::Element> tcurl;
+ boost::shared_ptr<amf::Element> swfurl;
+ boost::shared_ptr<amf::Buffer> response;
+
+ string basepath = docroot;
+
+ RTMP::rtmp_headersize_e response_head_size = RTMP::HEADER_12;
+
+ // This handler is called everytime there is RTMP data on a socket to
process the
+ // messsage. Unlike HTTP, RTMP always uses persistant network connections,
so we
+ // only want to initialize the handshake once. This becomes important as
the handshake
+ // is always sent as a large data block, 1536 bytes. Once we start reading
packets,
+ // the default size is adjustable via the ChunkSize command.
+ if (initialize) {
+ // Read the handshake bytes sent by the client when requesting
+ // a connection.
+ boost::shared_ptr<amf::Buffer> handshake1 = rtmp->recvMsg(args->netfd);
+ // See if we have data in the handshake, we should have 1537 bytes
+ if (handshake1 == 0) {
+ log_error("failed to read the handshake from the client.");
+ return false;
+ }
+
+ // Send our response to the handshake, which primarily is the bytes
+ // we just recieved.
+ rtmp->handShakeResponse(args->netfd, *handshake1);
+
+ boost::shared_ptr<amf::Buffer> handshake2 = rtmp->recvMsg(args->netfd);
+ // See if we have data in the handshake, we should have 1536 bytes
+ if (handshake2 == 0) {
+ log_error("failed to read the handshake from the client.");
+ return false;
+ }
+ // Don't assume the data we just read is a handshake.
+ pkt = rtmp->serverFinish(args->netfd, *handshake1, *handshake2);
+ if (pkt == 0) {
+ log_error("failed to read data from the end of the handshake from
the client!");
+ return false;
+ }
+ // We got data
+ if (pkt->allocated() > 0) {
+ initialize = false;
+ }
+
+ // Send a ping to reset the new stream
+ boost::shared_ptr<amf::Buffer> ping_reset =
rtmp->encodePing(RTMP::PING_RESET, 0);
+ if (rtmp->sendMsg(args->netfd, RTMP_SYSTEM_CHANNEL, RTMP::HEADER_12,
+ ping_reset->size(), RTMP::PING, RTMPMsg::FROM_SERVER,
*ping_reset)) {
+ log_debug("Sent Ping to client");
+ } else {
+ log_error("Couldn't send Ping to client!");
+ }
+
+ } else {
+ // Read the handshake bytes sent by the client when requesting
+ // a connection.
+ }
+
+ // See if this is a Red5 style echo test.
+ string::size_type pos;
+ if (tcurl) {
+ filespec = tcurl->to_string();
+ pos = filespec.rfind("/");
+ if (pos != string::npos) {
+ if (filespec.substr(pos, filespec.size()-pos) == "/echo") {
+ log_debug("Red5 echo test request!");
+ echo = true;
+ }
+ }
+ }
+
+ // Keep track of the network statistics
+ // See if we have any messages waiting. After the initial connect, this is
+ // the main loop for processing messages.
+
+ // Adjust the timeout
+ rtmp->setTimeout(30);
+// boost::shared_ptr<amf::Buffer> buf;
+
+ // This is the main message processing loop for rtmp. All message received
require
+ // a response.
+ do {
+ // If there is no data left from the previous chunk, process that before
+ // reading more data.
+ if (pkt != 0) {
+ log_debug("data left from previous packet");
+ } else {
+ pkt = rtmp->recvMsg(args->netfd);
+ }
+
+ if (pkt != 0) {
+ boost::uint8_t *tmpptr = 0;
+ if (pkt->allocated()) {
+ boost::shared_ptr<RTMP::queues_t> que = rtmp->split(*pkt);
+ boost::shared_ptr<RTMP::rtmp_head_t> qhead;
+ cerr << "FIXME1 incoming Que has " << que->size() << "
messages." << endl;
+ for (size_t i=0; i<que->size(); i++) {
+ boost::shared_ptr<amf::Buffer> bufptr = que->at(i)->pop();
+// que->at(i)->dump();
+ if (bufptr) {
+ bufptr->dump();
+ qhead = rtmp->decodeHeader(bufptr->reference());
+ log_debug("Message for channel #%d", qhead->channel);
+// tmpptr = bufptr->reference();
+ tmpptr = bufptr->reference() + qhead->head_size;
+ if (qhead->channel == RTMP_SYSTEM_CHANNEL) {
+ boost::shared_ptr<RTMP::rtmp_ping_t> ping =
rtmp->decodePing(tmpptr);
+ log_debug("Processed Ping message from client, type
%d", ping->type);
+ } else {
+ if (echo) {
+ log_debug("Got an echo request");
+ // process the echo test request
+ vector<boost::shared_ptr<amf::Element> >
request = rtmp->parseEchoRequest(
+
bufptr->reference() + qhead->head_size,
bufptr->allocated() - qhead->head_size);
+ if (request[3]) {
+ boost::shared_ptr<amf::Buffer> result =
rtmp->formatEchoResponse(request[1]->to_number(), *request[3]);
+ if (rtmp->sendMsg(args->netfd,
qhead->channel, RTMP::HEADER_8, result->allocated(),
+ RTMP::INVOKE,
RTMPMsg::FROM_SERVER, *result)) {
+ // If we're in single threaded mode, we
Just want to stay in
+ // this thread for now and do
everything all at once. Otherwise
+ // we're done, so we return to the
dispatch handler waiting for
+ // the next packet. Single threaded
mode is primarily used by
+ // developers for debugging protocols.
+ log_debug("Sent echo test response
response to client.");
+ }
+ } else {
+ log_error("Couldn't send echo test response
to client!");
+ done = true;
+ }
+ } else {
+ body = rtmp->decodeMsgBody(tmpptr,
qhead->bodysize);
+ if (body) {
+ body->setChannel(qhead->channel);
+ // Invoke the NetConnection::connect()
method
+ if (body->getMethodName() == "connect") {
+ response_head_size = RTMP::HEADER_12;
+ tcurl = body->findProperty("tcUrl");
+ if (tcurl) {
+ log_debug("Client request for
remote file is: %s", tcurl->to_string());
+ string path = tcurl->to_string();
+ string::size_type start =
path.find("://", 0) + 4;
+ if (start != string::npos) {
+ string::size_type end =
path.find("/", start);
+ if (end != string::npos) {
+ basepath +=
path.substr(end, path.size());
+ }
+ }
+ log_debug("Base path to files from
connect is: %s", basepath);
+
+ }
+ swfurl = body->findProperty("swfUrl");
+ if (swfurl) {
+ log_debug("SWF filename making
request is: %s", swfurl->to_string());
+ // See if this is a Red5 style echo
test.
+ string::size_type pos;
+ filespec = swfurl->to_string();
+ pos = filespec.rfind("/");
+ if (pos != string::npos) {
+ if (filespec.substr(pos,
filespec.size()-pos) == "/echo_test.swf") {
+ log_debug("Red5 echo test
request!");
+ echo = true;
+ }
+ }
+ }
+
+ response =
rtmp->encodeResult(RTMPMsg::NC_CONNECT_SUCCESS);
+
+ // Send a ping to reset the new stream
+ boost::shared_ptr<amf::Buffer>
ping_reset = rtmp->encodePing(RTMP::PING_RESET, 0);
+ if (rtmp->sendMsg(args->netfd,
RTMP_SYSTEM_CHANNEL, RTMP::HEADER_12,
+ ping_reset->size(),
RTMP::PING, RTMPMsg::FROM_SERVER, *ping_reset)) {
+ log_debug("Sent Ping to client");
+ } else {
+ log_error("Couldn't send Ping to
client!");
+ }
+
+ }
+ // Invoke the NetStream::createStream()
method
+ if (body->getMethodName() ==
"createStream") {
+ double streamid = body->getStreamID();
+ log_debug("The streamID from
NetStream::createStream() is: %d", streamid);
+ response_head_size = RTMP::HEADER_8;
+ response =
rtmp->encodeResult(RTMPMsg::NS_CREATE_STREAM, streamid);
+// body->dump();
+ }
+ if (body->getMethodName() ==
"deleteStream") {
+ double streamid = body->getStreamID();
+ log_debug("The streamID from
NetStream::deleyeStream() is: %d", streamid);
+ response_head_size = RTMP::HEADER_8;
+ response =
rtmp->encodeResult(RTMPMsg::NS_DELETE_STREAM, streamid);
+ body->dump();
+ }
+ // Invoke the NetStream::play() method
+ if (body->getMethodName() == "play") {
+ double streamid = body->getStreamID();
+ log_debug("The streamID from
NetStream::plays: %d", streamid);
+ filespec = body->at(1)->to_string();
+ response_head_size = RTMP::HEADER_8;
+ double clientid =
rtmp->createClientID();
+// response =
rtmp->encodeResult(RTMPMsg::NS_PLAY_RESET, filespec);
+ body->setChannel(4);
+// rtmp->sendMsg(args->netfd,
body->getChannel(), response_head_size, response->allocated(),
+// RTMP::INVOKE,
RTMPMsg::FROM_SERVER, *response);
+// response.reset();
+// rtmp->setChannel(4);
+// rtmp->sendMsg(args->netfd,
body->getChannel(), response_head_size, response->allocated(),
+ response =
rtmp->encodeResult(RTMPMsg::NS_PLAY_START, filespec, clientid);
+// body->dump();
+ sendfile = true;
+ }
+ if (body->getMethodName() == "recData") {
+ }
+ if (body->getMethodName() ==
"onEchoonServ") {
+ }
+ if (rtmp->sendMsg(args->netfd,
body->getChannel(), response_head_size, response->allocated(),
+ RTMP::INVOKE,
RTMPMsg::FROM_SERVER, *response)) {
+ log_error("Sent response to client.");
+ } else {
+ log_error("Couldn't send response to
client!");
+ }
+ if (sendfile) {
+ string fullspec = basepath;
+ fullspec += filespec;
+ rtmp->sendFile(args->netfd, fullspec);
+ sendfile = false;
+ }
+ }
+ }
+ }
+ } else {
+ log_error("Message contains no data!");
+ }
+ } // end of processing all the messages in the que
+
+ // we're done processing these packets, so get rid of them
+ pkt.reset();
+
+
+
+#if 0
+ // This is support for the Red5 'echo_test', which exercises
encoding and
+ // decoding of complex and nested AMF data types. FIXME: this
should be
+ // moved to a CGI type of thing that executes this as a
separate process,
+ // using a socket to pass output back to the client.
+ if (echo) {
+ boost::shared_ptr<RTMP::queues_t> que = rtmp->split(*pkt);
+ boost::shared_ptr<amf::Buffer> bufptr;
+ if (que->size() > 0) {
+ cerr << "FIXME2 echo Que size is: " << que->size() <<
endl;
+ bufptr = que->at(0)->pop();
+ }
+ // process the echo test request
+ vector<boost::shared_ptr<amf::Element> > request =
rtmp->parseEchoRequest(
+ bufptr->reference() + rthead->head_size,
bufptr->allocated() - rthead->head_size);
+ // now build a result
+ if (request[3]) {
+ boost::shared_ptr<amf::Buffer> result =
rtmp->formatEchoResponse(request[1]->to_number(), *request[3]);
+ if (rtmp->sendMsg(args->netfd, rthead->channel,
RTMP::HEADER_8, result->allocated(),
+ RTMP::INVOKE, RTMPMsg::FROM_SERVER,
*result)) {
+ // If we're in single threaded mode, we Just want
to stay in
+ // this thread for now and do everything all at
once. Otherwise
+ // we're done, so we return to the dispatch handler
waiting for
+ // the next packet. Single threaded mode is
primarily used by
+ // developers for debugging protocols.
+ log_debug("Sent echo test response response to
client.");
+ }
+ } else {
+ log_error("Couldn't send echo test response to
client!");
+ done = true;
+ }
+ } else { // end of Red5 echo test support
+// buf->dump();
+ // This is a non-Red5 message, which should be the normal
mode of operating.
+// boost::shared_ptr<RTMP::queues_t> que = rtmp->split(*pkt);
+ if (que->size() > 0) {
+ boost::shared_ptr<amf::Buffer> bufptr;
+ if (que->size() > 0) {
+ bufptr = que->at(0)->pop();
+ }
+ if (bufptr) {
+ boost::shared_ptr<RTMP::rtmp_head_t> qhead =
rtmp->decodeHeader(bufptr->reference());
+
+ for (size_t i=0; i<que->size(); i++) {
+ boost::uint8_t *tmpptr = bufptr->reference() +
qhead->head_size;
+ body = rtmp->decodeMsgBody(tmpptr,
qhead->bodysize);
+ boost::shared_ptr<amf::Buffer> response;
+ if (body) {
+ if (body->getMethodName() == "connect") {
+ response =
rtmp->encodeResult(RTMPMsg::NC_CONNECT_SUCCESS);
+ } else if (body->getMethodName() == "createS
+tream") {
+ response =
rtmp->encodeResult(RTMPMsg::NS_DATA_START);
+ } else {
+ response =
rtmp->encodeResult(RTMPMsg::NS_FAILED);
+ }
+ } else {
+ response =
rtmp->encodeResult(RTMPMsg::NS_FAILED);
+ }
+
+ if (rtmp->sendMsg(args->netfd, qhead->channel,
RTMP::HEADER_8, response->allocated(),
+ RTMP::INVOKE,
RTMPMsg::FROM_SERVER, *response)) {
+ log_error("Sent response to client.");
+ } else {
+ log_error("Couldn't send response to
client!");
+ }
+
+
+ }
+ } else {
+ log_error("%s:%d Message contains no data!",
__FUNCTION__, __LINE__);
+ }
+ }
+ }
+#endif
+
+
+ } else {
+ log_error("Never read any data from fd #%d", args->netfd);
+#if 0
+ // Send a ping to reset the new stream
+ boost::shared_ptr<amf::Buffer> ping_reset =
rtmp->encodePing(RTMP::PING_CLEAR, 0);
+ if (rtmp->sendMsg(args->netfd, RTMP_SYSTEM_CHANNEL,
RTMP::HEADER_12,
+ ping_reset->size(), RTMP::PING,
RTMPMsg::FROM_SERVER, *ping_reset)) {
+ log_debug("Sent Ping to client");
+ } else {
+ log_error("Couldn't send Ping to client!");
+ }
+#endif
+ initialize = true;
+ return false;
+ }
+ } else {
+ log_error("Communication error with client using fd #%d",
args->netfd);
+ initialize = true;
+ return false;
+ }
+ } while (!done);
+
+ return true;
}
} // end of gnash namespace
=== renamed file 'libnet/rtmp_server.h' => 'cygnal/rtmp_server.h'
--- a/libnet/rtmp_server.h 2008-12-15 03:46:09 +0000
+++ b/cygnal/rtmp_server.h 2009-02-14 22:42:54 +0000
@@ -28,32 +28,64 @@
#include "handler.h"
#include "network.h"
#include "buffer.h"
+#include "diskstream.h"
+#include "rtmp_msg.h"
-namespace gnash
+namespace cygnal
{
-class DSOEXPORT RTMPServer : public RTMP
+class DSOEXPORT RTMPServer : public gnash::RTMP
{
public:
RTMPServer();
~RTMPServer();
- bool handShakeWait();
- bool handShakeResponse();
- bool serverFinish();
- bool packetSend(boost::shared_ptr<amf::Buffer> buf);
- bool packetRead(boost::shared_ptr<amf::Buffer> buf);
+// bool processClientHandShake(int fd, amf::Buffer &buf);
+ bool handShakeResponse(int fd, amf::Buffer &buf);
+ boost::shared_ptr<amf::Buffer> serverFinish(int fd, amf::Buffer
&handshake1, amf::Buffer &handshake2);
+ bool packetSend(amf::Buffer &buf);
+ bool packetRead(amf::Buffer &buf);
// These are handlers for the various types
- boost::shared_ptr<amf::Buffer> encodeResult(RTMPMsg::rtmp_status_e status);
+ boost::shared_ptr<amf::Buffer> encodeResult(gnash::RTMPMsg::rtmp_status_e
status);
+ boost::shared_ptr<amf::Buffer> encodeResult(gnash::RTMPMsg::rtmp_status_e
status, const std::string &filename);
+ boost::shared_ptr<amf::Buffer> encodeResult(gnash::RTMPMsg::rtmp_status_e
status, const std::string &filename, double &streamid);
+ boost::shared_ptr<amf::Buffer> encodeResult(gnash::RTMPMsg::rtmp_status_e
status, double &streamid);
+ boost::shared_ptr<amf::Buffer> encodeResult(gnash::RTMPMsg::rtmp_status_e
status, const std::string &filename, double &streamid, double &clientid);
boost::shared_ptr<amf::Buffer> encodePing(rtmp_ping_e type,
boost::uint32_t milliseconds);
boost::shared_ptr<amf::Buffer> encodePing(rtmp_ping_e type);
-
+
+ // Parse an Echo Request message coming from the Red5 echo_test.
+ std::vector<boost::shared_ptr<amf::Element > >
parseEchoRequest(amf::Buffer &buf) { return parseEchoRequest(buf.reference(),
buf.size()); };
+ std::vector<boost::shared_ptr<amf::Element > >
parseEchoRequest(boost::uint8_t *buf, size_t size);
+ // format a response to the 'echo' test used for testing Gnash.
+ boost::shared_ptr<amf::Buffer> formatEchoResponse(double num, amf::Element
&el);
+ boost::shared_ptr<amf::Buffer> formatEchoResponse(double num, amf::Buffer
&data);
+ boost::shared_ptr<amf::Buffer> formatEchoResponse(double num,
boost::uint8_t *data, size_t size);
+ void addReference(boost::uint16_t index, amf::Element &el) {
_references[index] = el; };
+ amf::Element &getReference(boost::uint16_t index) { return
_references[index]; };
+
+ bool sendFile(int fd, const std::string &filespec);
+
+ double createClientID();
+ double createStreamID();
+ void setStreamID(double id) { _streamid = id; };
+ double getStreamID() { return _streamid; };
+
void dump();
private:
+ typedef boost::char_separator<char> Sep;
+ typedef boost::tokenizer<Sep> Tok;
+ gnash::DiskStream::filetype_e _filetype;
+ std::string _docroot;
+ std::string _filespec;
+ boost::uint32_t _filesize;
+ std::map<boost::uint16_t, amf::Element> _references;
+ std::vector<double> _clientids;
+ double _streamid;
};
// This is the thread for all incoming RTMP connections
-void rtmp_handler(Network::thread_params_t *args);
+bool rtmp_handler(gnash::Network::thread_params_t *args);
} // end of gnash namespace
// end of _RTMP_SERVER_H_
=== modified file 'libamf/amf.cpp'
--- a/libamf/amf.cpp 2008-12-24 02:31:58 +0000
+++ b/libamf/amf.cpp 2009-02-17 00:59:30 +0000
@@ -187,7 +187,7 @@
boost::shared_ptr<Buffer>
AMF::encodeObject(const amf::Element &data)
{
- GNASH_REPORT_FUNCTION;
+// GNASH_REPORT_FUNCTION;
boost::uint32_t length;
length = data.propertySize();
// log_debug("Encoded data size has %d properties", length);
@@ -197,7 +197,7 @@
}
*buf = Element::OBJECT_AMF0;
if (data.propertySize() > 0) {
- vector<boost::shared_ptr<amf::Element> >::const_iterator ait;
+ vector<boost::shared_ptr<amf::Element> >::const_iterator ait;
vector<boost::shared_ptr<amf::Element> > props = data.getProperties();
for (ait = props.begin(); ait != props.end(); ait++) {
boost::shared_ptr<amf::Element> el = (*(ait));
@@ -269,12 +269,14 @@
{
// GNASH_REPORT_FUNCTION;
// boost::shared_ptr<Buffer> buf;
- boost::shared_ptr<Buffer> buf(new Buffer(AMF0_NUMBER_SIZE+1));
- *buf = Element::DATE_AMF0;
- double num = *(reinterpret_cast<const double*>(date));
- swapBytes(&num, AMF0_NUMBER_SIZE);
- *buf += num;
-
+ boost::shared_ptr<Buffer> buf;
+ if (date != 0) {
+ buf.reset(new Buffer(AMF0_NUMBER_SIZE+1));
+ *buf = Element::DATE_AMF0;
+ double num = *(reinterpret_cast<const double*>(date));
+ swapBytes(&num, AMF0_NUMBER_SIZE);
+ *buf += num;
+ }
return buf;
}
@@ -320,44 +322,43 @@
boost::shared_ptr<Buffer>
AMF::encodeTypedObject(const amf::Element &data)
{
- GNASH_REPORT_FUNCTION;
- boost::uint32_t length;
- length = data.propertySize();
-// log_debug("Encoded data size has %d properties", length);
- boost::shared_ptr<amf::Buffer> buf(new amf::Buffer);
- buf->clear();
-#if 0
- size_t outsize = 0;
- if (data.getName()) {
- outsize = data.getNameSize() + sizeof(boost::uint16_t);
- } else {
- outsize == 1;
+// GNASH_REPORT_FUNCTION;
+
+ size_t size = 0;
+ boost::uint32_t props;
+ props = data.propertySize();
+ boost::shared_ptr<amf::Buffer> buf;
+ // log_debug("Encoded data size has %d properties", props);
+ if (props) {
+ // Calculate the total size of the output buffer
+ // needed to hold the encoded properties
+ for (size_t i=0; i<data.propertySize(); i++) {
+ size += data.getProperty(i)->getDataSize();
+ size += data.getProperty(i)->getNameSize();
+ size += AMF_PROP_HEADER_SIZE;
+ }
+ size += data.getNameSize();
+ buf.reset(new Buffer(size+24)); // FIXME: why are we several words off ?
}
-// if (length <= 0) {
-// buf.reset();
-// return buf;
-// }
- // buf.reset(new amf::Buffer);
-#endif
+
*buf = Element::TYPED_OBJECT_AMF0;
- // If the name field is set, it's a property, followed by the data
+
+ size_t length = data.getNameSize();
+ boost::uint16_t enclength = length;
+ swapBytes(&enclength, 2);
+ *buf += enclength;
+
if (data.getName()) {
- // Add the length of the string for the name of the variable
- size_t namelength = data.getNameSize();
- boost::uint16_t enclength = namelength;
- swapBytes(&enclength, 2);
- *buf += enclength;
- // Now the name itself
string name = data.getName();
if (name.size() > 0) {
*buf += name;
}
}
-
+
if (data.propertySize() > 0) {
- vector<boost::shared_ptr<amf::Element> >::reverse_iterator ait;
+ vector<boost::shared_ptr<amf::Element> >::const_iterator ait;
vector<boost::shared_ptr<amf::Element> > props = data.getProperties();
- for (ait = props.rbegin(); ait != props.rend(); ait++) {
+ for (ait = props.begin(); ait != props.end(); ait++) {
boost::shared_ptr<amf::Element> el = (*(ait));
boost::shared_ptr<amf::Buffer> item = AMF::encodeElement(el);
if (item) {
@@ -369,7 +370,7 @@
// el->dump();
}
}
-
+
// Terminate the object
*buf += '\0';
*buf += '\0';
@@ -386,11 +387,14 @@
///
/// @return a binary AMF packet in big endian format (header,data)
boost::shared_ptr<Buffer>
-AMF::encodeReference(const boost::uint8_t * /* data */, size_t /* size */)
+AMF::encodeReference(boost::uint16_t index)
{
// GNASH_REPORT_FUNCTION;
- boost::shared_ptr<Buffer> buf;
- log_unimpl("Reference AMF objects not supported yet");
+ boost::uint16_t num = index;
+ boost::shared_ptr<amf::Buffer> buf(new Buffer(3));
+ *buf = Element::REFERENCE_AMF0;
+ swapBytes(&num, sizeof(boost::uint16_t));
+ *buf += num;
return buf;
}
@@ -426,13 +430,16 @@
{
// GNASH_REPORT_FUNCTION;
boost::uint32_t length;
+ bool sparse = false;
+ size_t counter = 0;
+
length = data.propertySize();
// log_debug("Encoded data size has %d properties", length);
boost::shared_ptr<amf::Buffer> buf(new amf::Buffer);
if (length == 0) {
// an undefined array is only 5 bytes, 1 for the type and
// 4 for the length.
- buf->resize(5);
+ buf.reset(new amf::Buffer(5));
}
*buf = Element::ECMA_ARRAY_AMF0;
length = 1;
@@ -442,20 +449,38 @@
// At lest for red5, it seems to encode from the last item to the
// first, so we do the same for now.
if (data.propertySize() > 0) {
- vector<boost::shared_ptr<amf::Element> >::reverse_iterator ait;
+ boost::shared_ptr<amf::Buffer> item;
+ vector<boost::shared_ptr<amf::Element> >::const_iterator ait;
vector<boost::shared_ptr<amf::Element> > props = data.getProperties();
- for (ait = props.rbegin(); ait != props.rend(); ait++) {
+ for (ait = props.begin(); ait != props.end(); ait++) {
boost::shared_ptr<amf::Element> el = (*(ait));
- boost::shared_ptr<amf::Buffer> item = AMF::encodeElement(el);
- if (item) {
- *buf += item;
- item.reset();
+ if (sparse) {
+ sparse = false;
+// char num[12];
+// sprintf(num, "%d", counter);
+// amf::Element elnum(num, el->to_number());
+// *buf += AMF::encodeElement(elnum);
+// double nodes = items;
+ amf::Element ellen("length");
+ ellen.makeNumber(data.propertySize());
+ *buf += AMF::encodeElement(ellen);
} else {
- break;
+ item = AMF::encodeElement(el);
+ if (item) {
+ *buf += item;
+ item.reset();
+ } else {
+ break;
+ }
}
- //el->dump();
}
}
+#if 0
+ double count = data.propertySize();
+ amf::Element ellen("length", count);
+ boost::shared_ptr<amf::Buffer> buflen = ellen.encode();
+ *buf += buflen;
+#endif
// Terminate the object
*buf += '\0';
@@ -511,7 +536,7 @@
boost::shared_ptr<Buffer>
AMF::encodeStrictArray(const amf::Element &data)
{
- GNASH_REPORT_FUNCTION;
+// GNASH_REPORT_FUNCTION;
boost::uint32_t items;
items = data.propertySize();
// log_debug("Encoded data size has %d properties", items);
@@ -531,7 +556,7 @@
if (data.propertySize() > 0) {
vector<boost::shared_ptr<amf::Element> >::const_iterator ait;
vector<boost::shared_ptr<amf::Element> > props = data.getProperties();
- bool skip = false;
+ bool sparse = false;
size_t counter = 0;
for (ait = props.begin(); ait != props.end(); ait++) {
counter++;
@@ -539,7 +564,8 @@
// If we see an undefined data item, then switch to an ECMA
// array which is more compact. At least this is what Red5 does.
if (el->getType() == Element::UNDEFINED_AMF0) {
- if (!skip) {
+ if (!sparse) {
+ log_debug("Encoding a strict array as an ecma array");
*buf->reference() = Element::ECMA_ARRAY_AMF0;
// When returning an ECMA array for a sparsely populated
// array, Red5 adds one more to the count to be 1 based,
@@ -548,12 +574,12 @@
swapBytes(&moreitems, sizeof(boost::uint32_t));
boost::uint8_t *ptr = buf->reference() + 1;
memcpy(ptr, &moreitems, sizeof(boost::uint32_t));
- skip = true;
+ sparse = true;
}
continue;
} else {
- if (skip) {
- skip = false;
+ if (sparse) {
+ sparse = false;
char num[12];
sprintf(num, "%d", counter);
amf::Element elnum(num, el->to_number());
@@ -672,83 +698,6 @@
AMF::encodeElement(const amf::Element& el)
{
// GNASH_REPORT_FUNCTION;
-#if 0
- size_t outsize = 0;
-
- // Simple Elements have everything contained in just the class itself.
- // If thr name is set, it's a property, so the length is
- // prefixed to the name string.
- if (el.getNameSize()) {
- outsize += el.getNameSize() + sizeof(boost::uint16_t);
- }
- // If there is any data, then the size of the data plus the header
- // of the type and the length is next.
- if (el.getDataSize()) {
- outsize += el.getDataSize() + AMF_HEADER_SIZE;
- }
-
- // More complex messages have child elements, either properties or
- // the items in an array, If we have children, count up their size too.
- // Calculate the total size of the message
- vector<boost::shared_ptr<amf::Element> > props = el.getProperties();
- for (size_t i=0; i<props.size(); i++) {
- outsize += props[i]->getDataSize();
- if (props[i]->getNameSize()) {
- outsize += props[i]->getNameSize();
- outsize += amf::AMF_PROP_HEADER_SIZE;
- } else {
- outsize += amf::AMF_HEADER_SIZE;
- }
- }
-
- // If an array has no data, it's undefined, so has a length of zero.
- if (el.getType() == Element::STRICT_ARRAY_AMF0) {
- if ((el.getDataSize() == 0) && (props.size() == 0)) {
- outsize += sizeof(boost::uint32_t) + 1;
- }
- }
-
- // An encoded number is always 8 bytes (a double) plus one byte
- // for the type field.
- if (el.getType() == Element::NUMBER_AMF0) {
- outsize = AMF0_NUMBER_SIZE + 1;
- }
-
- // Several types have no data when encoded, like NULL, Undefined,
- // and Unsupported, so we only need enough room to store the header
- // type field, which is only 1 byte.
- if (outsize == 0) {
- outsize = 1;
- }
- // Arrays have an additional 4 byte long field to hold the
- // number of items in the array.
- if ((el.getType() == Element::STRICT_ARRAY_AMF0)
- || (el.getType() == Element::ECMA_ARRAY_AMF0)) {
- log_debug("Array has %d items", props.size());
- outsize += sizeof(boost::uint32_t);
- }
- if ((outsize <= 0) || (outsize > 0xffff)) {
- log_error("Outsize is out of range!", outsize);
- el.dump();
- }
- boost::shared_ptr<Buffer> buf(new Buffer(outsize));
- log_debug("AMF::%s: Outsize is: %d", __FUNCTION__, outsize);
-
- // If the name field is set, it's a property, followed by the data
- if (el.getName()) {
- // Add the length of the string for the name of the variable
- size_t length = el.getNameSize();
- boost::uint16_t enclength = length;
- swapBytes(&enclength, 2);
- *buf = enclength;
- // Now the name itself
- string name = el.getName();
- if (name.size() > 0) {
- *buf += name;
- }
- }
-#endif
-
boost::shared_ptr<Buffer> buf;
// Encode the element's data
switch (el.getType()) {
@@ -774,7 +723,11 @@
{
// boost::shared_ptr<Buffer> encstr = AMF::encodeString(el.to_string());
// *buf += encstr;
- buf = encodeString(el.to_string());
+ if (el.getDataSize() == 0) {
+ buf = encodeNullString();
+ } else {
+ buf = encodeString(el.to_string());
+ }
break;
}
case Element::OBJECT_AMF0:
@@ -792,7 +745,7 @@
buf = encodeUndefined();
break;
case Element::REFERENCE_AMF0:
- buf = encodeReference(el.to_reference(), el.getDataSize());
+ buf = encodeReference(el.to_short());
break;
case Element::ECMA_ARRAY_AMF0:
buf = encodeECMAArray(el);
@@ -842,8 +795,14 @@
};
// If the name field is set, it's a property, followed by the data
+ boost::shared_ptr<Buffer> bigbuf;
if (el.getName() && (el.getType() != Element::TYPED_OBJECT_AMF0)) {
- boost::shared_ptr<Buffer> bigbuf(new amf::Buffer(el.getNameSize() +
sizeof(boost::uint16_t) + buf->size()));
+ if (buf) {
+ bigbuf.reset(new amf::Buffer(el.getNameSize() +
sizeof(boost::uint16_t) + buf->size()));
+ } else {
+ bigbuf.reset(new amf::Buffer(el.getNameSize() +
sizeof(boost::uint16_t)));
+ }
+
// Add the length of the string for the name of the variable
size_t length = el.getNameSize();
boost::uint16_t enclength = length;
@@ -854,7 +813,9 @@
if (name.size() > 0) {
*bigbuf += name;
}
- *bigbuf += buf;
+ if (buf) {
+ *bigbuf += buf;
+ }
return bigbuf;
}
@@ -877,7 +838,7 @@
boost::shared_ptr<Buffer> buf(new Buffer(outsize));
_totalsize += outsize;
- // Add the length of the string for the name of the variable
+ // Add the length of the string for the name of the property
size_t length = el->getNameSize();
boost::uint16_t enclength = length;
swapBytes(&enclength, 2);
@@ -890,7 +851,7 @@
}
}
- // Add the type of the variable's data
+ // Add the type of the property's data
*buf += el->getType();
// Booleans appear to be encoded weird. Just a short after
// the type byte that's the value.
@@ -910,7 +871,7 @@
enclength = el->getDataSize();
swapBytes(&enclength, 2);
*buf += enclength;
- // Now the data for the variable
+ // Now the data for the property
buf->append(el->to_reference(), el->getDataSize());
}
@@ -959,6 +920,8 @@
return el;
}
+ std::map<boost::uint16_t, amf::Element> references;
+
// All elements look like this:
// the first two bytes is the length of name of the element
// Then the next bytes are the element name
@@ -995,8 +958,8 @@
length = ntohs((*(boost::uint16_t *)tmpptr) & 0xffff);
tmpptr += sizeof(boost::uint16_t);
if (length >= SANE_STR_SIZE) {
- log_error("%d bytes for a string is over the safe limit of %d",
- length, SANE_STR_SIZE);
+ log_error("%d bytes for a string is over the safe limit of %d,
line %d",
+ length, SANE_STR_SIZE, __LINE__);
el.reset();
return el;
}
@@ -1014,7 +977,7 @@
{
el->makeObject();
while (tmpptr < tooFar) { // FIXME: was tooFar - AMF_HEADER_SIZE)
- if (*tmpptr == TERMINATOR) {
+ if (*tmpptr+3 == TERMINATOR) {
// log_debug("No data associated with Property in object");
tmpptr++;
break;
@@ -1022,14 +985,14 @@
boost::shared_ptr<amf::Element> child =
amf_obj.extractProperty(tmpptr, tooFar);
if (child == 0) {
// skip past zero length string (2 bytes), null (1 byte) and
end object (1 byte)
- tmpptr += 4;
+// tmpptr += 3;
break;
}
// child->dump();
el->addProperty(child);
tmpptr += amf_obj.totalsize();
};
-// tmpptr += AMF_HEADER_SIZE; // skip past the terminator
bytes
+ tmpptr += AMF_HEADER_SIZE; // skip past the terminator
bytes
break;
}
case Element::MOVIECLIP_AMF0:
@@ -1042,31 +1005,54 @@
el->makeUndefined();
break;
case Element::REFERENCE_AMF0:
- el->makeReference();
+ {
+ length = ntohs((*(boost::uint16_t *)tmpptr) & 0xffff);
+ tmpptr += sizeof(boost::uint16_t);
+ el->makeReference(length);
+ // FIXME: connect reference Element to the object pointed to by the
index.
+ tmpptr += 3;
break;
- // An ECMA array is comprised of any of the data types. Much like an
Object,
- // the ECMA array is terminated by the end of object bytes, so parse
till then.
+ }
+ // An ECMA array is comprised of any of the data types. Much like an
Object,
+ // the ECMA array is terminated by the end of object bytes, so parse
till then.
case Element::ECMA_ARRAY_AMF0:
{
el->makeECMAArray();
+ tmpptr += sizeof(boost::uint32_t);
+#if 1
+ while (tmpptr < tooFar) { // FIXME: was tooFar - AMF_HEADER_SIZE)
+ if (*tmpptr+3 == TERMINATOR) {
+// log_debug("No data associated with Property in object");
+ tmpptr++;
+ break;
+ }
+ boost::shared_ptr<amf::Element> child =
amf_obj.extractProperty(tmpptr, tooFar);
+ if (child == 0) {
+ // skip past zero length string (2 bytes), null (1 byte) and
end object (1 byte)
+// tmpptr += 3;
+ break;
+ }
+// child->dump();
+ el->addProperty(child);
+ tmpptr += amf_obj.totalsize();
+ };
+ tmpptr += AMF_HEADER_SIZE; // skip past the terminator
bytes
+ break;
+#else
// get the number of elements in the array
boost::uint32_t items = ntohl((*(boost::uint32_t *)tmpptr) &
0xffffffff);
tmpptr += sizeof(boost::uint32_t);
- while (tmpptr < (tooFar - AMF_HEADER_SIZE)) {
- if (*tmpptr == TERMINATOR) {
-// log_debug("No data associated with Property in object");
- tmpptr++;
- break;
- }
+ while (items--) {
boost::shared_ptr<amf::Element> child =
amf_obj.extractProperty(tmpptr, tooFar);
if (child == 0) {
break;
}
-// child->dump();
+ child->dump();
el->addProperty(child);
tmpptr += amf_obj.totalsize();
};
tmpptr += AMF_HEADER_SIZE; // skip past the terminator
bytes
+#endif
break;
}
case Element::OBJECT_END_AMF0:
@@ -1116,28 +1102,33 @@
case Element::TYPED_OBJECT_AMF0:
{
el->makeTypedObject();
- // a Typed Object has a name
+
length = ntohs((*(boost::uint16_t *)tmpptr) & 0xffff);
tmpptr += sizeof(boost::uint16_t);
- el->setName(tmpptr, length);
- tmpptr += length;
- while (tmpptr < tooFar) { // FIXME: was tooFar - AMF_HEADER_SIZE)
- if (*tmpptr == TERMINATOR) {
-// log_debug("No data associated with Property in object");
+ if (length > 0) {
+ std::string name(reinterpret_cast<const char *>(tmpptr), length);
+ // log_debug("Typed object name is: %s", el->getName());
+ el->setName(name.c_str(), name.size());
+ }
+ // Don't read past the end
+ if (tmpptr + length < tooFar) {
+ tmpptr += length;
+ }
+ while (tmpptr < tooFar - length) { // FIXME: was tooFar -
AMF_HEADER_SIZE)
+ if (*(tmpptr +3) == TERMINATOR) {
+ log_debug("Found object terminator byte");
tmpptr++;
break;
}
boost::shared_ptr<amf::Element> child =
amf_obj.extractProperty(tmpptr, tooFar);
if (child == 0) {
- // skip past zero length string (2 bytes), null (1 byte) and
end object (1 byte)
- tmpptr += AMF_HEADER_SIZE;
break;
}
- // child->dump();
el->addProperty(child);
tmpptr += amf_obj.totalsize();
};
-// tmpptr += AMF_HEADER_SIZE; // skip past the terminator
bytes
+// el->dump();
+ tmpptr += AMF_HEADER_SIZE; // skip past the terminator
bytes
break;
}
case Element::AMF3_DATA:
@@ -1211,7 +1202,7 @@
}
if (length + tmpptr > tooFar) {
- log_error("%d bytes for a string is over the safe limit of %d. Putting
the rest of the buffer into the string", length, SANE_STR_SIZE);
+ log_error("%d bytes for a string is over the safe limit of %d. Putting
the rest of the buffer into the string, line %d", length, SANE_STR_SIZE,
__LINE__);
length = tooFar - tmpptr;
}
@@ -1231,7 +1222,7 @@
if (type == Element::NULL_AMF0) {
log_debug("No data associated with Property \"%s\"", name);
el.reset(new Element);
- el->setName(name.c_str(), length);
+ el->setName(name.c_str(), name.size());
tmpptr += 1;
// Calculate the offset for the next read
} else {
@@ -1241,9 +1232,9 @@
// tmpptr += length;
el = extractAMF(tmpptr, tooFar);
if (el) {
- el->setName(name.c_str(), length);
- tmpptr += totalsize();
+ el->setName(name.c_str(), name.size()); // FIXME: arg, overwrites
the name for TypedObjects
}
+ tmpptr += totalsize();
}
//delete name;
=== modified file 'libamf/amf.h'
--- a/libamf/amf.h 2008-12-23 02:58:01 +0000
+++ b/libamf/amf.h 2009-02-04 21:17:43 +0000
@@ -70,11 +70,11 @@
/// for the following value is bogus. Although the length field is a short, it
/// seems silly to assume we'll ever see a string 65,000 characters long.
Still,
/// it makes sense to make this an adjustable thing.
-const int SANE_STR_SIZE = 1024;
+const int SANE_STR_SIZE = 65535;
/// Binary representation of an ActionScript object.
//
-/// AMF is used to send objects, wheather to a SharedObject .sol file,
+/// AMF is used to send objects, whether to a SharedObject .sol file,
/// a memory based LocalConnection segment, or over an RTMP connection
/// for streaming.
///
@@ -212,7 +212,7 @@
///
/// @return a binary AMF packet in big endian format (header,data)
///
- static boost::shared_ptr<Buffer> encodeReference(const boost::uint8_t
*data, size_t size);
+ static boost::shared_ptr<Buffer> encodeReference(boost::uint16_t index);
/// Encode a Movie Clip (swf data) to its serialized representation.
//
=== modified file 'libamf/buffer.cpp'
--- a/libamf/buffer.cpp 2008-12-23 02:57:22 +0000
+++ b/libamf/buffer.cpp 2009-02-17 03:18:15 +0000
@@ -22,6 +22,8 @@
#include <boost/cstdint.hpp>
#include <iostream>
+#include <boost/random/uniform_int.hpp>
+#include <boost/random/mersenne_twister.hpp>
#include "buffer.h"
#include "amf.h"
@@ -72,7 +74,7 @@
{
// GNASH_REPORT_FUNCTION;
size_t count = str.size();
- size_t size = (count/3) + 1;
+ size_t size = (count/3) + 4;
boost::uint8_t ch = 0;
boost::uint8_t *ptr = const_cast<boost::uint8_t *>(reinterpret_cast<const
boost::uint8_t *>(str.c_str()));
@@ -95,6 +97,25 @@
return *this;
}
+// Convert each byte into its hex representation
+std::string
+Buffer::hexify ()
+{
+ return gnash::hexify(_data.get(), allocated(), false);
+}
+
+std::string
+Buffer::hexify (bool ascii)
+{
+ return gnash::hexify(_data.get(), allocated(), ascii);
+}
+
+std::string
+Buffer::hexify (amf::Buffer &buf, bool ascii)
+{
+ return gnash::hexify(buf.reference(), buf.allocated(), ascii);
+}
+
/// \brief Initialize a block of memory for this buffer.
/// This should only be used internally by the Buffer
/// class.
@@ -179,11 +200,19 @@
Buffer::copy(boost::uint8_t *data, size_t nbytes)
{
// GNASH_REPORT_FUNCTION;
+ _seekptr =_data.get();
if (_data) {
std::copy(data, data + nbytes, _data.get());
_seekptr = _data.get() + nbytes;
} else {
- throw GnashException("Not enough storage was allocated to hold the
copied data!");
+ char num[12];
+ sprintf(num, "%d", nbytes);
+ string msg = "Not enough storage was allocated to hold the copied data!
Needs ";
+ msg += num;
+ msg += " only has ";
+ sprintf(num, "%d", _nbytes);
+ msg += num;
+ throw GnashException(msg);
}
return *this;
}
@@ -205,7 +234,14 @@
std::copy(data, data + nbytes, _seekptr);
_seekptr += nbytes;
} else {
- throw GnashException("Not enough storage was allocated to hold the
appended data!");
+ char num[12];
+ string msg = "Not enough storage was allocated to hold the appended
data! Needs ";
+ sprintf(num, "%d", nbytes);
+ msg += num;
+ msg += " only has ";
+ sprintf(num, "%d", _nbytes - allocated());
+ msg += num;
+ throw GnashException(msg);
}
}
@@ -468,6 +504,7 @@
Buffer::operator=(boost::uint8_t byte)
{
// GNASH__FUNCTION;
+
return copy(&byte, 1);
}
@@ -697,15 +734,53 @@
void
Buffer::dump(std::ostream& os) const
{
- os << "Buffer is " << _seekptr-_data.get() << "/" << _nbytes << " bytes at
" << (void *)_data.get() << endl;
+ os << "Buffer is " << _seekptr-_data.get() << "/" << _nbytes << " bytes: ";
+ // Skip in-memory address " at " << (void *)_data.get() << endl;
if (_nbytes < 0xffff) {
const size_t bytes = _seekptr - _data.get();
os << gnash::hexify((unsigned char *)_data.get(), bytes, false) << endl;
os << gnash::hexify((unsigned char *)_data.get(), bytes, true) << endl;
} else {
os << "ERROR: Buffer size out of range!" << endl;
- abort();
- }
+ }
+}
+
+/// \brief Corrupt a buffer with random errors.
+/// This is used only for testing to make sure we can cleanly
+/// handle corruption of the packets.
+///
+/// @param factor A divisor to adjust how many errors are created.
+///
+/// @return nothing
+int
+Buffer::corrupt()
+{
+ corrupt(10);
+}
+
+int
+Buffer::corrupt(int factor)
+{
+ boost::mt19937 seed;
+ // Pick the number of errors to create based on the Buffer's data size
+ boost::uniform_int<> errs(1, (_nbytes/factor));
+ int errors = errs(seed);
+ log_debug("Creating %d errors in the buffer", errors);
+
+ for (int i=0; i<errors; i++) {
+ // find a location someplace within the file.
+ boost::uniform_int<> location(0, _nbytes);
+ int pos = location(seed);
+
+// log_debug("Creating error at %d in the buffer", pos);
+ // Create a random new value for the byte
+ boost::uniform_int<> shift(1, 256);
+ int newval = shift(seed);
+ // stomp the old value for our new one.
+ _data[pos] = newval;
+ }
+
+ return errors;
}
} // end of amf namespace
=== modified file 'libamf/buffer.h'
--- a/libamf/buffer.h 2008-12-20 17:11:55 +0000
+++ b/libamf/buffer.h 2009-01-01 19:00:41 +0000
@@ -70,6 +70,16 @@
/// Delete the memory allocated for this Buffer
~Buffer();
+ /// \brief Corrupt a buffer with random errors.
+ /// This is used only for testing to make sure we can
cleanly
+ /// handle corruption of the packets.
+ ///
+ /// @param factor A divisor to adjust how many errors are created.
+ ///
+ /// @return The number or errors that were created.
+ int corrupt();
+ int corrupt(int factor);
+
/// \brief Encode a Buffer from a hex string.
///
/// @param str A hex string.
@@ -79,6 +89,21 @@
/// primary used only for testing to create binary data
/// from an easy to read and edit format.
Buffer &hex2mem(const std::string &str);
+
+ /// \brief Output a debug version of the Buffer's data.
+ /// This just calls the gnash::Logfile::hexify(), but is
+ /// more convienient as we don't have to extract the pointer
+ /// and the byte count to hexify() a Buffer.
+ ///
+ /// @param ascii True if ASCII characters should be printed, false
+ /// if only hex is desired.
+ ///
+ /// @param buf The buffer to hexify().
+ ///
+ /// @return A string of the debug output
+ std::string hexify();
+ std::string hexify(bool ascii);
+ std::string hexify(Buffer &buf, bool ascii);
/// \brief Clear the contents of the buffer by setting all the bytes to
/// zeros.
=== modified file 'libamf/element.cpp'
--- a/libamf/element.cpp 2008-12-23 02:56:29 +0000
+++ b/libamf/element.cpp 2009-02-11 09:27:20 +0000
@@ -171,7 +171,8 @@
Element::Element(bool /* flag */, double /* unknown1 */, double /* unknown2 */,
const string &/* methodname */)
: _name(0),
- _type(NOTYPE)
+ _type(NOTYPE),
+ _referenceid(0)
{
// GNASH_REPORT_FUNCTION;
log_unimpl("Can't create remote function calls yet");
@@ -249,6 +250,34 @@
return -1.0;
}
+/// \brief Cast the data in this Element to a short value.
+///
+/// @return short value.
+boost::uint16_t
+Element::to_short() const
+{
+// GNASH_REPORT_FUNCTION;
+ if (_buffer) {
+ return *(reinterpret_cast<boost::uint16_t *>(_buffer->reference()));
+ }
+// return ::nan("NaN");
+ return -1;
+}
+
+/// \brief Cast the data in this Element to a short value.
+///
+/// @return short value.
+boost::uint32_t
+Element::to_integer() const
+{
+// GNASH_REPORT_FUNCTION;
+ if (_buffer) {
+ return *(reinterpret_cast<boost::uint32_t *>(_buffer->reference()));
+ }
+// return ::nan("NaN");
+ return -1;
+}
+
/// \brief Cast the data in this Element to an ASCII string value.
///
/// @return A NULL terminated ASCII string.
@@ -258,14 +287,7 @@
// GNASH_REPORT_FUNCTION;
if (_buffer) {
if (_buffer->size() > 0) {
-#if 0
- char *foo = new char[_buffer->size() + 1];
- memset(foo, 0, _buffer->size() + 1);
- memcpy(foo, _buffer->reference(), _buffer->size());
- return foo;
-#else
return reinterpret_cast<const char *>(_buffer->reference());
-#endif
}
return "NULL";
}
@@ -435,6 +457,14 @@
Element::encode()
{
// GNASH_REPORT_FUNCTION;
+
+ return encode(false);
+}
+
+boost::shared_ptr<Buffer>
+Element::encode(bool notobject)
+{
+// GNASH_REPORT_FUNCTION;
size_t size = 0;
boost::shared_ptr<Buffer> buf;
if (_type == Element::OBJECT_AMF0) {
@@ -445,8 +475,10 @@
size += _properties[i]->getNameSize();
size += AMF_PROP_HEADER_SIZE;
}
- buf.reset(new Buffer(size+1)); // FIXME: why are we one byte off ?
- *buf = Element::OBJECT_AMF0;
+ buf.reset(new Buffer(size+24)); // FIXME: why are we several bytes off ?
+ if (!notobject) {
+ *buf = Element::OBJECT_AMF0;
+ }
if (_name > 0) {
size_t length = getNameSize();
boost::uint16_t enclength = length;
@@ -471,10 +503,12 @@
}
}
// log_debug("FIXME: Terminating object");
- boost::uint8_t pad = 0;
- *buf += pad;
- *buf += pad;
- *buf += TERMINATOR;
+ if (!notobject) {
+ boost::uint8_t pad = 0;
+ *buf += pad;
+ *buf += pad;
+ *buf += TERMINATOR;
+ }
return buf;
} else {
return AMF::encodeElement(*this);
@@ -576,12 +610,19 @@
// GNASH_REPORT_FUNCTION;
_type = Element::STRING_AMF0;
- // Make room for an additional NULL terminator
- try {
- check_buffer(size+1);
- } catch (std::exception& e) {
- log_error("%s", e.what());
- return *this;
+ // If there is an existing string,
+ if (_buffer) {
+ if (_buffer->size() < size) {
+ _buffer->resize(size+1); // add room for the NULL terminator
+ }
+ } else {
+ // Make room for an additional NULL terminator
+ try {
+ check_buffer(size+1);
+ } catch (std::exception& e) {
+ log_error("%s", e.what());
+ return *this;
+ }
}
_buffer->clear(); // FIXME: this could be a performance issue
_buffer->copy(data, size);
@@ -945,7 +986,7 @@
return *this;
}
Element &
-Element::makeXMLObject(boost::uint8_t *data)
+Element::makeXMLObject(boost::uint8_t * /*data*/)
{
// GNASH_REPORT_FUNCTION;
_type = Element::XML_OBJECT_AMF0;
@@ -1028,7 +1069,7 @@
///
/// @return A reference to this Element.
Element &
-Element::makeTypedObject(boost::uint8_t *data)
+Element::makeTypedObject(boost::uint8_t */*data*/)
{
// GNASH_REPORT_FUNCTION;
_type = Element::TYPED_OBJECT_AMF0;
@@ -1045,6 +1086,16 @@
{
// GNASH_REPORT_FUNCTION;
_type = Element::REFERENCE_AMF0;
+}
+
+Element &
+Element::makeReference(boost::uint16_t index)
+{
+// GNASH_REPORT_FUNCTION;
+ _type = Element::REFERENCE_AMF0;
+ boost::uint8_t *ptr = reinterpret_cast<boost::uint8_t *>(&index);
+ return makeReference(ptr, sizeof(boost::uint16_t));
+
return *this;
}
@@ -1426,6 +1477,9 @@
if (_buffer->size() < size) {
throw ParserException("Buffer not big enough, try resizing!");
}
+ if (_buffer->size() == 0) {
+ throw ParserException("Buffer has zero size, not initialized!");
+ }
}
}
@@ -1438,11 +1492,11 @@
os << astype_str[_type] << ": ";
if (_name) {
- os << " property name is: " << _name << ", ";
+ os << " property name is: \"" << _name << "\", ";
} else {
- os << "(no name)";
+ os << "(no name), ";
}
- os << endl << "data length is " << getDataSize() << endl;
+ os << "data length is " << getDataSize() << endl;
switch (_type) {
=== modified file 'libamf/element.h'
--- a/libamf/element.h 2008-12-23 02:56:29 +0000
+++ b/libamf/element.h 2009-02-17 01:00:08 +0000
@@ -472,6 +472,7 @@
///
/// @return A reference to this Element.
Element &makeReference();
+ Element &makeReference(boost::uint16_t index);
/// \brief Make this Element a Property with an Object Reference as the
value.
///
@@ -621,6 +622,16 @@
/// @return double value.
double to_number() const;
+ /// \brief Cast the data in this Element to a short (2 bytes) value.
+ ///
+ /// @return short (2 bytes) value.
+ boost::uint16_t to_short() const;
+
+ /// \brief Cast the data in this Element to an integer (4 bytes) value.
+ ///
+ /// @return integer (4 bytes) value.
+ boost::uint32_t to_integer() const;
+
/// \brief Cast the data in this Element to an ASCII string value.
///
/// @return A NULL terminated ASCII string.
@@ -692,6 +703,8 @@
/// @return nothing.
void addProperty(boost::shared_ptr<Element> el) {
_properties.push_back(el); };
+ void clearProperties() { return _properties.clear(); };
+
/// \brief Get a smart pointer to the Element for this Property.
///
/// @return A smart pointer to the Element for this Property
@@ -711,8 +724,13 @@
/// This encodes this Element and all of it's associated
/// properties into raw binary data in big endoan format.
///
+ /// @param notobject Flag to not encode the element as an object,
+ /// instead it's just a list of properties. This is used
when
+ /// formatting onStatus response packets.
+ ///
/// @return a smart pointer to a Buffer class.
boost::shared_ptr<Buffer> encode();
+ boost::shared_ptr<Buffer> encode(bool notobject);
/// \brief Get the array of properties for this Element.
///
=== modified file 'libamf/flv.cpp'
--- a/libamf/flv.cpp 2008-12-20 17:11:55 +0000
+++ b/libamf/flv.cpp 2009-02-04 21:18:29 +0000
@@ -353,6 +353,8 @@
log_debug("FLV MetaData: %s: %s", el->getName(),
el->to_string());
}
}
+ } else {
+ cerr << "No properties" << endl;
}
}
=== modified file 'libnet/Makefile.am'
--- a/libnet/Makefile.am 2008-11-13 01:15:09 +0000
+++ b/libnet/Makefile.am 2008-12-30 22:39:46 +0000
@@ -55,7 +55,6 @@
rtmp.h \
rtmp_msg.h \
rtmp_client.h \
- rtmp_server.h \
statistics.h \
diskstream.h \
cache.h
@@ -70,7 +69,6 @@
rtmp.cpp \
rtmp_msg.cpp \
rtmp_client.cpp \
- rtmp_server.cpp \
statistics.cpp \
diskstream.cpp \
cache.cpp
=== modified file 'libnet/cache.h'
--- a/libnet/cache.h 2008-11-20 20:58:49 +0000
+++ b/libnet/cache.h 2009-02-14 22:42:54 +0000
@@ -36,6 +36,9 @@
/// This is the main namespace for Gnash and it's libraries.
namespace gnash {
+// max size of files to map enirely into the cache
+static const size_t CACHE_LIMIT = 102400000;
+
// forward instatiate
//class DiskStream;
=== modified file 'libnet/diskstream.cpp'
--- a/libnet/diskstream.cpp 2008-12-01 15:43:33 +0000
+++ b/libnet/diskstream.cpp 2009-01-31 06:24:01 +0000
@@ -463,6 +463,7 @@
(long long int) _filesize);
} else {
log_error (_("File %s doesn't exist"), _filespec);
+ return false;
}
#ifdef USE_STATS_CACHE
@@ -694,6 +695,7 @@
}
} else {
_filetype = FILETYPE_NONE;
+ return false;
} // end of stat()
_filesize = st.st_size;
=== modified file 'libnet/handler.cpp'
--- a/libnet/handler.cpp 2008-12-20 17:11:55 +0000
+++ b/libnet/handler.cpp 2008-12-30 22:39:46 +0000
@@ -38,7 +38,6 @@
#include "dsodefs.h" //For DSOEXPORT.
#include "rtmp.h"
-#include "rtmp_server.h"
#include "http.h"
using namespace gnash;
=== modified file 'libnet/http.cpp'
--- a/libnet/http.cpp 2009-01-26 10:04:57 +0000
+++ b/libnet/http.cpp 2009-02-17 01:02:00 +0000
@@ -79,9 +79,6 @@
// FIXME, this seems too small to me. --gnu
static const int readsize = 1024;
-// max size of files to map enirely into the cache
-static const size_t CACHE_LIMIT = 102400000;
-
static Cache& cache = Cache::getDefaultInstance();
HTTP::HTTP()
@@ -144,46 +141,46 @@
HTTP::processClientRequest(int fd)
{
// GNASH_REPORT_FUNCTION;
- bool result = false;
+ bool result;
boost::shared_ptr<amf::Buffer> buf(_que.peek());
if (buf) {
- _cmd = extractCommand(buf->reference());
- switch (_cmd) {
- case HTTP::HTTP_GET:
- result = processGetRequest(fd);
- break;
- case HTTP::HTTP_POST:
- result = processPostRequest(fd);
- break;
- case HTTP::HTTP_HEAD:
- result = processHeadRequest(fd);
- break;
- case HTTP::HTTP_CONNECT:
- result = processConnectRequest(fd);
- break;
- case HTTP::HTTP_TRACE:
- result = processTraceRequest(fd);
- break;
- case HTTP::HTTP_OPTIONS:
- result = processOptionsRequest(fd);
- break;
- case HTTP::HTTP_PUT:
- result = processPutRequest(fd);
- break;
- case HTTP::HTTP_DELETE:
- result = processDeleteRequest(fd);
- break;
- default:
- break;
- }
+ _cmd = extractCommand(buf->reference());
+ switch (_cmd) {
+ case HTTP::HTTP_GET:
+ result = processGetRequest(fd);
+ break;
+ case HTTP::HTTP_POST:
+ result = processPostRequest(fd);
+ break;
+ case HTTP::HTTP_HEAD:
+ result = processHeadRequest(fd);
+ break;
+ case HTTP::HTTP_CONNECT:
+ result = processConnectRequest(fd);
+ break;
+ case HTTP::HTTP_TRACE:
+ result = processTraceRequest(fd);
+ break;
+ case HTTP::HTTP_OPTIONS:
+ result = processOptionsRequest(fd);
+ break;
+ case HTTP::HTTP_PUT:
+ result = processPutRequest(fd);
+ break;
+ case HTTP::HTTP_DELETE:
+ result = processDeleteRequest(fd);
+ break;
+ default:
+ break;
+ }
}
if (result) {
- return _cmd;
+ return _cmd;
} else {
- return HTTP::HTTP_NONE;
- }
+ return HTTP::HTTP_NONE;
+ }
}
// A GET request asks the server to send a file to the client
@@ -229,14 +226,16 @@
// cache.addFile(url, filestream); FIXME: always reload from disk
for now.
- // Oopen the file and read the furst chunk into memory
- filestream->open(url);
-
- // Get the file size for the HTTP header
- if (filestream->getFileType() == DiskStream::FILETYPE_NONE) {
+ // Oopen the file and read the first chunk into memory
+ if (filestream->open(url)) {
formatErrorResponse(HTTP::NOT_FOUND);
} else {
- cache.addPath(_filespec, filestream->getFilespec());
+ // Get the file size for the HTTP header
+ if (filestream->getFileType() == DiskStream::FILETYPE_NONE) {
+ formatErrorResponse(HTTP::NOT_FOUND);
+ } else {
+ cache.addPath(_filespec, filestream->getFilespec());
+ }
}
}
@@ -561,9 +560,11 @@
const boost::uint8_t *cmd = reinterpret_cast<const boost::uint8_t
*>(i->c_str());
if (extractCommand(const_cast<boost::uint8_t *>(cmd)) ==
HTTP::HTTP_NONE) {
break;
+#if 1
} else {
- log_debug("Got a request, parsing \"%s\"", *i);
+ log_debug("Got a request, parsing \"%s\"", *i);
string::size_type start = i->find(" ");
+ string::size_type params = i->find("?");
string::size_type pos = i->find("HTTP/");
if (pos != string::npos) {
// The version is the last field and is the protocol name
@@ -575,7 +576,13 @@
log_debug (_("Version: %d.%d"), _version.major,
_version.minor);
// the filespec in the request is the middle field,
deliminated
// by a space on each end.
- _filespec = i->substr(start+1, pos-start-2);
+ if (params != string::npos) {
+ _params = i->substr(params+1, end);
+ _filespec = i->substr(start+1, params);
+ log_debug("Parameters for file: \"%s\"", _params);
+ } else {
+ _filespec = i->substr(start+1, pos-start-2);
+ }
log_debug("Requesting file: \"%s\"", _filespec);
// HTTP 1.1 enables persistant network connections
@@ -586,6 +593,7 @@
}
}
}
+#endif
}
}
@@ -1107,6 +1115,16 @@
// Get the first name, which is a raw string, and not preceded by
// a type byte.
boost::shared_ptr<amf::Element > el1(new amf::Element);
+
+ // If the length of the name field is corrupted, then we get out of
+ // range quick, and corrupt memory. This is a bit of a hack, but
+ // reduces memory errors caused by some of the corrupted tes cases.
+ boost::uint8_t *endstr = std::find(tmpptr, tmpptr+length, '\0');
+ if (endstr != tmpptr+length) {
+ log_debug("Caught corrupted string! length was %d, null at %d",
+ length, endstr-tmpptr);
+ length = endstr-tmpptr;
+ }
el1->setName(tmpptr, length);
tmpptr += length;
headers.push_back(el1);
@@ -1116,6 +1134,18 @@
length = ntohs((*(boost::uint16_t *)tmpptr) & 0xffff);
tmpptr += sizeof(boost::uint16_t);
boost::shared_ptr<amf::Element > el2(new amf::Element);
+
+// std::string name2(reinterpret_cast<const char *>(tmpptr), length);
+// el2->setName(name2.c_str(), name2.size());
+ // If the length of the name field is corrupted, then we get out of
+ // range quick, and corrupt memory. This is a bit of a hack, but
+ // reduces memory errors caused by some of the corrupted tes cases.
+ endstr = std::find(tmpptr, tmpptr+length, '\0');
+ if (endstr != tmpptr+length) {
+ log_debug("Caught corrupted string! length was %d, null at %d",
+ length, endstr-tmpptr);
+ length = endstr-tmpptr;
+ }
el2->setName(tmpptr, length);
headers.push_back(el2);
tmpptr += length;
@@ -1140,7 +1170,28 @@
HTTP::formatEchoResponse(const std::string &num, amf::Element &el)
{
// GNASH_REPORT_FUNCTION;
- boost::shared_ptr<amf::Buffer> data = el.encode(); //
amf::AMF::encodeElement(el);
+ boost::shared_ptr<amf::Buffer> data;
+
+ amf::Element nel;
+ if (el.getType() == amf::Element::TYPED_OBJECT_AMF0) {
+ nel.makeTypedObject();
+ string name = el.getName();
+ nel.setName(name);
+ if (el.propertySize()) {
+ // FIXME: see about using std::reverse() instead.
+ for (int i=el.propertySize()-1; i>=0; i--) {
+// for (int i=0 ; i<el.propertySize(); i++) {
+ boost::shared_ptr<amf::Element> child = el.getProperty(i);
+ nel.addProperty(child);
+ }
+ data = nel.encode();
+ } else {
+ data = el.encode();
+ }
+ } else {
+ data = el.encode();
+ }
+
return formatEchoResponse(num, data->reference(), data->allocated());
}
@@ -1302,7 +1353,7 @@
HTTP::http_method_e
HTTP::extractCommand(boost::uint8_t *data)
{
-// GNASH_REPORT_FUNCTION;
+ GNASH_REPORT_FUNCTION;
// string body = reinterpret_cast<const char *>(data);
HTTP::http_method_e cmd = HTTP::HTTP_NONE;
@@ -1335,11 +1386,27 @@
if (cmd != HTTP::HTTP_NONE) {
boost::uint8_t *start = std::find(data, data+7, ' ') + 1;
boost::uint8_t *end = std::find(start + 2, data+PATH_MAX, ' ');
-
- // This is fine as long as end is within the buffer.
- _filespec = std::string(start, end);
+ boost::uint8_t *params = std::find(start, end, '?');
+ if (params != end) {
+ _params = std::string(params+1, end);
+ _filespec = std::string(start, params);
+ log_debug("Parameters for file: \"%s\"", _params);
+ } else {
+ // This is fine as long as end is within the buffer.
+ _filespec = std::string(start, end);
+ }
+ log_debug("Requesting file: \"%s\"", _filespec);
+
+ // The third field is always the HTTP version
+ // The version is the last field and is the protocol name
+ // followed by a slash, and the version number. Note that
+ // the version is not a double, even though it has a dot
+ // in it. It's actually two separate integers.
+ _version.major = *(end+6) - '0';
+ _version.minor = *(end+8) - '0';
+ log_debug (_("Version: %d.%d"), _version.major, _version.minor);
}
-
+
return cmd;
}
@@ -1490,7 +1557,7 @@
log_debug("Starting to wait for data in net for fd #%d", args->netfd);
// Wait for data, and when we get it, process it.
-// do {
+ do {
#ifdef USE_STATISTICS
struct timespec start;
@@ -1507,8 +1574,7 @@
// hand->die(); // tell all the threads for this connection to
die
// hand->notifyin();
log_debug("Net HTTP done for fd #%d...", args->netfd);
-// hand->closeNet(args->netfd);
- done = true;
+// done = true;
}
// www.dump();
@@ -1535,7 +1601,7 @@
} else {
log_debug("Keep-Alive is on", www->keepAlive());
result = true;
- done = true;
+// done = true;
}
#ifdef USE_STATISTICS
struct timespec end;
@@ -1543,7 +1609,7 @@
log_debug("Processing time for GET request was %f seconds",
(float)((end.tv_sec - start.tv_sec) + ((end.tv_nsec -
start.tv_nsec)/1e9)));
#endif
-// } while(done != true);
+ } while(done != true);
// hand->notify();
=== modified file 'libnet/http.h'
--- a/libnet/http.h 2008-12-20 17:11:55 +0000
+++ b/libnet/http.h 2009-01-18 06:58:20 +0000
@@ -292,6 +292,7 @@
int getMaxRequests() { return _max_requests; }
int getFileSize() { return _filesize; }
std::string &getFilespec() { return _filespec; }
+ std::string &getParams() { return _params; }
// std::string &getURL() { return _url; }
std::map<int, struct status_codes *> getStatusCodes()
{ return _status_codes; }
@@ -310,6 +311,7 @@
DiskStream::filetype_e _filetype;
std::string _filespec;
+ std::string _params;
boost::uint32_t _filesize;
std::map<int, struct status_codes *> _status_codes;
=== modified file 'libnet/network.cpp'
--- a/libnet/network.cpp 2008-12-18 00:47:19 +0000
+++ b/libnet/network.cpp 2008-12-30 21:06:48 +0000
@@ -905,10 +905,18 @@
}
ret = read(fd, buffer, nbytes);
- // If we read zero bytes, the network is closed, as we returned from
the select()
- if (ret == 0) {
- return -1;
- }
+ // If we read zero bytes, the network may be closed, as we returned
from the select()
+ if (ret == -1) {
+ log_error (_("The socket for fd #%d was never available for
reading data"), fd);
+ return -1;
+ }
+
+ if (ret == 0) {
+ if (_debug) {
+ log_debug (_("The socket for #fd %d timed out waiting to read
data"), fd);
+ }
+ return 0;
+ }
if (_debug) {
log_debug (_("read %d bytes from fd #%d from port %d"), ret, fd,
_port);
=== modified file 'libnet/rtmp.cpp'
--- a/libnet/rtmp.cpp 2008-12-20 17:11:55 +0000
+++ b/libnet/rtmp.cpp 2009-02-14 22:42:54 +0000
@@ -25,6 +25,7 @@
#include <string>
#include <map>
#include <vector>
+#include <cerrno>
#include <boost/detail/endian.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/format.hpp>
@@ -196,6 +197,7 @@
// each channel can have a different chunksize
_chunksize[i] = RTMP_VIDEO_PACKET_SIZE;
+ _lastsize[i] = 0;
}
}
@@ -210,58 +212,64 @@
}
void
-RTMP::addProperty(boost::shared_ptr<amf::Element> el)
+RTMP::addProperty(amf::Element &el)
{
// GNASH_REPORT_FUNCTION;
- _properties[el->getName()] = el;
+ _properties[el.getName()] = el;
}
void
-RTMP::addProperty(char *name, boost::shared_ptr<amf::Element> el)
+RTMP::addProperty(char *name, amf::Element &el)
{
// GNASH_REPORT_FUNCTION;
_properties[name] = el;
}
-boost::shared_ptr<amf::Element>
+amf::Element &
RTMP::getProperty(const std::string &name)
{
// GNASH_REPORT_FUNCTION;
// return _properties[name.c_str()];
- map<const char *, boost::shared_ptr<amf::Element> >::iterator it;
+ map<const char *, amf::Element>::iterator it;
for (it = _properties.begin(); it != _properties.end(); it++) {
const char *title = it->first;
- boost::shared_ptr<amf::Element> el = it->second;
+ amf::Element &el = it->second;
if (name == title) {
// log_debug("found variable in RTMP packet: %s", name);
return el;
}
}
- boost::shared_ptr<amf::Element> el;
- return el;
}
-RTMP::rtmp_head_t *
-RTMP::decodeHeader(boost::shared_ptr<amf::Buffer> buf)
+boost::shared_ptr<RTMP::rtmp_head_t>
+RTMP::decodeHeader(amf::Buffer &buf)
{
// GNASH_REPORT_FUNCTION;
- return decodeHeader(buf->reference());
+ return decodeHeader(buf.reference());
}
-RTMP::rtmp_head_t *
+boost::shared_ptr<RTMP::rtmp_head_t>
RTMP::decodeHeader(boost::uint8_t *in)
{
- GNASH_REPORT_FUNCTION;
-
+// GNASH_REPORT_FUNCTION;
+
+ boost::shared_ptr<RTMP::rtmp_head_t> head(new RTMP::rtmp_head_t);
boost::uint8_t *tmpptr = in;
-
- _header.channel = *tmpptr & RTMP_INDEX_MASK;
- log_debug (_("The AMF channel index is %d"), _header.channel);
-
- _header.head_size = headerSize(*tmpptr++);
- log_debug (_("The header size is %d"), _header.head_size);
-
- if (_header.head_size >= 4) {
+
+ head->channel = *tmpptr & RTMP_INDEX_MASK;
+ log_debug (_("The AMF channel index is %d"), head->channel);
+
+ head->head_size = headerSize(*tmpptr++);
+ log_debug (_("The header size is %d"), head->head_size);
+
+ if (head->head_size > RTMP_MAX_HEADER_SIZE) {
+ head.reset();
+ return head;
+ }
+
+// cerr << "FIXME3: " << hexify(in, head->head_size, false) << endl;
+
+ if (head->head_size >= 4) {
_mystery_word = *tmpptr++;
_mystery_word = (_mystery_word << 8) + *tmpptr++;
_mystery_word = (_mystery_word << 8) + *tmpptr++;
@@ -269,36 +277,36 @@
log_debug(_("The mystery word is: %d"), _mystery_word);
}
- if (_header.head_size >= 8) {
- _header.bodysize = *tmpptr++;
- _header.bodysize = (_header.bodysize << 8) + *tmpptr++;
- _header.bodysize = (_header.bodysize << 8) + *tmpptr++;
- _header.bodysize = _header.bodysize & 0xffffff;
- log_debug(_("The body size is: %d"), _header.bodysize);
+ if (head->head_size >= 8) {
+ head->bodysize = *tmpptr++;
+ head->bodysize = (head->bodysize << 8) + *tmpptr++;
+ head->bodysize = (head->bodysize << 8) + *tmpptr++;
+ head->bodysize = head->bodysize & 0xffffff;
+ log_debug(_("The body size is: %d"), head->bodysize);
}
- if (_header.head_size >= 8) {
+ if (head->head_size >= 8) {
boost::uint8_t byte = *tmpptr;
- _header.type = (content_types_e)byte;
+ head->type = (content_types_e)byte;
tmpptr++;
- if (_header.type <= RTMP::INVOKE ) {
- log_debug(_("The type is: %s"), content_str[_header.type]);
+ if (head->type <= RTMP::INVOKE ) {
+ log_debug(_("The type is: %s"), content_str[head->type]);
} else {
- log_debug(_("The type is: 0x%x"), _header.type);
+ log_debug(_("The type is: 0x%x"), head->type);
}
}
- if (_header.head_size == 1) {
- if (_header.channel == RTMP_SYSTEM_CHANNEL) {
- _header.bodysize = sizeof(boost::uint16_t) * 3;
- log_debug("Got a one byte header system message: %s", hexify(in,
_header.bodysize, false));
+ if (head->head_size == 1) {
+ if (head->channel == RTMP_SYSTEM_CHANNEL) {
+ head->bodysize = sizeof(boost::uint16_t) * 3;
+ log_debug("Got a one byte header system message: %s", hexify(in,
head->bodysize, false));
} else {
- log_debug("Got a continuation packet for channel #%d",
_header.channel);
- _header.bodysize = 0;
+ log_debug("Got a continuation packet for channel #%d",
head->channel);
+ head->bodysize = 0;
}
}
-// switch(_header.type) {
+// switch(head->type) {
// case CHUNK_SIZE:
// case BYTES_READ:
// case PING:
@@ -318,13 +326,14 @@
// break;
// };
- if (_header.head_size == 12) {
- _header.src_dest = *(reinterpret_cast<RTMPMsg::rtmp_source_e
*>(tmpptr));
+ if (head->head_size == 12) {
+ head->src_dest = *(reinterpret_cast<RTMPMsg::rtmp_source_e *>(tmpptr));
tmpptr += sizeof(unsigned int);
- log_debug(_("The source/destination is: %x"), _header.src_dest);
+ log_debug(_("The source/destination is: %x"), head->src_dest);
}
- return &_header;
+ return head;
+
}
/// \brief \ Each RTMP header consists of the following:
@@ -355,7 +364,7 @@
size_t total_size, content_types_e type,
RTMPMsg::rtmp_source_e routing)
{
- GNASH_REPORT_FUNCTION;
+// GNASH_REPORT_FUNCTION;
boost::shared_ptr<amf::Buffer> buf;
switch(head_size) {
@@ -372,9 +381,6 @@
buf.reset(new Buffer(12));
break;
}
-
-// FIXME: this is only to make this more readeable with GDB, and is a
performance hit.
- buf->clear();
boost::uint8_t *ptr = buf->reference();
// Make the channel index & header size byte
@@ -409,39 +415,47 @@
ptr += 4;
}
+ // Manually adjust the seek pointer since we added the data by
+ // walking ou own temporary pointer, so none of the regular ways
+ // of setting the seek pointer are appropriate.
+ buf->setSeekPointer(buf->reference() + buf->size());
+
return buf;
}
+#if 0
bool
-RTMP::packetRead(boost::shared_ptr<amf::Buffer> buf)
+RTMP::packetRead(amf::Buffer &buf)
{
GNASH_REPORT_FUNCTION;
// int packetsize = 0;
size_t amf_index, headersize;
- boost::uint8_t *ptr = buf->reference();
- boost::uint8_t *tooFar = ptr+buf->size();
+ boost::uint8_t *ptr = buf.reference();
+ boost::uint8_t *tooFar = ptr+buf.size();
AMF amf;
+
+ ptr += 1; // skip past the RTMP header byte
- amf_index = *buf->reference() & RTMP_INDEX_MASK;
- headersize = headerSize(*buf->reference());
+ amf_index = *ptr & RTMP_INDEX_MASK;
+ headersize = headerSize(*buf.reference());
log_debug (_("The Header size is: %d"), headersize);
log_debug (_("The AMF index is: 0x%x"), amf_index);
-// if (headersize > 1) {
-// packetsize = decodeHeader(ptr);
+ if (headersize > 1) {
+ RTMP::rtmp_head_t *rthead = decodeHeader(ptr);
// if (packetsize) {
// log_debug (_("Read first RTMP packet header of size %d"),
packetsize);
// } else {
// log_error (_("Couldn't read first RTMP packet header"));
// return false;
// }
-// }
+ }
#if 1
- boost::uint8_t *end = buf->remove(0xc3);
+ boost::uint8_t *end = buf.remove(0xc3);
#else
- boost::uint8_t *end = buf->find(0xc3);
+ boost::uint8_t *end = buf.find(0xc3);
log_debug("END is %x", (void *)end);
*end = '*';
#endif
@@ -462,13 +476,13 @@
}
ptr += 1;
size_t actual_size = static_cast<size_t>(_header.bodysize -
AMF_HEADER_SIZE);
- log_debug("Total size in header is %d, buffer size is: %d",
_header.bodysize, buf->size());
+ log_debug("Total size in header is %d, buffer size is: %d",
_header.bodysize, buf.size());
// buf->dump();
- if (buf->size() < actual_size) {
+ if (buf.size() < actual_size) {
log_debug("FIXME: MERGING");
// buf = _handler->merge(buf); FIXME needs to use shared_ptr
}
- while ((ptr - buf->begin()) < static_cast<int>(actual_size)) {
+ while ((ptr - buf.begin()) < static_cast<int>(actual_size)) {
boost::shared_ptr<amf::Element> el = amf.extractProperty(ptr, tooFar);
addProperty(el);
// el->dump(); // FIXME: dump the AMF objects as they are read
in
@@ -492,20 +506,21 @@
return true;
}
+#endif
void
RTMP::dump()
{
cerr << "RTMP packet contains " << _properties.size() << " variables." <<
endl;
- map<const char *, boost::shared_ptr<amf::Element> >::iterator it;
+ map<const char *, amf::Element>::iterator it;
for (it = _properties.begin(); it != _properties.end(); it++) {
// const char *name = it->first;
- boost::shared_ptr<amf::Element> el = it->second;
- el->dump();
+ amf::Element el = it->second;
+ el.dump();
}
}
-// A Ping packet has two parameters that ae always specified, and 2 that are
optional.
+// A Ping packet has two parameters that are always specified, and 2 that are
optional.
// The first two bytes are the ping type, as in rtmp_ping_e, the second is the
ping
// target, which is always zero as far as we can tell.
//
@@ -527,14 +542,13 @@
// two paramters are required.
// This seems to be a ping message, 12 byte header, system channel 2
// 02 00 00 00 00 00 06 04 00 00 00 00 00 00 00 00 00 00
-RTMP::rtmp_ping_t *
+boost::shared_ptr<RTMP::rtmp_ping_t>
RTMP::decodePing(boost::uint8_t *data)
{
- GNASH_REPORT_FUNCTION;
+// GNASH_REPORT_FUNCTION;
boost::uint8_t *ptr = reinterpret_cast<boost::uint8_t *>(data);
- rtmp_ping_t *ping = new rtmp_ping_t;
- memset(ping, 0, sizeof(rtmp_ping_t));
+ boost::shared_ptr<rtmp_ping_t> ping(new rtmp_ping_t);
// All the data fields in a ping message are 2 bytes long.
boost::uint16_t type = ntohs(*reinterpret_cast<boost::uint16_t *>(ptr));
@@ -555,11 +569,11 @@
return ping;
}
-RTMP::rtmp_ping_t *
-RTMP::decodePing(boost::shared_ptr<amf::Buffer> buf)
+boost::shared_ptr<RTMP::rtmp_ping_t>
+RTMP::decodePing(amf::Buffer &buf)
{
- GNASH_REPORT_FUNCTION;
- return decodePing(buf->reference());
+// GNASH_REPORT_FUNCTION;
+ return decodePing(buf.reference());
}
// Decode the result we get from the server after we've made a request.
@@ -611,7 +625,7 @@
// The first data object is the method name of this object.
boost::shared_ptr<amf::Element> name = amf_obj.extractAMF(ptr, tooFar);
if (name) {
- ptr += name->getDataSize() + 3; // skip the length bytes too
+ ptr += name->getDataSize() + AMF_HEADER_SIZE; // skip the length bytes
too
} else {
log_error("Name field of RTMP Message corrupted!");
return 0;
@@ -624,7 +638,7 @@
// Most onStatus messages have the stream ID, but the Data Start
onStatus
// message is basically just a marker that an FLV file is coming next.
if (streamid->getType() == Element::NUMBER_AMF0) {
- ptr += streamid->getDataSize() + 2;
+ ptr += AMF0_NUMBER_SIZE + 1;
}
} else {
log_error("Stream ID field of RTMP Message corrupted!");
@@ -636,7 +650,10 @@
RTMPMsg *msg = new RTMPMsg;
// memset(msg, 0, sizeof(RTMPMsg));
- msg->setMethodName(name->to_string());
+ if (name->to_string() != 0) {
+ msg->setMethodName(name->to_string());
+ }
+
double swapped = streamid->to_number();
// swapBytes(&swapped, amf::AMF0_NUMBER_SIZE);
msg->setStreamID(swapped);
@@ -654,21 +671,20 @@
if (el == 0) {
break;
}
-// el->dump();
msg->addObject(el);
if (status) {
msg->checkStatus(el);
}
- };
+ };
return msg;
}
RTMPMsg *
-RTMP::decodeMsgBody(boost::shared_ptr<amf::Buffer> buf)
+RTMP::decodeMsgBody(amf::Buffer &buf)
{
// GNASH_REPORT_FUNCTION;
- return decodeMsgBody(buf->reference(), buf->size());
+ return decodeMsgBody(buf.reference(), buf.allocated());
}
boost::shared_ptr<amf::Buffer>
@@ -807,42 +823,85 @@
// Send a message, usually a single ActionScript object. This message
// may be broken down into a series of packets on a regular byte
-// interval. (128 bytes for video data). Each message main contain
-// multiple packets.
+// interval. The byte boundary defaults to 128 bytes (video data), but can
+// be changed by the ChunkSize() command.
bool
-RTMP::sendMsg(boost::shared_ptr<amf::Buffer> data)
+RTMP::sendMsg(int fd, int channel, rtmp_headersize_e head_size,
+ size_t total_size, content_types_e type,
+ RTMPMsg::rtmp_source_e routing, amf::Buffer &data)
{
- GNASH_REPORT_FUNCTION;
+// GNASH_REPORT_FUNCTION;
+ return sendMsg(fd, channel, head_size, total_size, type, routing,
data.reference(), data.allocated());
+}
- size_t partial = RTMP_VIDEO_PACKET_SIZE;
+bool
+RTMP::sendMsg(int fd, int channel, rtmp_headersize_e head_size,
+ size_t total_size, content_types_e type,
+ RTMPMsg::rtmp_source_e routing, boost::uint8_t *data, size_t size)
+{
+// GNASH_REPORT_FUNCTION;
+ int ret = 0;
+
+ // We got some bogus parameters
+ if (total_size == 0) {
+ log_error("Bogus size parameter in %s!", __PRETTY_FUNCTION__);
+ return false;
+ }
+
+ // This builds the full header,which is required as the first part
+ // of the packet.
+ boost::shared_ptr<amf::Buffer> head = encodeHeader(channel, head_size,
total_size,
+ type, routing);
+ // When more data is sent than fits in the chunksize for this
+ // channel, it gets broken into chunksize pieces, and each piece
+ // after the first packet is sent gets a one byte header instead.
+ boost::shared_ptr<amf::Buffer> cont_head = encodeHeader(channel,
RTMP::HEADER_1);
+ size_t partial = _chunksize[channel];
size_t nbytes = 0;
- boost::uint8_t header = 0xc3;
-
- while (nbytes <= data->size()) {
- if ((data->size() - nbytes) < static_cast<signed
int>(RTMP_VIDEO_PACKET_SIZE)) {
- partial = data->size() - nbytes;
- }
- writeNet(data->reference() + nbytes, partial);
- if (partial == static_cast<signed int>(RTMP_VIDEO_PACKET_SIZE)) {
- writeNet(&header, 1);
- }
- nbytes += RTMP_VIDEO_PACKET_SIZE;
+
+ // First send the full header, afterwards we only use continuation
+ // headers, which are only one byte.
+ ret = writeNet(fd, head->reference(), head->size());
+ if (ret == -1) {
+ log_error("Couldn't write the RTMP header!");
+ return false;
+ }
+
+ // now send the data
+ while (nbytes <= size) {
+ // The last bit of data is usually less than the packet size,
+ // so we write less data of course.
+ if ((size - nbytes) < static_cast<signed int>(_chunksize[channel])) {
+ partial = size - nbytes;
+ }
+ // After the first packet, only send the single byte
+ // continuation packet.
+ if (nbytes > 0) {
+ int ret = writeNet(fd, *cont_head);
+ }
+ // write the data to the client
+ ret = writeNet(fd, data + nbytes, partial);
+ if (ret == -1) {
+ log_error("Couldn't write the RTMP body!");
+ return false;
+ }
+ // adjust the accumulator.
+ nbytes += _chunksize[channel];
};
return true;
}
-
+
+#if 0
// Send a Msg, and expect a response back of some kind.
RTMPMsg *
-RTMP::sendRecvMsg(int amf_index, rtmp_headersize_e head_size,
- size_t total_size, content_types_e type,
- RTMPMsg::rtmp_source_e routing,
boost::shared_ptr<amf::Buffer> bufin)
+RTMP::sendRecvMsg(amf::Buffer &bufin)
{
GNASH_REPORT_FUNCTION;
// size_t total_size = buf2->size() - 6; // FIXME: why drop 6 bytes ?
boost::shared_ptr<amf::Buffer> head = encodeHeader(amf_index, head_size,
total_size,
type, routing);
// int ret = 0;
- int ret = writeNet(head->reference(), head->size());
+ int ret = writeNet(head->reference(), head->size()); // send the header
first
// if (netDebug()) {
// head->dump();
// bufin->dump();
@@ -982,6 +1041,7 @@
return msg;
}
+#endif
// Receive a message, which is a series of AMF elements, seperated
// by a one byte header at regular byte intervals. (128 bytes for
@@ -989,8 +1049,8 @@
boost::shared_ptr<amf::Buffer>
RTMP::recvMsg()
{
- GNASH_REPORT_FUNCTION;
- return recvMsg(_timeout);
+// GNASH_REPORT_FUNCTION;
+ return recvMsg(getFileFd());
}
// Read big chunks of NETBUFSIZE, which is the default for a Buffer as it's
@@ -998,32 +1058,44 @@
// also include the RTMP header every _chunksize bytes, this raw data will
// need to be processed later on.
boost::shared_ptr<amf::Buffer>
-RTMP::recvMsg(int timeout)
+RTMP::recvMsg(int fd)
{
GNASH_REPORT_FUNCTION;
int ret = 0;
bool nopacket = true;
- boost::shared_ptr<amf::Buffer> buf(new Buffer(NETBUFSIZE));
- while (nopacket) {
- ret = readNet(buf->reference(), buf->size(), timeout);
- if (ret <= 0) {
- log_error("Never got any data at line %d", __LINE__);
- buf.reset(); // no point in returning a buffer, right?
- return buf;
+ // Read really big packets, they get split into the smaller ones when
'split'
+ boost::shared_ptr<amf::Buffer> buf(new Buffer(7096));
+ do {
+ ret = readNet(fd, buf->reference()+ret, buf->size()-ret, _timeout);
+// cerr << __PRETTY_FUNCTION__ << ": " << ret << endl;
+ // We got data. Resize the buffer if necessary.
+ if (ret > 0) {
+ buf->setSeekPointer(buf->reference() + ret);
}
+ // the read timed out as there was no data, but the socket is still
open.
+ if (ret == 0) {
+ log_debug("no data for fd #%d, done reading this packet...", fd);
+ break;
+ }
if ((ret == 1) && (*(buf->reference()) == 0xff)) {
log_debug("Got an empty packet from the server at line %d",
__LINE__);
continue;
}
- nopacket = false;
- }
- buf->resize(ret);
+ // ret is "no position" when the socket is closed from the other end of
the connection,
+ // so we're done.
+ if ((ret == static_cast<int>(string::npos)) || (ret == -1)) {
+ log_debug("socket for fd #%d was closed...", fd);
+ buf.reset();
+ break;
+ }
+ } while (ret <= 0);
+
// if (netDebug()) {
// buf->dump();
// }
-
+
return buf;
}
@@ -1033,44 +1105,75 @@
// but RTMP uses a weird scheme of a standard header, and then every chunksize
// bytes another 1 byte RTMP header. The header itself is not part of the byte
// count.
-RTMP::queues_t *
-RTMP::split(boost::shared_ptr<Buffer> buf)
-{
- GNASH_REPORT_FUNCTION;
-
- if (buf == 0) {
+boost::shared_ptr<RTMP::queues_t>
+RTMP::split(amf::Buffer &buf)
+{
+ GNASH_REPORT_FUNCTION;
+ return split(buf.reference(), buf.allocated());
+}
+
+boost::shared_ptr<RTMP::queues_t>
+RTMP::split(boost::uint8_t *data, size_t size)
+{
+ GNASH_REPORT_FUNCTION;
+
+ if (data == 0) {
log_error("Buffer pointer is invalid.");
}
-
+
+ boost::shared_ptr<RTMP::queues_t> channels(new RTMP::queues_t);
+
// split the buffer at the chunksize boundary
boost::uint8_t *ptr = 0;
- rtmp_head_t *rthead = 0;
+ boost::shared_ptr<rtmp_head_t> rthead(new rtmp_head_t);
size_t pktsize = 0;
size_t nbytes = 0;
- ptr = buf->reference();
+ ptr = data;
boost::shared_ptr<amf::Buffer> chunk;
- while ((ptr - buf->reference()) < buf->size()) {
+ // There may be multiple messages in this Buffer, so we walk a
+ // temp pointer through the contents of the Buffer.
+ while ((ptr - data) < static_cast<int>(size)) {
+ // Decode the header of the packet to get the header size, the
+ // body size, and the channel, all of which we need.
rthead = decodeHeader(ptr);
+ // System channel messages are always on channel 2, and get
+ // processed differently.
+ // FIXME: skip system messages for now!
if (rthead->channel == RTMP_SYSTEM_CHANNEL) {
- log_debug("Got a message on the system channel");
- ptr += rthead->head_size + rthead->bodysize;
- continue;
+ log_debug("FIXME: %s: Got a message on the system channel!",
__FUNCTION__);
+// ptr += rthead->head_size + rthead->bodysize;
+// continue;
}
- // Make sure the header size is in range
+ // Make sure the header size we just got is in range. We can
+ // proceed as long as it is in range, but if it is out of
+ // range, we can't really continue.
if (rthead->head_size <= RTMP_MAX_HEADER_SIZE) {
- // Any packet with a size greater than 1 is a new header, so create
- // a new Buffer to hold all the data.
+ // Any packet with a header size greater than 1 is a
+ // always a new RTMP message, so create a new Buffer to
+ // hold all the data.
+ if (rthead->head_size <= 4) {
+ rthead->bodysize = _lastsize[rthead->channel];
+ }
if ((rthead->head_size > 1)) {
cerr << "New packet for channel #" << rthead->channel << " of
size "
<< (rthead->head_size + rthead->bodysize) << endl;
+ // give it some memory to store data in. We store
chunk.reset(new Buffer(rthead->bodysize + rthead->head_size));
- chunk->clear(); // FIXME: temporary debug only, should be
unnecessary
+ // Each RTMP connection has 64 channels, so we store
+ // the header with the data so that info is accessible
+ // via the Buffer for processing later. All the data
+ // goes in a queue for each channel.
_queues[rthead->channel].push(chunk);
+// rthead->head_size == 4
} else {
- // Use the existing Buffer for this pkt
+ // Use the existing Buffer for this packet, as it's a
+ // continuation messages for an existing packet. Leave
+ // the message in the queue, we just want access to
+ // the Buffer.
chunk = _queues[rthead->channel].peek();
}
+#if 1
// Red5 version 5 sends out PING messages with a 1 byte header. I
think this
// may be a bug in Red5, but we should handle it anyway.
if (chunk == 0) {
@@ -1079,32 +1182,44 @@
chunk->clear(); // FIXME: temporary debug only, should be
unnecessary
_queues[rthead->channel].push(chunk);
}
-
- // Many RTMP messages are smaller than the chunksize
+#endif
+ // Many RTMP messages are smaller than the chunksize, so
+ // they're easy. Each channel may have a different
+ // chunksize, just to keep things interesting. The
+ // chunksize for a channel is changed by the Chunksize
+ // RTMP command.
if (chunk->size() <= _chunksize[rthead->channel]) {
- // a single byte header has no length field. As these are often
- // used as continuation packets, the body size is the same as
the
- // previous header with a length field.
- if ((rthead->head_size > 1)) {
- pktsize = chunk->size();
- } else {
- pktsize = rthead->head_size + rthead->bodysize -
chunk->size();
- }
- } else { // this RTMP message is larger than the chunksize
+ // Since the total RTMP message size is less than the
+ // chunksize for this channel, the packet size is the
+ // total message size.
+ pktsize = chunk->size();
+ } else {
+ // This RTMP message is larger than the chunksize for
+ // this channel, so the packet size is smaller than
+ // the total message size. The header bytes aren't
+ // counted as part of the message size, so we read the
+ // header plus all the data up to the channel chunksize.
if (rthead->head_size > 1) {
pktsize = rthead->head_size + _chunksize[rthead->channel];
} else {
- if ((rthead->head_size + chunk->size()) <
_chunksize[rthead->channel]) {
- pktsize = rthead->head_size + chunk->size();
+ // One byte headers are continuation messages for
+ // existing data. There may be multiple
+ // continuation messages to complete the RTMP
+ // messagem, so all packets are read up to the
+ // chunksize but the last packet of the sequence.
+ if (chunk->spaceLeft() < _chunksize[rthead->channel]) {
+ // don't store the continutation header,jusdt
+ // append the data,
+ pktsize = chunk->spaceLeft();
} else {
pktsize = rthead->head_size + (chunk->size() -
_chunksize[rthead->channel]);
}
}
}
- // Range check the size of the packet
+ // Now that we calculated the packet size, range check it
+ // for sanity.
if (pktsize <= (_chunksize[rthead->channel] +
RTMP_MAX_HEADER_SIZE)) {
- nbytes += pktsize;
// Skip the header for all but the first packet. The rest are
just to
// complete all the data up to the body size from the header.
// cerr << _queues[rthead->channel].size() << " messages in queue
for channel "
@@ -1114,20 +1229,30 @@
cerr << "Space Left in buffer for channel " <<
rthead->channel << " is: "
<< chunk->spaceLeft() << endl;
ptr += rthead->head_size;
- pktsize -= rthead->head_size;
-// } else {
-// cerr << "FIRST PACKET!" << " for channel " <<
rthead->channel << endl;
+ } else {
+ cerr << "FIRST PACKET!" << " for channel " <<
rthead->channel << endl;
}
- // This is a queue of channels with active messages
- _channels.push_back(&_queues[rthead->channel]);
+ // This is a queue of channels with active messages. This is a
+ // much smaller list to traverse when processing data than all
64 channels.
if (pktsize < 0xffffff) {
+// cerr << "FIXME5: " << hexify(ptr, pktsize, true) << endl;
+ // If the packet size is in range, then append the
+ // data to the existing data to complete the message.
chunk->append(ptr, pktsize);
+ _lastsize[rthead->channel] = rthead->bodysize;
cerr << "Adding data to existing packet for channel #" <<
rthead->channel
<< ", read " << pktsize << " bytes." << endl;
ptr += pktsize;
} else {
log_error("Packet size out of range! %d, %d",
rthead->bodysize, pktsize);
}
+ // add this packet to the list of active channels if we've
gotten
+ // all the data.
+// if (chunk->allocated() - 5 >= rthead->bodysize) {
+// cerr << "Bodysize: " << rthead->bodysize
+// << " Allocated Chunksize: " << chunk->allocated() <<
endl;
+ channels->push_back(&_queues[rthead->channel]);
+// }
} else {
log_error("RTMP packet size is out of range! %d, %d",
rthead->bodysize, pktsize);
break;
@@ -1138,7 +1263,7 @@
}
}
- return &_channels;
+ return channels;
}
=== modified file 'libnet/rtmp.h'
--- a/libnet/rtmp.h 2008-12-20 17:11:55 +0000
+++ b/libnet/rtmp.h 2009-02-14 22:42:54 +0000
@@ -20,6 +20,7 @@
#include <boost/cstdint.hpp>
#include <boost/shared_ptr.hpp>
+#include <boost/scoped_ptr.hpp>
#include <string>
#include <vector>
@@ -35,7 +36,7 @@
{
const boost::uint8_t RTMP_HANDSHAKE = 0x3;
-const int RTMP_BODY_SIZE = 1536;
+const int RTMP_HANDSHAKE_SIZE = 1536;
const int MAX_AMF_INDEXES = 64;
const int RTMP_HEADSIZE_MASK = 0xc0;
@@ -211,19 +212,16 @@
virtual ~RTMP();
// Decode
- rtmp_head_t *decodeHeader(boost::uint8_t *header);
- rtmp_head_t *decodeHeader(boost::shared_ptr<amf::Buffer> data);
+ boost::shared_ptr<rtmp_head_t> decodeHeader(boost::uint8_t *header);
+ boost::shared_ptr<rtmp_head_t> decodeHeader(amf::Buffer &data);
boost::shared_ptr<amf::Buffer> encodeHeader(int amf_index,
rtmp_headersize_e head_size,
size_t total_size, content_types_e type,
RTMPMsg::rtmp_source_e routing);
boost::shared_ptr<amf::Buffer> encodeHeader(int amf_index,
rtmp_headersize_e head_size);
- bool packetSend(boost::shared_ptr<amf::Buffer> buf);
- bool packetRead(boost::shared_ptr<amf::Buffer> buf);
-
- void addProperty(boost::shared_ptr<amf::Element> el);
- void addProperty(char *name, boost::shared_ptr<amf::Element> el);
- void addProperty(std::string &name, boost::shared_ptr<amf::Element> el);
- boost::shared_ptr<amf::Element> getProperty(const std::string &name);
+ void addProperty(amf::Element &el);
+ void addProperty(char *name, amf::Element &el);
+ void addProperty(std::string &name, amf::Element &el);
+ amf::Element &getProperty(const std::string &name);
void setHandler(Handler *hand) { _handler = hand; };
int headerSize(boost::uint8_t header);
@@ -237,10 +235,10 @@
// Decode an RTMP message
RTMPMsg *decodeMsgBody(boost::uint8_t *data, size_t size);
- RTMPMsg *decodeMsgBody(boost::shared_ptr<amf::Buffer> buf);
+ RTMPMsg *decodeMsgBody(amf::Buffer &buf);
- virtual rtmp_ping_t *decodePing(boost::uint8_t *data);
- rtmp_ping_t *decodePing(boost::shared_ptr<amf::Buffer> buf);
+ virtual boost::shared_ptr<rtmp_ping_t> decodePing(boost::uint8_t *data);
+ boost::shared_ptr<rtmp_ping_t> decodePing(amf::Buffer &buf);
// These are handlers for the various types
virtual boost::shared_ptr<amf::Buffer> encodeChunkSize();
@@ -271,40 +269,51 @@
// Receive a message, which is a series of AMF elements, seperated
// by a one byte header at regular byte intervals. (128 bytes for
- // video data by default). Each message main contain multiple packets.
+ // video data by default). Each message may contain multiple packets.
boost::shared_ptr<amf::Buffer> recvMsg();
- boost::shared_ptr<amf::Buffer> recvMsg(int timeout);
+ boost::shared_ptr<amf::Buffer> recvMsg(int fd);
// Send a message, usually a single ActionScript object. This message
// may be broken down into a series of packets on a regular byte
// interval. (128 bytes for video data by default). Each message main
// contain multiple packets.
- bool sendMsg(boost::shared_ptr<amf::Buffer> data);
+ bool sendMsg(amf::Buffer &data);
+ bool sendMsg(int fd, int channel, rtmp_headersize_e head_size,
+ size_t total_size, content_types_e type,
+ RTMPMsg::rtmp_source_e routing, amf::Buffer &data);
+ bool sendMsg(int fd, int channel, rtmp_headersize_e head_size,
+ size_t total_size, content_types_e type,
+ RTMPMsg::rtmp_source_e routing, boost::uint8_t *data, size_t
size);
+#if 0
// Send a Msg, and expect a response back of some kind.
RTMPMsg *sendRecvMsg(int amf_index, rtmp_headersize_e head_size,
size_t total_size, content_types_e type,
- RTMPMsg::rtmp_source_e routing,
boost::shared_ptr<amf::Buffer> buf);
+ RTMPMsg::rtmp_source_e routing, amf::Buffer &buf);
+#endif
// Split a large buffer into multiple smaller ones of the default chunksize
// of 128 bytes. We read network data in big chunks because it's more
efficient,
// but RTMP uses a weird scheme of a standard header, and then every
chunksize
// bytes another 1 byte RTMP header. The header itself is not part of the
byte
// count.
- queues_t *split(boost::shared_ptr<amf::Buffer> buf);
+ boost::shared_ptr<queues_t> split(amf::Buffer &buf);
+ boost::shared_ptr<queues_t> split(boost::uint8_t *data, size_t size);
CQue &operator[] (size_t x) { return _queues[x]; }
void dump();
protected:
- std::map<const char *, boost::shared_ptr<amf::Element> > _properties;
+ std::map<const char *, amf::Element> _properties;
amf::Buffer *_handshake;
Handler *_handler;
rtmp_head_t _header;
int _packet_size;
int _mystery_word;
size_t _chunksize[MAX_AMF_INDEXES];
+ size_t _lastsize[MAX_AMF_INDEXES];
int _timeout;
CQue _queues[MAX_AMF_INDEXES];
- queues_t _channels;
+// queues_t _channels;
+ amf::Buffer _buffer;
};
} // end of gnash namespace
=== modified file 'libnet/rtmp_client.cpp'
--- a/libnet/rtmp_client.cpp 2008-12-20 17:11:55 +0000
+++ b/libnet/rtmp_client.cpp 2008-12-28 01:47:56 +0000
@@ -328,7 +328,7 @@
GNASH_REPORT_FUNCTION;
// Make a buffer to hold the handshake data.
- _handshake = new Buffer(RTMP_BODY_SIZE+1);
+ _handshake = new Buffer(RTMP_HANDSHAKE_SIZE+1);
if (!_handshake) {
return false;
}
@@ -338,7 +338,7 @@
// Since we don't know what the format is, create a pattern we can
// recognize if we stumble across it later on.
- for (int i=0; i<RTMP_BODY_SIZE; i++) {
+ for (int i=0; i<RTMP_HANDSHAKE_SIZE; i++) {
boost::uint8_t pad = i^256;
*_handshake += pad;
}
@@ -362,32 +362,32 @@
_handshake->clear();
gnashSleep(1000000); // FIXME: why do we still need a delay here, when
readNet() does a select ?
- ret = readNet(_handshake->reference(), RTMP_BODY_SIZE);
- if (ret == RTMP_BODY_SIZE) {
+ ret = readNet(_handshake->reference(), RTMP_HANDSHAKE_SIZE);
+ if (ret == RTMP_HANDSHAKE_SIZE) {
log_debug (_("Read first data block in handshake"));
} else {
log_error (_("Couldn't read first data block in handshake"));
// return false;
}
- if (ret > RTMP_BODY_SIZE) {
- ret = readNet(_handshake->reference(), RTMP_BODY_SIZE);
- if (ret == RTMP_BODY_SIZE) {
+ if (ret > RTMP_HANDSHAKE_SIZE) {
+ ret = readNet(_handshake->reference(), RTMP_HANDSHAKE_SIZE);
+ if (ret == RTMP_HANDSHAKE_SIZE) {
log_debug (_("Read second data block in handshake"));
} else {
log_error (_("Couldn't read second data block in handshake"));
// return false;
}
}
- ret = readNet(_handshake->reference(), RTMP_BODY_SIZE);
- if (ret == RTMP_BODY_SIZE) {
+ ret = readNet(_handshake->reference(), RTMP_HANDSHAKE_SIZE);
+ if (ret == RTMP_HANDSHAKE_SIZE) {
log_debug (_("Read second data block in handshake"));
} else {
log_error (_("Couldn't read second data block in handshake"));
// return false;
}
- if (ret > RTMP_BODY_SIZE) {
- ret = readNet(_handshake->reference(), RTMP_BODY_SIZE);
- if (ret == RTMP_BODY_SIZE) {
+ if (ret > RTMP_HANDSHAKE_SIZE) {
+ ret = readNet(_handshake->reference(), RTMP_HANDSHAKE_SIZE);
+ if (ret == RTMP_HANDSHAKE_SIZE) {
log_debug (_("Read second data block in handshake"));
} else {
log_error (_("Couldn't read second data block in handshake"));
@@ -395,7 +395,7 @@
}
}
- ret = writeNet(_handshake->reference(), RTMP_BODY_SIZE);
+ ret = writeNet(_handshake->reference(), RTMP_HANDSHAKE_SIZE);
if ( ret <= 0 ) return false;
return true;
=== modified file 'libnet/rtmp_msg.cpp'
--- a/libnet/rtmp_msg.cpp 2008-09-22 22:56:11 +0000
+++ b/libnet/rtmp_msg.cpp 2009-02-04 21:20:09 +0000
@@ -50,14 +50,14 @@
: _routing(FROM_SERVER),
_status(APP_SHUTDOWN),
_streamid(0),
- _channel(9)
+ _channel(0)
{
// GNASH_REPORT_FUNCTION;
// _inbytes = 0;
// _outbytes = 0;
-// _body = new unsigned char(RTMP_BODY_SIZE+1);
-// memset(_body, 0, RTMP_BODY_SIZE+1);
+// _body = new unsigned char(RTMP_HANDSHAKE_SIZE+1);
+// memset(_body, 0, RTMP_HANDSHAKE_SIZE+1);
}
RTMPMsg::~RTMPMsg()
@@ -250,6 +250,12 @@
return _status;
}
+// void
+// RTMPMsg::setHeaderData(RTMP::rtmp_head_t &qhead)
+// {
+
+// }
+
boost::shared_ptr<amf::Element>
RTMPMsg::operator[](size_t index)
{
@@ -262,6 +268,31 @@
return el;
};
+/// \brief Find the named property for this Object.
+///
+/// @param name An ASCII string that is the name of the property to
+/// search for.
+///
+/// @return A smart pointer to the Element for this property.
+boost::shared_ptr<amf::Element>
+RTMPMsg::findProperty(const std::string &name)
+{
+ if (_amfobjs.size() > 0) {
+ vector<boost::shared_ptr<Element> >::iterator ait;
+// cerr << "# of Properties in object: " << _properties.size() << endl;
+ for (ait = _amfobjs.begin(); ait != _amfobjs.end(); ait++) {
+ boost::shared_ptr<amf::Element> el = (*(ait));
+ boost::shared_ptr<amf::Element> prop = el->findProperty(name);
+ if (prop) {
+ return prop;
+ }
+ }
+ }
+ boost::shared_ptr<Element> el;
+ return el;
+}
+
+
void
RTMPMsg::dump()
{
=== modified file 'libnet/rtmp_msg.h'
--- a/libnet/rtmp_msg.h 2008-12-20 17:11:55 +0000
+++ b/libnet/rtmp_msg.h 2009-02-10 19:23:05 +0000
@@ -80,7 +80,10 @@
SO_CREATION_FAILED,
SO_NO_READ_ACCESS,
SO_NO_WRITE_ACCESS,
- SO_PERSISTENCE_MISMATCH
+ SO_PERSISTENCE_MISMATCH,
+ // Anything below here is specific to Gnash's implementation
+ NS_CREATE_STREAM,
+ NS_DELETE_STREAM
} rtmp_status_e;
typedef enum {
FROM_SERVER, // Flash com server
@@ -107,8 +110,19 @@
boost::uint8_t getChannel() { return _channel; } ;
boost::shared_ptr<amf::Element> operator[](size_t x);
-
- // Dump internal status to the terminal
+ boost::shared_ptr<amf::Element> at(size_t x) { return _amfobjs[x]; };
+
+ /// \brief Find the named property for this Object.
+ ///
+ /// @param name An ASCII string that is the name of the property to
+ /// search for.
+ ///
+ /// @return A smart pointer to the Element for this property.
+ boost::shared_ptr<amf::Element> findProperty(const std::string &name);
+
+// void setHeaderData(RTMP::rtmp_head_t &qhead);
+
+// Dump internal status to the terminal
void dump();
protected:
=== modified file 'packaging/redhat/gnash.spec'
--- a/packaging/redhat/gnash.spec 2009-02-15 15:36:01 +0000
+++ b/packaging/redhat/gnash.spec 2009-02-17 03:18:15 +0000
@@ -2,7 +2,7 @@
Version: 20090213
Release: 1
Distribution: fc10
-# Distribution: ydl6
+#Distribution: ydl6
Summary: GNU SWF player
Group: Applications/Multimedia
=== modified file 'packaging/xpi/install.rdf'
--- a/packaging/xpi/install.rdf 2008-09-12 21:18:45 +0000
+++ b/packaging/xpi/install.rdf 2009-02-17 03:18:15 +0000
@@ -63,7 +63,7 @@
<em:homepageURL>http://www.gnashdev.org/</em:homepageURL>
<!-- Front End Integration Hooks (used by Extension Manager)-->
-<!--
<em:updateURL>"http://www.getgnash.org/updates/update.rdf"</em:updateURL> -->
+
<em:updateURL>"http://www.getgnash.org/updates/update.rdf"</em:updateURL>
<em:homepageURL>"http://www.gnu.org/software/gnash"<em:homepageURL>
<em:targetPlatform>Linux_x86-gcc3</em:targetPlatform>
=== modified file 'packaging/xpi/update.rdf'
--- a/packaging/xpi/update.rdf 2008-08-10 03:46:02 +0000
+++ b/packaging/xpi/update.rdf 2009-02-17 03:18:15 +0000
@@ -8,7 +8,7 @@
<r:Seq>
<r:li>
<r:Description>
- <version>0.8.3</version>
+ <version>trunk-20090214</version>
<targetApplication>
<r:Description>
<id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</id>
@@ -21,7 +21,7 @@
</r:li>
</r:Seq>
</updates>
- <version>0.8.3</version>
+ <version>trunk-20090214</version>
<updateLink>http://www.getgnash.org/updates/getgnash.xpi</updateLink>
</r:Description>
</r:RDF>
=== modified file 'testsuite/libamf.all/test_amf.cpp'
--- a/testsuite/libamf.all/test_amf.cpp 2008-12-29 23:18:28 +0000
+++ b/testsuite/libamf.all/test_amf.cpp 2009-02-17 03:18:15 +0000
@@ -159,37 +159,27 @@
test_encoding()
{
// This is a 8 byte wide double data type in hex
- {
- boost::shared_ptr<Buffer> buf1(new Buffer("40 83 38 00 00 00 00 00"));
- double num = *(reinterpret_cast<double *>(buf1->reference()));
- swapBytes(&num, amf::AMF0_NUMBER_SIZE); // we alwasy encode in big
endian format
+ boost::shared_ptr<Buffer> buf1(new Buffer("40 83 38 00 00 00 00 00"));
+ double num = *(reinterpret_cast<double *>(buf1->reference()));
+ swapBytes(&num, amf::AMF0_NUMBER_SIZE); // we always encode in big endian
format
#if defined(HAVE_MALLINFO) && defined(USE_STATS_MEMORY)
- if (memdebug) {
- mem->addStats(__LINE__); // take a sample
- }
+ if (memdebug) {
+ mem->addStats(__LINE__); // take a sample
+ }
#endif
- boost::shared_ptr<Buffer> encnum = AMF::encodeNumber(num);
- // A number AMF object has only one header byte, which is the type
field.
+ boost::shared_ptr<Buffer> encnum = AMF::encodeNumber(num);
+ // A number AMF object has only one header byte, which is the type field.
#if defined(HAVE_MALLINFO) && defined(USE_STATS_MEMORY)
- if (memdebug) {
- mem->addStats(__LINE__); // take a sample
- }
+ if (memdebug) {
+ mem->addStats(__LINE__); // take a sample
+ }
#endif
- if ((*encnum->reference() == Element::NUMBER_AMF0) &&
- (memcmp(buf1->reference(), encnum->reference()+1,
amf::AMF0_NUMBER_SIZE) == 0)) {
- runtest.pass("Encoded AMF Number");
- } else {
- runtest.fail("Encoded AMF Number");
- }
-
- Element el(num);
- boost::shared_ptr<Buffer> buf = AMF::encodeElement(el);
-
- check_equals(*buf->reference(), Element::NUMBER_AMF0);
- check_equals(buf->size(), amf::AMF0_NUMBER_SIZE+1); // +1 for the type
byte
- // A String AMF object has a 3 bytes head, the type, and a two byte
length.
- check_equals(memcmp(buf1->reference(), buf->reference()+1,
amf::AMF0_NUMBER_SIZE), 0);
+ if ((*encnum->reference() == Element::NUMBER_AMF0) &&
+ (memcmp(buf1->reference(), encnum->reference()+1,
amf::AMF0_NUMBER_SIZE) == 0)) {
+ runtest.pass("Encoded AMF Number");
+ } else {
+ runtest.fail("Encoded AMF Number");
}
// Encode a boolean. Although we know a bool is only one character, for
AMF,
@@ -221,22 +211,6 @@
} else {
runtest.fail("Encoded AMF Boolean");
}
-
- Element el(true);
- boost::shared_ptr<Buffer> buf = AMF::encodeElement(el);
-
- check_equals(*buf->reference(), Element::BOOLEAN_AMF0);
- check_equals(buf->size(), 2);
- // A String AMF object has a 3 bytes head, the type, and a two byte
length.
- check_equals(memcmp(buf->reference(), buf2->reference(), 2), 0);
-
- Element el2(false);
- buf = AMF::encodeElement(el2);
-
- check_equals(*buf->reference(), Element::BOOLEAN_AMF0);
- check_equals(buf->size(), 2);
- // A String AMF object has a 3 bytes head, the type, and a two byte
length.
- check_equals(*(buf->reference()+1), 0);
}
// Encode a String.
@@ -298,20 +272,35 @@
check_equals(len, 0);
}
-// amf::AMF::encodeECMAArray(unsigned char*, int)
+ AMF amf;
+ Element el1;
+ boost::uint16_t index = 1;
+ el1.makeReference(index);
+ if (el1.to_short() == 1) {
+ runtest.pass("Made Reference");
+ } else {
+ runtest.fail("Made Reference");
+ }
+
+ boost::shared_ptr<amf::Buffer> buf2 = amf.encodeElement(el1);
+ if ((*buf2->reference() == Element::REFERENCE_AMF0)
+ && (*(buf2->reference() + 1) == 0)
+ && (*(buf2->reference() + 2) == 1)) {
+ runtest.pass("Encoded Reference");
+ } else {
+ runtest.fail("Encoded Reference");
+ }
+
+ boost::shared_ptr<Buffer> buf3(new Buffer("07 00 01"));
+ boost::shared_ptr<amf::Element> el3 = amf.extractAMF(buf3);
+ if ((el3->getType() == Element::REFERENCE_AMF0)
+ && (el3->to_short() == 1)) {
+ runtest.pass("Extracted Reference");
+ } else {
+ runtest.fail("Extracted Reference");
+ }
+
}
-// amf::encodeDate(unsigned char*)
-// amf::AMF::encodeLongString(unsigned char*, int)
-// amf::AMF::encodeStrictArray(unsigned char*, int)
-// amf::AMF::encodeTypedObject(unsigned char*, int)
-// amf::AMF::encodeUnsupported()
-// amf::AMF::encodeNull()
-// amf::AMF::encodeElement(amf::Element*)
-// amf::AMF::encodeMovieClip(unsigned char*, int)
-// amf::AMF::encodeRecordSet(unsigned char*, int)
-// amf::AMF::encodeReference(unsigned char*, int)
-// amf::AMF::encodeUndefined()
-// amf::AMF::encodeXMLObject(unsigned char*, int)
void
test_array()
@@ -411,7 +400,7 @@
// but this should have a more accurate test to make sure all
// the child elements are correct all the time.
if ((newtop->getType() == Element::OBJECT_AMF0)
- && (newtop->propertySize() == 3)) {
+ && (newtop->propertySize() >= 3)) {
runtest.pass("Extracted Object");
} else {
runtest.fail("Extracted Object");
=== modified file 'testsuite/libnet.all/Makefile.am'
--- a/testsuite/libnet.all/Makefile.am 2008-12-25 23:00:23 +0000
+++ b/testsuite/libnet.all/Makefile.am 2009-02-17 03:18:15 +0000
@@ -49,11 +49,11 @@
check_PROGRAMS = \
test_cque \
- test_handler \
test_http \
test_diskstream \
- test_cache
-# test_rtmp
+ test_cache \
+ test_rtmp
+# test_handler
generate_amfbins_SOURCES = generate_amfbins.cpp
generate_amfbins_LDADD = $(AM_LDFLAGS)
@@ -71,17 +71,17 @@
test_diskstream_LDADD = $(AM_LDFLAGS)
test_diskstream_DEPENDENCIES = site-update
-#test_rtmp_SOURCES = test_rtmp.cpp
-#test_rtmp_LDADD = $(AM_LDFLAGS)
-#test_rtmp_DEPENDENCIES = site-update
+test_rtmp_SOURCES = test_rtmp.cpp
+test_rtmp_LDADD = $(AM_LDFLAGS)
+test_rtmp_DEPENDENCIES = site-update
test_cque_SOURCES = test_cque.cpp
test_cque_LDADD = $(AM_LDFLAGS)
test_cque_DEPENDENCIES = site-update
-test_handler_SOURCES = test_handler.cpp
-test_handler_LDADD = $(AM_LDFLAGS)
-test_handler_DEPENDENCIES = site-update
+# test_handler_SOURCES = test_handler.cpp
+# test_handler_LDADD = $(AM_LDFLAGS)
+# test_handler_DEPENDENCIES = site-update
# Rebuild with GCC 4.x Mudflap support
mudflap:
=== modified file 'testsuite/libnet.all/test_http.cpp'
--- a/testsuite/libnet.all/test_http.cpp 2008-12-26 18:55:58 +0000
+++ b/testsuite/libnet.all/test_http.cpp 2009-02-17 01:09:27 +0000
@@ -37,6 +37,10 @@
#include <string>
#include <vector>
#include <regex.h>
+#include <ctime> // std::time
+
+#include <boost/random/uniform_int.hpp>
+#include <boost/random/mersenne_twister.hpp>
#include "log.h"
#include "http.h"
@@ -59,6 +63,14 @@
LogFile& dbglogfile = LogFile::getDefaultInstance();
+// Uncommenting this enables test cases that attempt to handle
+// corrupted packets by randomly trashing data. These are not
+// enabled by default, as they aren't valgrind clean by definition
+// These tests primary function is to make sure HTTP, RTMPT, and
+// AMF parsing is as stable as possible, and can handle some of the
+// without crashing.
+//#define CORRUPT_MEMORY_TESTS 1
+
int
main(int argc, char *argv[])
{
@@ -359,25 +371,44 @@
// User Agent: Lynx/2.8.6rel.2 libwww-FM/2.14 SSL-MM/1.4.1 OpenSSL/0.9.8b
-#if 0
- boost::uint8_t *field1 = (boost::uint8_t *)"GET /index.html HTTP/1.1";
+ Buffer field1;
+ field1 = "GET /index.html HTTP/1.1";
+ // boost::uint8_t *field1 = (boost::uint8_t *)"GET /index.html
HTTP/1.1";
HTTP http1;
- http1.extractMethod(field1);
- if ((http1.keepAlive() == true) && (http1.getVersion()->minor == 1)) {
- runtest.pass ("HTTP::extractMethod(HTTP/1.1)");
+ // http1.extractCommand(field1);
+ http1.extractCommand(field1);
+ if ((http1.getVersion()->minor == 1) && (http1.getFilespec() ==
"/index.html")) {
+ runtest.pass ("HTTP::extractCommand(HTTP/1.1)");
} else {
- runtest.fail ("HTTP::extractMethod(HTTP/1.1)");
+ runtest.fail ("HTTP::extractCommand(HTTP/1.1)");
}
- boost::uint8_t *field2 = (boost::uint8_t *)"GET /index.html HTTP/1.0";
+ Buffer field2;
+ field2 = "GET /index.html HTTP/1.0";
HTTP http2;
- http2.extractMethod(field2);
- if ((http2.keepAlive() == false) && (http2.getVersion()->minor == 0)) {
- runtest.pass ("HTTP::extractMethod(HTTP/1.0)");
- } else {
- runtest.fail ("HTTP::extractMethod(HTTP/1.0)");
- }
-
+ http2.extractCommand(field2);
+ if ((http2.getVersion()->minor == 0) && (http2.getFilespec() ==
"/index.html")) {
+ runtest.pass ("HTTP::extractCommand(HTTP/1.0)");
+ } else {
+ runtest.fail ("HTTP::extractCommand(HTTP/1.0)");
+ }
+
+ Buffer field3;
+ field3 = "GET
/software/gnash/tests/flvplayer.swf?file=http://localhost/software/gnash/tests/Ouray_Ice_Festival_Climbing_Competition.flv
HTTP/1.1\r\n";
+ HTTP http3;
+ http3.extractCommand(field3);
+ if (http3.getFilespec() == "/software/gnash/tests/flvplayer.swf") {
+ runtest.pass ("HTTP::extractCommand(filespec)");
+ } else {
+ runtest.fail ("HTTP::extractCommand(params)");
+ }
+ if (http3.getParams() ==
"file=http://localhost/software/gnash/tests/Ouray_Ice_Festival_Climbing_Competition.flv")
{
+ runtest.pass ("HTTP::extractCommand(params)");
+ } else {
+ runtest.fail ("HTTP::extractCommand(params)");
+ }
+
+#if 0
boost::uint8_t *field3 = (boost::uint8_t *) "Keep-Alive: 300";
HTTP http3;
http3.extractKeepAlive(field3);
@@ -411,7 +442,7 @@
"Content-Language: en-US,en;q=0.9\r\n"
"Content-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1\r\n"
"Content-Encoding: deflate, gzip, x-gzip, identity, *;q=0\r\n";
-// http.extractMethod(buffer);
+// http.extractCommand(buffer);
string result;
result = http.extractReferer(buffer);
if (result == "http://localhost/software/gnash/tests/index.html") {
@@ -652,7 +683,6 @@
void
test_rtmpt (void)
{
-
HTTP http;
// Boolean True request
@@ -666,6 +696,8 @@
} else {
runtest.fail("HTTP::parseEchoRequest(Boolean TRUE)");
}
+// hex_req1->corrupt();
+
// Boolean True response
boost::shared_ptr<Buffer> hex_res1(new Buffer("00 00 00 00 00 01 00 0b 2f
31 2f 6f 6e 52 65 73 75 6c 74 00 04 6e 75 6c 6c ff ff ff ff 01 01"));
amf::Buffer &buf1 = http.formatEchoResponse(headers1[1]->getName(),
*headers1[3]);
@@ -1264,7 +1296,8 @@
runtest.fail("HTTP::formatEchoResponse(Strict Array - Number,
undefines, Number)");
}
#endif
-
+
+#if 0
// Array request
boost::shared_ptr<Buffer> hex_req28(new Buffer("00 00 00 00 00 01 00 04 65
63 68 6f 00 02 2f 37 00 00 00 38 0a 00 00 00 01 08 00 00 00 01 00 06 6c 65 6e
67 74 68 00 3f f0 00 00 00 00 00 00 00 01 30 00 3f f0 00 00 00 00 00 00 00 03
6f 6e 65 00 3f f0 00 00 00 00 00 00 00 00 09"));
vector<boost::shared_ptr<amf::Element> > headers28 =
http.parseEchoRequest(*hex_req28);
@@ -1283,12 +1316,12 @@
} else {
runtest.fail("HTTP::parseEchoRequest(ECMA Array, 2 Numbers)");
}
+
// Undefined Array response
boost::shared_ptr<Buffer> hex_res28(new Buffer("00 00 00 00 00 01 00 0b 2f
37 2f 6f 6e 52 65 73 75 6c 74 00 04 6e 75 6c 6c ff ff ff ff 08 00 00 00 01 00
03 6f 6e 65 00 3f f0 00 00 00 00 00 00 00 01 30 00 3f f0 00 00 00 00 00 00 00
06 6c 65 6e 67 74 68 00 3f f0 00 00 00 00 00 00 00 00 09"));
amf::Buffer &buf28 = http.formatEchoResponse(headers28[1]->getName(),
*headers28[3]);
// cerr << hexify(hex_res28->reference()+30, hex_res28->allocated()-30,
false) << endl;
// cerr << hexify(buf28.reference() + 124, buf28.allocated() - 124, false)
<< endl;
- // headers28[3]->dump();
string head28(reinterpret_cast<const char *>(buf28.reference()));
const char *ptr28a = reinterpret_cast<const char
*>(hex_res28->reference());
const char *ptr28b = reinterpret_cast<const char *>(buf28.reference()) +
head28.size();
@@ -1297,6 +1330,7 @@
} else {
runtest.fail("HTTP::formatEchoResponse(ECMA Array, 2 Numbers)");
}
+#endif
// NULL String request, ie.. no data
boost::shared_ptr<Buffer> hex_req29(new Buffer("00 00 00 00 00 01 00 04 65
63 68 6f 00 02 2f 31 00 00 00 08 0a 00 00 00 01 02 00 00"));
@@ -1420,9 +1454,8 @@
if (headers41[3] == 0) {
runtest.unresolved("HTTP::parseEchoRequest(object CustomClass Array)");
} else {
- if ((strncmp(headers41[0]->getName(), "echo", 4) == 0)
- && (strncmp(headers41[1]->getName(), "/2", 2) == 0)
- && (headers41[3]->getType() == Element::STRICT_ARRAY_AMF0)) {
+ if ((headers41[3]->getType() == Element::STRICT_ARRAY_AMF0)
+ && (headers41[3]->propertySize() == 2)) {
runtest.pass("HTTP::parseEchoRequest(object CustomClass Array)");
} else {
runtest.fail("HTTP::parseEchoRequest(object CustomClass Array)");
@@ -1448,7 +1481,8 @@
} else {
if ((strncmp(headers42[0]->getName(), "echo", 4) == 0)
&& (strncmp(headers42[1]->getName(), "/1", 2) == 0)
- && (headers42[3]->getType() == Element::TYPED_OBJECT_AMF0)) {
+ && (headers42[3]->getType() == Element::TYPED_OBJECT_AMF0)
+ && (headers42[3]->propertySize() == 2)) {
runtest.pass("HTTP::parseEchoRequest(object RemoteClass)");
} else {
runtest.fail("HTTP::parseEchoRequest(object RemoteClass)");
@@ -1474,11 +1508,9 @@
if (headers43[3] == 0) {
runtest.unresolved("HTTP::parseEchoRequest(object RemoteClass Array, 2
items)");
} else {
- // headers43[3]->dump();
std::vector<boost::shared_ptr<amf::Element> > props43 =
headers43[3]->getProperties();
std::vector<boost::shared_ptr<amf::Element> > props43a =
props43[0]->getProperties();
std::vector<boost::shared_ptr<amf::Element> > props43b =
props43[1]->getProperties();
- // props43[1]->dump();
if ((strncmp(headers43[0]->getName(), "echo", 4) == 0)
&& (strncmp(headers43[1]->getName(), "/2", 2) == 0)
&& (headers43[3]->getType() == Element::STRICT_ARRAY_AMF0)
@@ -1504,20 +1536,20 @@
amf::Buffer &buf43 = http.formatEchoResponse(headers43[1]->getName(),
*headers43[3]);
std::vector<boost::shared_ptr<amf::Element> > props43 =
headers43[3]->getProperties();
// std::vector<boost::shared_ptr<amf::Element> > props43a =
props43[0]->getProperties();
- // headers43[3]->dump();
- // props43[0]->dump();
// cerr << hexify(hex_res43->reference()+29, hex_res43->allocated()-29 ,
false) << endl;
// cerr << hexify(buf43.reference(), buf43.allocated(), true) << endl;
// cerr << hexify(buf43.reference() + 124, buf43.allocated()-124, false)
<< endl;
string head43(reinterpret_cast<const char *>(buf43.reference()));
const char *ptr43a = reinterpret_cast<const char
*>(hex_res43->reference());
const char *ptr43b = reinterpret_cast<const char *>(buf43.reference()) +
head43.size();
+#if 0
if (memcmp(ptr43a, ptr43b, hex_res43->allocated()-4) == 0) {
- runtest.pass("HTTP::formatEchoResponse(object RemoteClass Array, 2
items)");
+ runtest.xpass("HTTP::formatEchoResponse(object RemoteClass Array, 2
items)");
} else {
- runtest.fail("HTTP::formatEchoResponse(object RemoteClass Array, 2
items)");
+ runtest.xfail("HTTP::formatEchoResponse(object RemoteClass Array, 2
items)");
}
-
+#endif
+
// [object RemoteClass] [object RemoteClass]
boost::shared_ptr<Buffer> hex_req44(new Buffer("00 00 00 00 00 01 00 04 65
63 68 6f 00 02 2f 33 00 00 00 5b 0a 00 00 00 01 10 00 27 6f 72 67 2e 72 65 64
35 2e 73 65 72 76 65 72 2e 77 65 62 61 70 70 2e 65 63 68 6f 2e 52 65 6d 6f 74
65 43 6c 61 73 73 00 0a 61 74 74 72 69 62 75 74 65 32 00 41 d2 65 80 b4 80 00
00 00 0a 61 74 74 72 69 62 75 74 65 31 02 00 05 74 68 72 65 65 00 00 09"));
vector<boost::shared_ptr<amf::Element> > headers44 =
http.parseEchoRequest(*hex_req44);
@@ -1542,7 +1574,8 @@
} else {
runtest.fail("HTTP::formatEchoResponse(object RemoteClass)");
}
-
+
+#if 0
// [object RemoteClass] [object RemoteClass]
boost::shared_ptr<Buffer> hex_req45(new Buffer("00 00 00 00 00 01 00 04 65
63 68 6f 00 02 2f 34 00 00 00 5a 0a 00 00 00 01 10 00 27 6f 72 67 2e 72 65 64
35 2e 73 65 72 76 65 72 2e 77 65 62 61 70 70 2e 65 63 68 6f 2e 52 65 6d 6f 74
65 43 6c 61 73 73 00 0a 61 74 74 72 69 62 75 74 65 32 00 42 71 3f 8f 4d 00 00
00 00 0a 61 74 74 72 69 62 75 74 65 31 02 00 04 66 6f 75 72 00 00 09"));
vector<boost::shared_ptr<amf::Element> > headers45 =
http.parseEchoRequest(*hex_req45);
@@ -1550,22 +1583,26 @@
runtest.unresolved("HTTP::parseEchoRequest(object RemoteClass Array)");
} else {
std::vector<boost::shared_ptr<amf::Element> > props45 =
headers45[3]->getProperties();
- if ((strncmp(headers45[0]->getName(), "echo", 4) == 0)
- && (strncmp(headers45[1]->getName(), "/4", 2) == 0)
- && (headers45[3]->getType() == Element::TYPED_OBJECT_AMF0)
- && (strcmp(headers45[3]->getName(),
"org.red5.server.webapp.echo.RemoteClass") == 0)
- && (props45[0]->getType() == Element::NUMBER_AMF0)
- && (strncmp(props45[0]->getName(), "attribute2", 10) == 0)
- && (props45[1]->getType() == Element::STRING_AMF0)
- && (strncmp(props45[1]->getName(), "attribute1", 10) == 0)
- && (strncmp(props45[1]->to_string(), "four", 4) == 0)
- ) {
- runtest.pass("HTTP::parseEchoRequest(object RemoteClass)");
- } else {
- runtest.fail("HTTP::parseEchoRequest(object RemoteClass)");
+ if (props45.size() == 2) {
+ if ((strncmp(headers45[0]->getName(), "echo", 4) == 0)
+ && (strncmp(headers45[1]->getName(), "/4", 2) == 0)
+ && (headers45[3]->getType() == Element::TYPED_OBJECT_AMF0)
+ && (strcmp(headers45[3]->getName(),
"org.red5.server.webapp.echo.RemoteClass") == 0)
+ && (props45[0]->getType() == Element::NUMBER_AMF0)
+ && (strncmp(props45[0]->getName(), "attribute2", 10) == 0)
+ && (props45[1]->getType() == Element::STRING_AMF0)
+ && (strncmp(props45[1]->getName(), "attribute1", 10) == 0)
+ && (strncmp(props45[1]->to_string(), "four", 4) == 0)
+ ) {
+ runtest.pass("HTTP::parseEchoRequest(object RemoteClass)");
+ } else {
+ runtest.fail("HTTP::parseEchoRequest(object RemoteClass)");
+ }
+ } else {
+ runtest.untested("HTTP::parseEchoRequest(object RemoteClass)");
}
}
-
+
boost::shared_ptr<Buffer> hex_res45(new Buffer("00 00 00 00 00 01 00 0b 2f
34 2f 6f 6e 52 65 73 75 6c 74 00 04 6e 75 6c 6c ff ff ff ff 10 00 27 6f 72 67
2e 72 65 64 35 2e 73 65 72 76 65 72 2e 77 65 62 61 70 70 2e 65 63 68 6f 2e 52
65 6d 6f 74 65 43 6c 61 73 73 00 0a 61 74 74 72 69 62 75 74 65 31 02 00 04 66
6f 75 72 00 0a 61 74 74 72 69 62 75 74 65 32 00 c1 9c 2c c0 00 00 00 00 00 00
09"));
amf::Buffer &buf45 = http.formatEchoResponse(headers45[1]->getName(),
*headers45[3]);
string head45(reinterpret_cast<const char *>(buf45.reference()));
@@ -1579,17 +1616,338 @@
} else {
runtest.fail("HTTP::formatEchoResponse(object RemoteClass)");
}
+#endif
// String test with 40000 characters
// String test with 70000 characters
// String test with 1000000 characters
-//boost::shared_ptr<Buffer> hex1(new Buffer("00 00 00 00 00 01 00 04 65 63 68
6f 00 02 2f 34 00 00 9c 48 0a 00 00 00 01 02 9c 40 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35"));
-//boost::shared_ptr<Buffer> hex1(new Buffer("36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39"));
-//boost::shared_ptr<Buffer> hex1(new Buffer("30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39"));
-
-//boost::shared_ptr<Buffer> hex1(new Buffer("00 00 00 00 00 01 00 0b 2f 34 2f
6f 6e 52 65 73 75 6c 74 00 04 6e 75 6c 6c ff ff ff ff 02 9c 40 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34"));
-//boost::shared_ptr<Buffer> hex1(new Buffer("35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39
30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35
36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31
32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37
38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33
34 35 36 37 38 39 30 31 32 33"));
-//boost::shared_ptr<Buffer> hex1(new Buffer("34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34
35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30
31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36
37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32
33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38
39"));
+
+#ifdef CORRUPT_MEMORY_TESTS
+ // Use the existing binary data and see if we can survive decoding corupted
+ // packets. While the data may be bogus in the returned Elements, we
shouldn't
+ // ever crash,. so these are primarily a stress test.
+// cerr << hexify(hex_req1->reference(), hex_req1->allocated(), false) <<
endl;
+ hex_req1->corrupt(6);
+// cerr << hexify(hex_req1->reference(), hex_req1->allocated(), false) <<
endl;
+ vector<boost::shared_ptr<amf::Element> > corrupt1 =
http.parseEchoRequest(*hex_req1);
+ if (corrupt1.size()) {
+ runtest.pass("Corrupted HTTP::parseEchoRequest(Boolean TRUE)");
+ } else {
+ runtest.fail("Corrupted HTTP::parseEchoRequest(Boolean TRUE)");
+ }
+
+// cerr << hexify(hex_req2->reference(), hex_req2->allocated(), false) <<
endl;
+ hex_req2->corrupt(4);
+// cerr << hexify(hex_req2->reference(), hex_req2->allocated(), false) <<
endl;
+ vector<boost::shared_ptr<amf::Element> > corrupt2 =
http.parseEchoRequest(*hex_req2);
+ if (corrupt2.size()) {
+ runtest.pass("Corrupted HTTP::parseEchoRequest(Boolean FALSE)");
+ } else {
+ runtest.fail("Corrupted HTTP::parseEchoRequest(Boolean FALSE)");
+ }
+
+// cerr << hexify(hex_req3->reference(), hex_req3->allocated(), false) <<
endl;
+ hex_req3->corrupt(3);
+// cerr << hexify(hex_req3->reference(), hex_req3->allocated(), false) <<
endl;
+ vector<boost::shared_ptr<amf::Element> > corrupt3 =
http.parseEchoRequest(*hex_req3);
+ if (corrupt3.size()) {
+ runtest.pass("Corrupted HTTP::parseEchoRequest(NULL Object)");
+ } else {
+ runtest.fail("Corrupted HTTP::parseEchoRequest(NULL Object)");
+ }
+
+// cerr << hexify(hex_req4->reference(), hex_req4->allocated(), false) <<
endl;
+ hex_req4->corrupt(7);
+// cerr << hexify(hex_req4->reference(), hex_req4->allocated(), false) <<
endl;
+ vector<boost::shared_ptr<amf::Element> > corrupt4 =
http.parseEchoRequest(*hex_req4);
+ if (corrupt4.size()) {
+ runtest.pass("Corrupted HTTP::parseEchoRequest(UNDEFINED Object)");
+ } else {
+ runtest.fail("Corrupted HTTP::parseEchoRequest(UNDEFINED Object)");
+ }
+
+ cerr << hexify(hex_req5->reference(), hex_req5->allocated(), false) <<
endl;
+ hex_req5->corrupt(5);
+ cerr << hexify(hex_req5->reference(), hex_req5->allocated(), false) <<
endl;
+ vector<boost::shared_ptr<amf::Element> > corrupt5 =
http.parseEchoRequest(*hex_req5);
+ if (corrupt5.size()) {
+ runtest.pass("Corrupted HTTP::parseEchoRequest(DATE Object)");
+ } else {
+ runtest.fail("Corrupted HTTP::parseEchoRequest(DATE Object)");
+ }
+
+// cerr << hexify(hex_req6->reference(), hex_req6->allocated(), false) <<
endl;
+ hex_req6->corrupt(7);
+// cerr << hexify(hex_req6->reference(), hex_req6->allocated(), false) <<
endl;
+ vector<boost::shared_ptr<amf::Element> > corrupt6 =
http.parseEchoRequest(*hex_req6);
+ if (corrupt6.size()) {
+ runtest.pass("Corrupted HTTP::parseEchoRequest(DATE Array)");
+ } else {
+ runtest.fail("Corrupted HTTP::parseEchoRequest(DATE Array)");
+ }
+
+// cerr << hexify(hex_req7->reference(), hex_req7->allocated(), false) <<
endl;
+ hex_req7->corrupt(5);
+// cerr << hexify(hex_req7->reference(), hex_req7->allocated(), false) <<
endl;
+ vector<boost::shared_ptr<amf::Element> > corrupt7 =
http.parseEchoRequest(*hex_req7);
+ if (corrupt7.size()) {
+ runtest.pass("Corrupted HTTP::parseEchoRequest(Undefined Strict
Array)");
+ } else {
+ runtest.fail("Corrupted HTTP::parseEchoRequest(Undefined Strict
Array)");
+ }
+
+// cerr << hexify(hex_req8->reference(), hex_req8->allocated(), false) <<
endl;
+ hex_req8->corrupt(2);
+// cerr << hexify(hex_req8->reference(), hex_req8->allocated(), false) <<
endl;
+ vector<boost::shared_ptr<amf::Element> > corrupt8 =
http.parseEchoRequest(*hex_req8);
+ if (corrupt8.size()) {
+ runtest.pass("Corrupted HTTP::parseEchoRequest(Simple Strict Array of
Numbers. 1 item)");
+ } else {
+ runtest.fail("Corrupted HTTP::parseEchoRequest(Simple Strict Array of
Numbers. 1 item)");
+ }
+
+// cerr << hexify(hex_req9->reference(), hex_req9->allocated(), false) <<
endl;
+ hex_req9->corrupt(3);
+// cerr << hexify(hex_req9->reference(), hex_req9->allocated(), false) <<
endl;
+ vector<boost::shared_ptr<amf::Element> > corrupt9 =
http.parseEchoRequest(*hex_req9);
+ if (corrupt9.size()) {
+ runtest.pass("Corrupted HTTP::parseEchoRequest(Simple Strict Array of
Numbers. 2 items)");
+ } else {
+ runtest.fail("Corrupted HTTP::parseEchoRequest(Simple Strict Array of
Numbers. 2 items)");
+ }
+
+// cerr << hexify(hex_req10->reference(), hex_req10->allocated(), false) <<
endl;
+ hex_req10->corrupt(2);
+// cerr << hexify(hex_req10->reference(), hex_req10->allocated(), false) <<
endl;
+ vector<boost::shared_ptr<amf::Element> > corrupt10 =
http.parseEchoRequest(*hex_req10);
+ if (corrupt10.size()) {
+ runtest.pass("Corrupted HTTP::parseEchoRequest(Simple Strict Array of
Numbers. 3 items)");
+ } else {
+ runtest.fail("Corrupted HTTP::parseEchoRequest(Simple Strict Array of
Numbers. 3 items)");
+ }
+
+// cerr << hexify(hex_req11->reference(), hex_req11->allocated(), false) <<
endl;
+ hex_req11->corrupt(2);
+// cerr << hexify(hex_req11->reference(), hex_req11->allocated(), false) <<
endl;
+ vector<boost::shared_ptr<amf::Element> > corrupt11 =
http.parseEchoRequest(*hex_req11);
+ if (corrupt11.size()) {
+ runtest.pass("Corrupted HTTP::parseEchoRequest(Number 0)");
+ } else {
+ runtest.fail("Corrupted HTTP::parseEchoRequest(Number 0)");
+ }
+
+// cerr << hexify(hex_req12->reference(), hex_req12->allocated(), false) <<
endl;
+ hex_req12->corrupt(4);
+// cerr << hexify(hex_req12->reference(), hex_req12->allocated(), false) <<
endl;
+ vector<boost::shared_ptr<amf::Element> > corrupt12 =
http.parseEchoRequest(*hex_req12);
+ if (corrupt12.size()) {
+ runtest.pass("Corrupted HTTP::parseEchoRequest(Number 1)");
+ } else {
+ runtest.fail("Corrupted HTTP::parseEchoRequest(Number 1)");
+ }
+
+// cerr << hexify(hex_req13->reference(), hex_req13->allocated(), false) <<
endl;
+ hex_req13->corrupt(1);
+// cerr << hexify(hex_req13->reference(), hex_req13->allocated(), false) <<
endl;
+ vector<boost::shared_ptr<amf::Element> > corrupt13 =
http.parseEchoRequest(*hex_req13);
+ if (corrupt13.size()) {
+ runtest.pass("Corrupted HTTP::parseEchoRequest(Number -1)");
+ } else {
+ runtest.fail("Corrupted HTTP::parseEchoRequest(Number -1)");
+ }
+
+// cerr << hexify(hex_req14->reference(), hex_req14->allocated(), false) <<
endl;
+ hex_req14->corrupt(5);
+// cerr << hexify(hex_req14->reference(), hex_req14->allocated(), false) <<
endl;
+ vector<boost::shared_ptr<amf::Element> > corrupt14 =
http.parseEchoRequest(*hex_req14);
+ if (corrupt14.size()) {
+ runtest.pass("Corrupted HTTP::parseEchoRequest(Number 256)");
+ } else {
+ runtest.fail("Corrupted HTTP::parseEchoRequest(Number 256)");
+ }
+
+// cerr << hexify(hex_req15->reference(), hex_req15->allocated(), false) <<
endl;
+ hex_req15->corrupt(5);
+// cerr << hexify(hex_req15->reference(), hex_req15->allocated(), false) <<
endl;
+ vector<boost::shared_ptr<amf::Element> > corrupt15 =
http.parseEchoRequest(*hex_req15);
+ if (corrupt15.size()) {
+ runtest.pass("Corrupted HTTP::parseEchoRequest(Number -256)");
+ } else {
+ runtest.fail("Corrupted HTTP::parseEchoRequest(Number -256)");
+ }
+
+// cerr << hexify(hex_req16->reference(), hex_req16->allocated(), false) <<
endl;
+ hex_req16->corrupt(2);
+// cerr << hexify(hex_req16->reference(), hex_req16->allocated(), false) <<
endl;
+ vector<boost::shared_ptr<amf::Element> > corrupt16 =
http.parseEchoRequest(*hex_req16);
+ if (corrupt16.size()) {
+ runtest.pass("Corrupted HTTP::parseEchoRequest(Number 65536)");
+ } else {
+ runtest.fail("Corrupted HTTP::parseEchoRequest(Number 65536)");
+ }
+
+// cerr << hexify(hex_req17->reference(), hex_req17->allocated(), false) <<
endl;
+ hex_req16x->corrupt(6);
+// cerr << hexify(hex_req17->reference(), hex_req17->allocated(), false) <<
endl;
+ vector<boost::shared_ptr<amf::Element> > corrupt17 =
http.parseEchoRequest(*hex_req16x);
+ if (corrupt17.size()) {
+ runtest.pass("Corrupted HTTP::parseEchoRequest(Number -65536)");
+ } else {
+ runtest.fail("Corrupted HTTP::parseEchoRequest(Number -65536)");
+ }
+
+// cerr << hexify(hex_req19->reference(), hex_req19->allocated(), false) <<
endl;
+ hex_req19->corrupt(1);
+// cerr << hexify(hex_req19->reference(), hex_req19->allocated(), false) <<
endl;
+ vector<boost::shared_ptr<amf::Element> > corrupt19 =
http.parseEchoRequest(*hex_req19);
+ if (corrupt19.size()) {
+ runtest.pass("Corrupted HTTP::parseEchoRequest(Number 1.5)");
+ } else {
+ runtest.fail("Corrupted HTTP::parseEchoRequest(Number 1.5)");
+ }
+
+// cerr << hexify(hex_req20->reference(), hex_req20->allocated(), false) <<
endl;
+ hex_req20->corrupt(4);
+// cerr << hexify(hex_req20->reference(), hex_req20->allocated(), false) <<
endl;
+ vector<boost::shared_ptr<amf::Element> > corrupt20 =
http.parseEchoRequest(*hex_req20);
+ if (corrupt20.size()) {
+ runtest.pass("Corrupted HTTP::parseEchoRequest(Number -1.5)");
+ } else {
+ runtest.fail("Corrupted HTTP::parseEchoRequest(Number -1.5)");
+ }
+
+// cerr << hexify(hex_req21->reference(), hex_req21->allocated(), false) <<
endl;
+ hex_req21->corrupt(8);
+// cerr << hexify(hex_req21->reference(), hex_req21->allocated(), false) <<
endl;
+ vector<boost::shared_ptr<amf::Element> > corrupt21 =
http.parseEchoRequest(*hex_req21);
+ if (corrupt21.size()) {
+ runtest.pass("Corrupted HTTP::parseEchoRequest(Number NaN)");
+ } else {
+ runtest.fail("Corrupted HTTP::parseEchoRequest(Number NaN)");
+ }
+
+// cerr << hexify(hex_req22->reference(), hex_req22->allocated(), false) <<
endl;
+ hex_req22->corrupt(1);
+// cerr << hexify(hex_req22->reference(), hex_req22->allocated(), false) <<
endl;
+ vector<boost::shared_ptr<amf::Element> > corrupt22 =
http.parseEchoRequest(*hex_req22);
+ if (corrupt22.size()) {
+ runtest.pass("Corrupted HTTP::parseEchoRequest(Number Infinity)");
+ } else {
+ runtest.fail("Corrupted HTTP::parseEchoRequest(Number Infinity)");
+ }
+
+// cerr << hexify(hex_req26->reference(), hex_req26->allocated(), false) <<
endl;
+ hex_req26->corrupt(5);
+// cerr << hexify(hex_req26->reference(), hex_req26->allocated(), false) <<
endl;
+ vector<boost::shared_ptr<amf::Element> > corrupt26 =
http.parseEchoRequest(*hex_req26);
+ if (corrupt26.size()) {
+ runtest.pass("Corrupted HTTP::parseEchoRequest(Strict Array of
Numbers, 3 items)");
+ } else {
+ runtest.fail("Corrupted HTTP::parseEchoRequest(Strict Array of
Numbers, 3 items)");
+ }
+
+// cerr << hexify(hex_req27->reference(), hex_req27->allocated(), false) <<
endl;
+ hex_req27->corrupt(3);
+// cerr << hexify(hex_req27->reference(), hex_req27->allocated(), false) <<
endl;
+ vector<boost::shared_ptr<amf::Element> > corrupt27 =
http.parseEchoRequest(*hex_req27);
+ if (corrupt27.size()) {
+ runtest.pass("Corrupted HTTP::parseEchoRequest(Strict Array - Number,
undefines, Number)");
+ } else {
+ runtest.fail("Corrupted HTTP::parseEchoRequest(Strict Array - Number,
undefines, Number)");
+ }
+
+// cerr << hexify(hex_req29->reference(), hex_req29->allocated(), false) <<
endl;
+ hex_req29->corrupt(8);
+// cerr << hexify(hex_req29->reference(), hex_req29->allocated(), false) <<
endl;
+ vector<boost::shared_ptr<amf::Element> > corrupt29 =
http.parseEchoRequest(*hex_req29);
+ if (corrupt29.size()) {
+ runtest.pass("Corrupted HTTP::parseEchoRequest(NULL String)");
+ } else {
+ runtest.fail("Corrupted HTTP::parseEchoRequest(NULL String)");
+ }
+
+// cerr << hexify(hex_req30->reference(), hex_req30->allocated(), false) <<
endl;
+ hex_req30->corrupt(7);
+// cerr << hexify(hex_req30->reference(), hex_req30->allocated(), false) <<
endl;
+ vector<boost::shared_ptr<amf::Element> > corrupt30 =
http.parseEchoRequest(*hex_req30);
+ if (corrupt30.size()) {
+ runtest.pass("Corrupted HTTP::parseEchoRequest(Simple String)");
+ } else {
+ runtest.fail("Corrupted HTTP::parseEchoRequest(Simple String)");
+ }
+
+// cerr << hexify(hex_req31->reference(), hex_req31->allocated(), false) <<
endl;
+ hex_req31->corrupt(2);
+// cerr << hexify(hex_req31->reference(), hex_req31->allocated(), false) <<
endl;
+ vector<boost::shared_ptr<amf::Element> > corrupt31 =
http.parseEchoRequest(*hex_req31);
+ if (corrupt31.size()) {
+ runtest.pass("Corrupted HTTP::parseEchoRequest(Simple String Array)");
+ } else {
+ runtest.fail("Corrupted HTTP::parseEchoRequest(Simple String Array)");
+ }
+
+// cerr << hexify(hex_req40->reference(), hex_req40->allocated(), false) <<
endl;
+ hex_req40->corrupt(6);
+// cerr << hexify(hex_req40->reference(), hex_req40->allocated(), false) <<
endl;
+ vector<boost::shared_ptr<amf::Element> > corrupt40 =
http.parseEchoRequest(*hex_req40);
+ if (corrupt40.size()) {
+ runtest.pass("Corrupted HTTP::parseEchoRequest(object CustomClass)");
+ } else {
+ runtest.fail("Corrupted HTTP::parseEchoRequest(object CustomClass)");
+ }
+
+// cerr << hexify(hex_req41->reference(), hex_req41->allocated(), false) <<
endl;
+ hex_req41->corrupt(1);
+// cerr << hexify(hex_req41->reference(), hex_req41->allocated(), false) <<
endl;
+ vector<boost::shared_ptr<amf::Element> > corrupt41 =
http.parseEchoRequest(*hex_req41);
+ if (corrupt41.size()) {
+ runtest.pass("Corrupted HTTP::parseEchoRequest(object CustomClass
Array)");
+ } else {
+ runtest.fail("Corrupted HTTP::parseEchoRequest(object CustomClass
Array)");
+ }
+
+// cerr << hexify(hex_req42->reference(), hex_req42->allocated(), false) <<
endl;
+ hex_req42->corrupt(2);
+// cerr << hexify(hex_req42->reference(), hex_req42->allocated(), false) <<
endl;
+ vector<boost::shared_ptr<amf::Element> > corrupt42 =
http.parseEchoRequest(*hex_req42);
+ if (corrupt42.size()) {
+ runtest.pass("Corrupted HTTP::parseEchoRequest(object RemoteClass)");
+ } else {
+ runtest.fail("Corrupted HTTP::parseEchoRequest(object RemoteClass)");
+ }
+
+// cerr << hexify(hex_req43->reference(), hex_req43->allocated(), false) <<
endl;
+ hex_req43->corrupt(4);
+// cerr << hexify(hex_req43->reference(), hex_req43->allocated(), false) <<
endl;
+ vector<boost::shared_ptr<amf::Element> > corrupt43 =
http.parseEchoRequest(*hex_req43);
+ if (corrupt43.size()) {
+ runtest.pass("Corrupted HTTP::parseEchoRequest(object RemoteClass
Array, 2 items)");
+ } else {
+ runtest.fail("Corrupted HTTP::parseEchoRequest(object RemoteClass
Array, 2 items)");
+ }
+
+// cerr << hexify(hex_req44->reference(), hex_req44->allocated(), false) <<
endl;
+ hex_req44->corrupt(3);
+// cerr << hexify(hex_req44->reference(), hex_req44->allocated(), false) <<
endl;
+ vector<boost::shared_ptr<amf::Element> > corrupt44 =
http.parseEchoRequest(*hex_req44);
+ if (corrupt44.size()) {
+ runtest.pass("Corrupted HTTP::parseEchoRequest(object RemoteClass");
+ } else {
+ runtest.fail("Corrupted HTTP::parseEchoRequest(object RemoteClass");
+ }
+#endif
+
+// cerr << hexify(hex_req45->reference(), hex_req45->allocated(), false) <<
endl;
+#if 0
+ hex_req45->corrupt(6);
+// cerr << hexify(hex_req45->reference(), hex_req45->allocated(), false) <<
endl;
+ vector<boost::shared_ptr<amf::Element> > corrupt45 =
http.parseEchoRequest(*hex_req45);
+ if (corrupt45.size()) {
+ runtest.pass("Corrupted HTTP::parseEchoRequest(object RemoteClass");
+ } else {
+ runtest.fail("Corrupted HTTP::parseEchoRequest(object RemoteClass");
+ }
+#endif
}
static void
=== modified file 'testsuite/libnet.all/test_rtmp.cpp'
--- a/testsuite/libnet.all/test_rtmp.cpp 2008-10-25 16:29:48 +0000
+++ b/testsuite/libnet.all/test_rtmp.cpp 2009-02-14 22:42:54 +0000
@@ -148,11 +148,11 @@
RTMPClient client;
bool notest = false;
- RTMP::rtmp_head_t *rthead = 0;
+ boost::shared_ptr<RTMP::rtmp_head_t> rthead;
CQue *que;
boost::shared_ptr<Buffer> buf1(new Buffer("04 00 00 00 00 00 b8 14 01 00
00 00 02 00 08 6f 6e 53 74 61 74 75 73 00 00 00 00 00 00 00 00 00 05 03 00 05
6c 65 76 65 6c 02 00 06 73 74 61 74 75 73 00 04 63 6f 64 65 02 00 14 4e 65 74
53 74 72 65 61 6d 2e 50 6c 61 79 2e 52 65 73 65 74 00 0b 64 65 73 63 72 69 70
74 69 6f 6e 02 00 2d 50 6c 61 79 69 6e 67 20 61 6e 64 20 72 65 73 65 74 74 69
6e 67 20 67 61 74 65 30 36 5f 74 61 62 6c 61 6e 5f 62 63 75 65 75 5f 30 31 2e
c4 00 07 64 65 74 61 69 6c 73 02 00 16 67 61 74 65 30 36 5f 74 61 62 6c 61 6e
5f 62 63 75 65 75 5f 30 31 00 08 63 6c 69 65 6e 74 69 64 00 41 bf e4 78 30 00
00 00 00 00 09"));
- RTMP::queues_t *queues1 = client.split(buf1);
+ boost::shared_ptr<RTMP::queues_t> queues1 = client.split(*buf1);
if (queues1->size() == 0) {
notest = true;
}
@@ -208,7 +208,7 @@
// delete queues1;
boost::shared_ptr<Buffer> buf2(new Buffer("02 00 00 00 00 00 04 01 00 00
00 00 00 00 00 80 02 00 00 00 00 00 06 04 00 00 00 00 00 04 00 00 00 01 04 00
00 00 00 00 b8 14 01 00 00 00 02 00 08 6f 6e 53 74 61 74 75 73 00 00 00 00 00
00 00 00 00 05 03 00 05 6c 65 76 65 6c 02 00 06 73 74 61 74 75 73 00 04 63 6f
64 65 02 00 14 4e 65 74 53 74 72 65 61 6d 2e 50 6c 61 79 2e 52 65 73 65 74 00
0b 64 65 73 63 72 69 70 74 69 6f 6e 02 00 2d 50 6c 61 79 69 6e 67 20 61 6e 64
20 72 65 73 65 74 74 69 6e 67 20 67 61 74 65 30 36 5f 74 61 62 6c 61 6e 5f 62
63 75 65 75 5f 30 31 2e 02 00 00 00 00 00 06 04 00 00 00 00 00 00 00 00 00 01
c4 00 07 64 65 74 61 69 6c 73 02 00 16 67 61 74 65 30 36 5f 74 61 62 6c 61 6e
5f 62 63 75 65 75 5f 30 31 00 08 63 6c 69 65 6e 74 69 64 00 41 d8 fb 78 56 00
00 00 00 00 09"));
- RTMP::queues_t *queues2 = client.split(buf2);
+ boost::shared_ptr<RTMP::queues_t> queues2 = client.split(*buf2);
if (queues2->size() == 0) {
notest = true;
}
@@ -302,7 +302,7 @@
// for other channels.
//
...............onStatus.............level...status..code...NetStream.Play.Start..description..'Started
playing
gate06_tablan_bcueu_01...clie......'address@hidden;...../..rP.....K.......m......,......%......................B........M.<.$.....`.......i..9..C..J..........%..........G....2Np."address@hidden;.ntid.A..xV.....
boost::shared_ptr<Buffer> buf3(new Buffer("05 00 00 00 00 00 90 14 01 00
00 00 02 00 08 6f 6e 53 74 61 74 75 73 00 00 00 00 00 00 00 00 00 05 03 00 05
6c 65 76 65 6c 02 00 06 73 74 61 74 75 73 00 04 63 6f 64 65 02 00 14 4e 65 74
53 74 72 65 61 6d 2e 50 6c 61 79 2e 53 74 61 72 74 00 0b 64 65 73 63 72 69 70
74 69 6f 6e 02 00 27 53 74 61 72 74 65 64 20 70 6c 61 79 69 6e 67 20 67 61 74
65 30 36 5f 74 61 62 6c 61 6e 5f 62 63 75 65 75 5f 30 31 2e 00 08 63 6c 69 65
07 00 00 00 00 00 27 09 01 00 00 00 14 00 78 46 0f 14 0f 14 3f 6a ff ff 00 08
9f 40 10 9f f8 8b 3f fd b2 4f fb 5d c0 00 00 00 00 00 00 00 00 00 00 00 00 08
00 00 00 00 00 00 08 01 00 00 00 08 00 00 00 00 01 3b 08 01 00 00 00 2f ff fb
72 50 00 00 00 00 00 4b 00 00 00 00 07 e0 09 6d 00 00 00 00 00 01 2c 00 00 00
00 1f 80 25 b4 00 00 00 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff fc 0c 87
42 80 ec c8 b0 0e 90 c2 12 4d 90 3c 18 24 16 01 88 03 e1 60 1a 1a a0 1a 09 9c
1a 69 a1 10 39 06 8d 43 02 c3 4a 12 0b 00 c8 1f 0b 00 d8 16 00 25 9f ff ff fe
c1 a0 00 00 ff 8a 47 80 80 0e 1e 32 4e 70 f1 22 ed 31 60 40 f8 02 00 00 00 00
00 04 01 00 00 00 00 00 00 01 3b c5 6e 74 69 64 00 41 d8 fb 78 56 00 00 00 00
00 09"));
- RTMP::queues_t *queues3 = client.split(buf3);
+ boost::shared_ptr<RTMP::queues_t> queues3 = client.split(*buf3);
if (queues3->size() == 0) {
notest = true;
}
@@ -324,7 +324,7 @@
tmpbuf = que->pop();
// tmpbuf->dump();
queues3->pop_front();
- rthead = client.decodeHeader(tmpbuf);
+ rthead = client.decodeHeader(tmpbuf->reference());
if ((*tmpbuf->reference() == 0x05) && (rthead->type <= RTMP::INVOKE))
{
runtest.pass("RTMP::split(1st packet header) of 6");
} else {
@@ -339,7 +339,7 @@
tmpbuf = que->pop();
// tmpbuf->dump();
queues3->pop_front();
- rthead = client.decodeHeader(tmpbuf);
+ rthead = client.decodeHeader(tmpbuf->reference());
if ((*tmpbuf->reference() == 0x07) && (rthead->type <=
RTMP::VIDEO_DATA)) {
runtest.pass("RTMP::split(2nd packet header) of 6");
} else {
@@ -354,7 +354,7 @@
tmpbuf = que->pop();
// tmpbuf->dump();
queues3->pop_front();
- rthead = client.decodeHeader(tmpbuf);
+ rthead = client.decodeHeader(tmpbuf->reference());
if ((*tmpbuf->reference() == 0x08) && (rthead->type <=
RTMP::AUDIO_DATA)) {
runtest.pass("RTMP::split(3rd packet header) of 6");
} else {
@@ -369,7 +369,7 @@
tmpbuf = que->pop();
// tmpbuf->dump();
queues3->pop_front();
- rthead = client.decodeHeader(tmpbuf);
+ rthead = client.decodeHeader(tmpbuf->reference());
if ((*tmpbuf->reference() == 0x08) && (rthead->type <=
RTMP::AUDIO_DATA)) {
runtest.pass("RTMP::split(4th packet header) of 6");
} else {
@@ -384,7 +384,7 @@
// tmpbuf->dump();
queues3->pop_front();
- rthead = client.decodeHeader(tmpbuf);
+ rthead = client.decodeHeader(tmpbuf->reference());
if ((*tmpbuf->reference() == 0x02) && (rthead->type <=
RTMP::AUDIO_DATA)) {
runtest.pass("RTMP::split(5th packet header) of 6");
} else {
@@ -392,12 +392,27 @@
}
}
-// delete queues3;
+ // the oflaDemo connect packet, which currently core dumps
+ notest = false;
+ boost::shared_ptr<Buffer> buf4(new Buffer("03 00 00 00 00 01 0b 14 00 00
00 00 02 00 07 63 6f 6e 6e 65 63 74 00 3f f0 00 00 00 00 00 00 03 00 03 61 70
70 02 00 08 6f 66 6c 61 44 65 6d 6f 00 08 66 6c 61 73 68 56 65 72 02 00 0e 4c
4e 58 20 31 30 2c 30 2c 31 32 2c 33 36 00 06 73 77 66 55 72 6c 02 00 29 68 74
74 70 3a 2f 2f 6c 6f 63 61 6c 68 6f 73 74 3a 35 30 38 30 2f 64 65 6d 6f 73 2f
6f 66 6c 61 5f 64 65 6d 6f 2e 73 77 66 00 05 74 63 55 72 6c 02 00 1e 72 74 6d
c3 70 3a 2f 2f 6c 6f 63 61 6c 68 6f 73 74 3a 35 39 33 35 2f 6f 66 6c 61 44 65
6d 6f 00 04 66 70 61 64 01 00 00 0c 63 61 70 61 62 69 6c 69 74 69 65 73 00 40
2e 00 00 00 00 00 00 00 0b 61 75 64 69 6f 43 6f 64 65 63 73 00 40 a8 ee 00 00
00 00 00 00 0b 76 69 64 65 6f 43 6f 64 65 63 73 00 40 6f 80 00 00 00 00 00 00
0d 76 69 64 65 6f 46 75 6e 63 74 69 6f 6e 00 3f f0 00 00 00 00 00 00 00 07 c3
70 61 67 65 55 72 6c 06 00 00 09"));
+// buf4->dump();
-// delete que1;
+ boost::shared_ptr<RTMP::queues_t> queues4 = client.split(*buf4);
+ if (queues4->size() == 0) {
+ notest = true;
+ }
+ if (notest) {
+ runtest.unresolved("RTMP::split(oflaDemo)");
+ } else {
+ queues4->at(0)->dump();
+ if (queues4->size() == 1) {
+ runtest.pass("RTMP::split(oflaDemo)");
+ notest = false;
+ } else {
+ runtest.fail("RTMP::split(oflaDemo)");
+ }
+ }
-// delete buf2;
-// delete que2;
}
void
@@ -406,20 +421,21 @@
GNASH_REPORT_FUNCTION;
RTMPClient client;
- RTMPServer server;
boost::shared_ptr<amf::Buffer> buf1(new amf::Buffer("00 00 00 00 00 00"));
// clear buffer message
boost::shared_ptr<amf::Buffer> buf2(new amf::Buffer("00 06 cf 03 04 c3"));
// ping client from server
boost::shared_ptr<amf::Buffer> buf3(new amf::Buffer("00 07 cf 03 04 c3"));
// Pong, reply from client
boost::shared_ptr<amf::Buffer> buf4(new amf::Buffer("00 00 00 00 00 01"));
// clear buffer message
- RTMP::rtmp_ping_t *ping1 = client.decodePing(buf1);
+ boost::shared_ptr<RTMP::rtmp_ping_t> ping1 = client.decodePing(*buf1);
if (ping1->type == RTMP::PING_CLEAR) {
runtest.pass("Decoded RTMP Ping message");
} else {
runtest.fail("Decoded RTMP Ping message");
}
+#if 0
+ RTMPServer server;
boost::shared_ptr<amf::Buffer> enc1 = server.encodePing(RTMP::PING_CLEAR);
if ((memcmp(buf1->reference(), enc1->reference(), 6) == 0)) {
runtest.pass("Encoded RTMP Ping Clear message");
@@ -436,8 +452,9 @@
} else {
runtest.fail("Encoded RTMP Ping Client message");
}
-
- RTMP::rtmp_ping_t *ping2 = client.decodePing(buf2);
+#endif
+
+ boost::shared_ptr<RTMP::rtmp_ping_t> ping2 = client.decodePing(*buf2);
if ((ping2->type == RTMP::PING_CLIENT)
&& (ping2->target == 0xcf03)
&& (ping2->param1 == 0x4c3)) {
@@ -470,8 +487,6 @@
// "c2 00 06 30 86 0a ae";
// cleanup
- delete ping1;
- delete ping2;
}
void
@@ -479,12 +494,11 @@
{
GNASH_REPORT_FUNCTION;
RTMPClient client;
- RTMPServer server;
// this is a sample 12 bytes RTMP header
// const char *x1 = "03 00 00 00 00 01 1f 14 00 00 00 00";
boost::shared_ptr<amf::Buffer> buf1(new Buffer("03 00 00 00 00 01 1f 14 00
00 00 00"));
- boost::shared_ptr<amf::Buffer> head1 = server.encodeHeader(0x3,
RTMP::HEADER_12, 287,
+ boost::shared_ptr<amf::Buffer> head1 = client.encodeHeader(0x3,
RTMP::HEADER_12, 287,
RTMP::INVOKE, RTMPMsg::FROM_SERVER);
// cerr << hexify(buf1->begin(), RTMP_MAX_HEADER_SIZE, false) << endl;
// cerr << hexify(head1->begin(), RTMP_MAX_HEADER_SIZE, false) << endl;
@@ -494,8 +508,7 @@
} else {
runtest.fail("Encoded RTMP header(Invoke)");
}
-
- RTMP::rtmp_head_t *header1 = server.decodeHeader(buf1->reference());
+ boost::shared_ptr<RTMP::rtmp_head_t> header1 =
client.decodeHeader(buf1->reference());
if ((header1->channel == 0x3) && (header1->head_size ==
RTMP_MAX_HEADER_SIZE)
&& (header1->bodysize == 287) && (header1->type == RTMP::INVOKE)) {
runtest.pass("Decoded RTMP header(Invoke)");
@@ -504,7 +517,7 @@
}
boost::shared_ptr<amf::Buffer> buf2(new Buffer("02 00 00 00 00 00 06 04
00 00 00 00"));
- boost::shared_ptr<amf::Buffer> head2 = server.encodeHeader(0x2,
RTMP::HEADER_12, PING_MSG_SIZE,
+ boost::shared_ptr<amf::Buffer> head2 = client.encodeHeader(0x2,
RTMP::HEADER_12, PING_MSG_SIZE,
RTMP::PING, RTMPMsg::FROM_SERVER);
// cerr << hexify(head2->begin(), RTMP_MAX_HEADER_SIZE, false) << endl;
if ((memcmp(buf2->reference(), head2->reference(), 8) == 0)) {
@@ -514,7 +527,7 @@
}
boost::shared_ptr<amf::Buffer> buf3(new Buffer("02 ff e3 6c 00 00 06 04
00 00 00 00"));
- boost::shared_ptr<amf::Buffer> head3 = server.encodeHeader(0x2,
RTMP::HEADER_12, PING_MSG_SIZE,
+ boost::shared_ptr<amf::Buffer> head3 = client.encodeHeader(0x2,
RTMP::HEADER_12, PING_MSG_SIZE,
RTMP::PING, RTMPMsg::FROM_SERVER);
// cerr << hexify(head3->begin(), RTMP_MAX_HEADER_SIZE, false) << endl;
if ((memcmp(buf2->reference(), head3->reference(), 8) == 0)) {
@@ -523,7 +536,7 @@
runtest.fail("Encoded RTMP header(Ping 1)");
}
- RTMP::rtmp_head_t *header2 = client.decodeHeader(buf3);
+ boost::shared_ptr<RTMP::rtmp_head_t> header2 = client.decodeHeader(*buf3);
if ((header2->channel == 0x2) && (header2->head_size ==
RTMP_MAX_HEADER_SIZE)
&& (header2->bodysize == 6) && (header2->type == RTMP::PING)) {
runtest.pass("Decoded RTMP header(Ping)");
@@ -532,7 +545,7 @@
}
boost::shared_ptr<amf::Buffer> buf4(new Buffer("c2"));
- boost::shared_ptr<amf::Buffer> head4 = server.encodeHeader(0x2,
RTMP::HEADER_1);
+ boost::shared_ptr<amf::Buffer> head4 = client.encodeHeader(0x2,
RTMP::HEADER_1);
// cerr << hexify(head4->begin(), RTMP_MAX_HEADER_SIZE, false) << endl;
if ((memcmp(buf4->reference(), head4->reference(), 1) == 0)) {
runtest.pass("Encoded RTMP header(size 1)");
@@ -544,7 +557,7 @@
// 6f 6e 65 00 40 00 00 00 00 00 00 00 05
boost::shared_ptr<amf::Buffer> buf5(new Buffer("43 00 00 00 00 00 19
14"));
- boost::shared_ptr<amf::Buffer> head5 = server.encodeHeader(0x3,
RTMP::HEADER_8, 0x19, RTMP::INVOKE,
+ boost::shared_ptr<amf::Buffer> head5 = client.encodeHeader(0x3,
RTMP::HEADER_8, 0x19, RTMP::INVOKE,
RTMPMsg::FROM_CLIENT);
// head5->dump();
// cerr << hexify(head5->begin(), 8, false) << endl;
@@ -554,13 +567,24 @@
runtest.fail("Encoded RTMP header(size 8)");
}
- RTMP::rtmp_head_t *header3 = client.decodeHeader(buf5);
+ boost::shared_ptr<RTMP::rtmp_head_t> header3 = client.decodeHeader(*buf5);
if ((header3->channel == 0x3) && (header3->head_size == 8)
&& (header3->bodysize == 0x19) && (header3->type == RTMP::INVOKE)) {
runtest.pass("Decoded RTMP header(size 8)");
} else {
runtest.fail("Decoded RTMP header(size 8)");
}
+
+ // 4 byte header
+ boost::shared_ptr<amf::Buffer> buf6(new Buffer("83 00 04 16"));
+ boost::shared_ptr<amf::Buffer> head6 = client.encodeHeader(0x3,
RTMP::HEADER_4, 0x19, RTMP::INVOKE,
+ RTMPMsg::FROM_CLIENT);
+ if ((memcmp(buf6->reference(), head6->reference(), 4) == 0)) {
+ runtest.pass("Encoded RTMP header(size 4)");
+ } else {
+ runtest.fail("Encoded RTMP header(size 4)");
+ }
+// head5->dump();
}
void
@@ -579,7 +603,7 @@
// 63 74 2e 53 75 63 63 65 73 73 00 00 c3 09 ct.Success....
boost::shared_ptr<amf::Buffer> hex2(new Buffer("02 00 07 5f 72 65 73 75 6c
74 00 3f f0 00 00 00 00 00 00 05 03 00 0b 61 70 70 6c 69 63 61 74 69 6f 6e 05
00 05 6c 65 76 65 6c 02 00 06 73 74 61 74 75 73 00 0b 64 65 73 63 72 69 70 74
69 6f 6e 02 00 15 43 6f 6e 6e 65 63 74 69 6f 6e 20 73 75 63 63 65 65 64 65 64
2e 00 04 63 6f 64 65 02 00 1d 4e 65 74 43 6f 6e 6e 65 63 74 69 6f 6e 2e 43 6f
6e 6e 65 63 74 2e 53 75 63 63 65 73 73 00 00 09"));
- RTMPMsg *msg1 = rtmp.decodeMsgBody(hex2);
+ RTMPMsg *msg1 = rtmp.decodeMsgBody(*hex2);
if (msg1) {
std::vector<boost::shared_ptr<amf::Element> > hell =
msg1->getElements();
std::vector<boost::shared_ptr<amf::Element> > props =
hell[0]->getProperties();
@@ -613,7 +637,7 @@
#endif
boost::shared_ptr<amf::Buffer> hex3(new Buffer("02 00 07 5f 72 65 73 75 6c
74 00 3f f0 00 00 00 00 00 00 05 03 00 0b 61 70 70 6c 69 63 61 74 69 6f 6e 05
00 05 6c 65 76 65 6c 02 00 05 65 72 72 6f 72 00 0b 64 65 73 63 72 69 70 74 69
6f 6e 02 00 00 00 04 63 6f 64 65 02 00 1c 4e 65 74 43 6f 6e 6e 65 63 74 69 6f
6e 2e 43 6f 6e 6e 65 63 74 2e 46 61 69 6c 65 64 00 00 09"));
- RTMPMsg *msg2 = rtmp.decodeMsgBody(hex3);
+ RTMPMsg *msg2 = rtmp.decodeMsgBody(*hex3);
std::vector<boost::shared_ptr<amf::Element> > hell = msg2->getElements();
std::vector<boost::shared_ptr<amf::Element> > props =
hell[0]->getProperties();
// printf("FIXME: %d, %d, %s:%s\n", props.size(), msg1->getStatus(),
@@ -654,8 +678,8 @@
// clientid
// dsLgYohb
boost::shared_ptr<amf::Buffer> hex4(new Buffer("02 00 08 6f 6e 53 74 61 74
75 73 00 00 00 00 00 00 00 00 00 05 03 00 05 6c 65 76 65 6c 02 00 06 73 74 61
74 75 73 00 04 63 6f 64 65 02 00 14 4e 65 74 53 74 72 65 61 6d 2e 50 6c 61 79
2e 52 65 73 65 74 00 0b 64 65 73 63 72 69 70 74 69 6f 6e 02 00 2a 50 6c 61 79
69 6e 67 20 61 6e 64 20 72 65 73 65 74 74 69 6e 67 20 50 44 5f 45 6e 67 6c 69
73 68 5f 4c 6f 77 40 32 30 30 31 2e 00 07 64 65 74 61 69 6c 73 02 00 13 50 44
5f 45 6e 67 6c 69 73 68 5f 4c 6f 77 40 32 30 30 31 00 08 63 6c 69 65 6e 74 69
64 02 00 08 64 73 4c 67 59 6f 68 62 00 00 09"));
- RTMPMsg *msg4 = rtmp.decodeMsgBody(hex4);
-// msg4->dump();
+ RTMPMsg *msg4 = rtmp.decodeMsgBody(*hex4);
+ msg4->dump();
// std::vector<amf::Element *> hell4 = msg4->getElements();
if ((msg4->getStatus() == RTMPMsg::NS_PLAY_RESET)
&& (msg4->getMethodName() == "onStatus")
@@ -672,8 +696,8 @@
// NetStream
// Data.Start
boost::shared_ptr<amf::Buffer> hex5(new Buffer("02 00 08 6f 6e 53 74 61 74
75 73 03 00 04 63 6f 64 65 02 00 14 4e 65 74 53 74 72 65 61 6d 2e 44 61 74 61
2e 53 74 61 72 74 00 00 09"));
- RTMPMsg *msg5 = rtmp.decodeMsgBody(hex5);
-// msg5->dump();
+ RTMPMsg *msg5 = rtmp.decodeMsgBody(*hex5);
+ msg5->dump();
// cout << msg5->getStreamID() << endl;
// std::vector<amf::Element *> hell4 = msg4->getElements();
if ((msg5->getStatus() == RTMPMsg::NS_DATA_START)
@@ -696,7 +720,7 @@
// details
// address@hidden
boost::shared_ptr<amf::Buffer> hex6(new Buffer("02 00 08 6f 6e 53 74 61 74
75 73 00 00 00 00 00 00 00 00 00 05 03 00 05 6c 65 76 65 6c 02 00 06 73 74 61
74 75 73 00 04 63 6f 64 65 02 00 14 4e 65 74 53 74 72 65 61 6d 2e 50 6c 61 79
2e 53 74 61 72 74 00 0b 64 65 73 63 72 69 70 74 69 6f 6e 02 00 24 53 74 61 72
74 65 64 20 70 6c 61 79 69 6e 67 20 50 44 5f 45 6e 67 6c 69 73 68 5f 4c 6f 77
40 32 30 30 31 2e 00 07 64 65 74 61 69 6c 73 02 00 13 50 44 5f 45 6e 67 6c 69
73 68 5f 4c 6f 77 40 32 30 30 31 00 08 63 6c 69 65 6e 74 69 64 02 00 08 64 73
4c 67 59 6f 68 62 00 00 09"));
- RTMPMsg *msg6 = rtmp.decodeMsgBody(hex6);
+ RTMPMsg *msg6 = rtmp.decodeMsgBody(*hex6);
// msg6->dump();
// std::vector<amf::Element *> hell4 = msg4->getElements();
if ((msg6->getStatus() == RTMPMsg::NS_PLAY_START)
@@ -711,7 +735,7 @@
// ..............._error.?.........
..level...error..code...NetConnection.Connect.Rejected..description..A[
Server.Reject ] : Virtual host _defa.ultVHost_ is not available....
boost::shared_ptr<amf::Buffer> hex7(new Buffer("02 00 06 5f 65 72 72 6f 72
00 3f f0 00 00 00 00 00 00 05 03 00 05 6c 65 76 65 6c 02 00 05 65 72 72 6f 72
00 04 63 6f 64 65 02 00 1e 4e 65 74 43 6f 6e 6e 65 63 74 69 6f 6e 2e 43 6f 6e
6e 65 63 74 2e 52 65 6a 65 63 74 65 64 00 0b 64 65 73 63 72 69 70 74 69 6f 6e
02 00 41 5b 20 53 65 72 76 65 72 2e 52 65 6a 65 63 74 20 5d 20 3a 20 56 69 72
74 75 61 6c 20 68 6f 73 74 20 5f 64 65 66 61 c3 75 6c 74 56 48 6f 73 74 5f 20
69 73 20 6e 6f 74 20 61 76 61 69 6c 61 62 6c 65 2e 00 00 09"));
- RTMPMsg *msg7 = rtmp.decodeMsgBody(hex7);
+ RTMPMsg *msg7 = rtmp.decodeMsgBody(*hex7);
if ((msg7->getStatus() == RTMPMsg::NC_CONNECT_REJECTED)
&& (msg7->getMethodName() == "_error")
&& (msg7->size() == 1)) {
@@ -723,7 +747,7 @@
//.onStatus.............level...error..code...NetStream.Play.StreamNotFound..description..6Failed
to play gate06_tablan_bcueu_; .stream not
found...details...gate06_tablan_bcueu_..clientid.A.;..
boost::shared_ptr<amf::Buffer> hex8(new Buffer("02 00 08 6f 6e 53 74 61 74
75 73 00 00 00 00 00 00 00 00 00 05 03 00 05 6c 65 76 65 6c 02 00 05 65 72 72
6f 72 00 04 63 6f 64 65 02 00 1d 4e 65 74 53 74 72 65 61 6d 2e 50 6c 61 79 2e
53 74 72 65 61 6d 4e 6f 74 46 6f 75 6e 64 00 0b 64 65 73 63 72 69 70 74 69 6f
6e 02 00 36 46 61 69 6c 65 64 20 74 6f 20 70 6c 61 79 20 67 61 74 65 30 36 5f
74 61 62 6c 61 6e 5f 62 63 75 65 75 5f 3b 20 c4 73 74 72 65 61 6d 20 6e 6f 74
20 66 6f 75 6e 64 2e 00 07 64 65 74 61 69 6c 73 02 00 14 67 61 74 65 30 36 5f
74 61 62 6c 61 6e 5f 62 63 75 65 75 5f 00 08 63 6c 69 65 6e 74 69 64 00 41 d8
3b b4 e4 00 00 00 00 00 09"));
- RTMPMsg *msg8 = rtmp.decodeMsgBody(hex8);
+ RTMPMsg *msg8 = rtmp.decodeMsgBody(*hex8);
// msg4->dump();
// std::vector<amf::Element *> hell4 = msg4->getElements();
if ((msg8->getStatus() == RTMPMsg::NS_PLAY_STREAMNOTFOUND)
@@ -738,7 +762,7 @@
//.....onStatus.............level...status..code...NetStream.Play.Stop..description..%Stopped
playing
gate06_tablan_bcueu_...details....gate06_tablan_bcueu_..clientid.A.;.......reason......
boost::shared_ptr<amf::Buffer> hex9(new Buffer("02 00 08 6f 6e 53 74 61 74
75 73 00 00 00 00 00 00 00 00 00 05 03 00 05 6c 65 76 65 6c 02 00 06 73 74 61
74 75 73 00 04 63 6f 64 65 02 00 13 4e 65 74 53 74 72 65 61 6d 2e 50 6c 61 79
2e 53 74 6f 70 00 0b 64 65 73 63 72 69 70 74 69 6f 6e 02 00 25 53 74 6f 70 70
65 64 20 70 6c 61 79 69 6e 67 20 67 61 74 65 30 36 5f 74 61 62 6c 61 6e 5f 62
63 75 65 75 5f 2e 00 07 64 65 74 61 69 6c 73 c4 02 00 14 67 61 74 65 30 36 5f
74 61 62 6c 61 6e 5f 62 63 75 65 75 5f 00 08 63 6c 69 65 6e 74 69 64 00 41 d8
3b b4 e4 00 00 00 00 06 72 65 61 73 6f 6e 02 00 00 00 00 09"));
- RTMPMsg *msg9 = rtmp.decodeMsgBody(hex9);
+ RTMPMsg *msg9 = rtmp.decodeMsgBody(*hex9);
// msg4->dump();
// std::vector<amf::Element *> hell4 = msg4->getElements();
if ((msg9->getStatus() == RTMPMsg::NS_PLAY_STOP)
=== modified file 'utilities/Makefile.am'
--- a/utilities/Makefile.am 2009-01-22 20:10:39 +0000
+++ b/utilities/Makefile.am 2009-02-02 02:07:06 +0000
@@ -80,7 +80,7 @@
GNASH_LIBS += $(GLIB_LIBS) $(GSTREAMER_LIBS)
#endif
-bin_PROGRAMS = gprocessor soldumper dumpshm flvdumper rtmpget
+bin_PROGRAMS = gprocessor soldumper dumpshm flvdumper
#check_PROGRAMS = gdebug.swf
gprocessor_SOURCES = processor.cpp
@@ -91,9 +91,6 @@
dumpshm_SOURCES = dumpshm.cpp
dumpshm_LDADD = $(GNASH_LIBS)
-rtmpget_SOURCES = rtmpget.cpp
-rtmpget_LDADD = $(GNASH_LIBS)
-
soldumper_SOURCES = soldumper.cpp
soldumper_LDADD = $(GNASH_LIBS)
=== modified file 'utilities/flvdumper.cpp'
--- a/utilities/flvdumper.cpp 2008-12-20 17:11:55 +0000
+++ b/utilities/flvdumper.cpp 2009-02-17 03:18:15 +0000
@@ -163,7 +163,7 @@
catch (Arg_parser::ArgParserException &e) {
cerr << _("Error parsing command line options: ") << e.what() <<
endl;
- cerr << _("This is a Gnash bug.") << endl;
+ cerr << _("This is a Gnash flvdumper bug.") << endl;
}
}
@@ -179,8 +179,6 @@
Flv flv;
struct stat st;
- boost::uint8_t *buf = 0;
- boost::uint8_t *ptr = 0;
// boost::shared_ptr<Flv::flv_header_t> head;
Flv::previous_size_t previous = 0;
boost::shared_ptr<Flv::flv_tag_t> tag;
@@ -223,7 +221,7 @@
}
ifs.read(reinterpret_cast<char *>(buf->reference()),
sizeof(Flv::flv_tag_t));
tag = flv.decodeTagHeader(buf);
-
+ flv.dump();
total -= sizeof(Flv::previous_size_t);
size_t bodysize = flv.convert24(tag->bodysize);
if (bodysize == 0) {
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Gnash-commit] /srv/bzr/gnash/trunk r10592: merge from 'rtmp' branch.,
rob <=